1 14 15 package org.apache.activemq.kaha.impl.container; 16 17 import java.io.IOException ; 18 import java.util.ArrayList ; 19 import java.util.Collection ; 20 import java.util.Iterator ; 21 import java.util.LinkedList ; 22 import java.util.List ; 23 import java.util.ListIterator ; 24 import org.apache.activemq.kaha.ContainerId; 25 import org.apache.activemq.kaha.ListContainer; 26 import org.apache.activemq.kaha.Marshaller; 27 import org.apache.activemq.kaha.RuntimeStoreException; 28 import org.apache.activemq.kaha.Store; 29 import org.apache.activemq.kaha.StoreEntry; 30 import org.apache.activemq.kaha.StoreLocation; 31 import org.apache.activemq.kaha.impl.DataManager; 32 import org.apache.activemq.kaha.impl.data.Item; 33 import org.apache.activemq.kaha.impl.index.IndexItem; 34 import org.apache.activemq.kaha.impl.index.IndexManager; 35 import org.apache.commons.logging.Log; 36 import org.apache.commons.logging.LogFactory; 37 38 43 public class ListContainerImpl extends BaseContainerImpl implements ListContainer{ 44 45 private static final Log log=LogFactory.getLog(ListContainerImpl.class); 46 protected Marshaller marshaller=Store.ObjectMarshaller; 47 48 49 public ListContainerImpl(ContainerId id,IndexItem root,IndexManager indexManager,DataManager dataManager, 50 boolean persistentIndex) throws IOException { 51 super(id,root,indexManager,dataManager,persistentIndex); 52 } 53 54 59 public synchronized void load(){ 60 checkClosed(); 61 if(!loaded){ 62 if(!loaded){ 63 loaded=true; 64 try{ 65 init(); 66 long nextItem=root.getNextItem(); 67 while(nextItem!=Item.POSITION_NOT_SET){ 68 IndexItem item=indexManager.getIndex(nextItem); 69 indexList.add(item); 70 itemAdded(item,indexList.size()-1,getValue(item)); 71 nextItem=item.getNextItem(); 72 } 73 }catch(IOException e){ 74 log.error("Failed to load container "+getId(),e); 75 throw new RuntimeStoreException(e); 76 } 77 } 78 } 79 } 80 81 86 public synchronized void unload(){ 87 checkClosed(); 88 if(loaded){ 89 loaded=false; 90 indexList.clear(); 91 92 } 93 } 94 95 100 public synchronized void setMarshaller(Marshaller marshaller){ 101 checkClosed(); 102 this.marshaller=marshaller; 103 } 104 105 public synchronized boolean equals(Object obj){ 106 load(); 107 boolean result=false; 108 if(obj!=null&&obj instanceof List ){ 109 List other=(List )obj; 110 result=other.size()==size(); 111 if(result){ 112 for(int i=0;i<indexList.size();i++){ 113 Object o1=other.get(i); 114 Object o2=get(i); 115 result=o1==o2||(o1!=null&&o2!=null&&o1.equals(o2)); 116 if(!result){ 117 break; 118 } 119 } 120 } 121 } 122 return result; 123 } 124 125 130 public synchronized int size(){ 131 load(); 132 return indexList.size(); 133 } 134 135 140 public synchronized void addFirst(Object o){ 141 internalAddFirst(o); 142 } 143 144 149 public synchronized void addLast(Object o){ 150 internalAddLast(o); 151 } 152 153 158 public synchronized Object removeFirst(){ 159 load(); 160 Object result=null; 161 IndexItem item=(IndexItem)indexList.getFirst(); 162 if(item!=null){ 163 itemRemoved(0); 164 result=getValue(item); 165 IndexItem prev=root; 166 IndexItem next=indexList.size()>1?(IndexItem)indexList.get(1):null; 167 indexList.removeFirst(); 168 delete(item,prev,next); 169 item=null; 170 } 171 return result; 172 } 173 174 179 public synchronized Object removeLast(){ 180 load(); 181 Object result=null; 182 IndexItem last=indexList.getLast(); 183 if(last!=null){ 184 itemRemoved(indexList.size()-1); 185 result=getValue(last); 186 IndexItem prev=indexList.getPrevEntry(last); 187 IndexItem next=null; 188 indexList.removeLast(); 189 delete(last,prev,next); 190 } 191 return result; 192 } 193 194 199 public synchronized boolean isEmpty(){ 200 load(); 201 return indexList.isEmpty(); 202 } 203 204 209 public synchronized boolean contains(Object o){ 210 load(); 211 boolean result=false; 212 if(o!=null){ 213 IndexItem next=indexList.getFirst(); 214 while(next!=null){ 215 Object value=getValue(next); 216 if(value!=null&&value.equals(o)){ 217 result=true; 218 break; 219 } 220 next=indexList.getNextEntry(next); 221 } 222 } 223 return result; 224 } 225 226 231 public synchronized Iterator iterator(){ 232 load(); 233 return listIterator(); 234 } 235 236 241 public synchronized Object [] toArray(){ 242 load(); 243 List tmp=new ArrayList (indexList.size()); 244 IndexItem next=indexList.getFirst(); 245 while(next!=null){ 246 Object value=getValue(next); 247 tmp.add(value); 248 next=indexList.getNextEntry(next); 249 } 250 return tmp.toArray(); 251 } 252 253 258 public synchronized Object [] toArray(Object [] a){ 259 load(); 260 List tmp=new ArrayList (indexList.size()); 261 IndexItem next=indexList.getFirst(); 262 while(next!=null){ 263 Object value=getValue(next); 264 tmp.add(value); 265 next=indexList.getNextEntry(next); 266 } 267 return tmp.toArray(a); 268 } 269 270 275 public synchronized boolean add(Object o){ 276 load(); 277 addLast(o); 278 return true; 279 } 280 281 286 public synchronized boolean remove(Object o){ 287 load(); 288 boolean result=false; 289 int pos=0; 290 IndexItem next=indexList.getFirst(); 291 while(next!=null){ 292 Object value=getValue(next); 293 if(value!=null&&value.equals(o)){ 294 remove(next); 295 itemRemoved(pos); 296 result=true; 297 break; 298 } 299 next=indexList.getNextEntry(next); 300 pos++; 301 } 302 return result; 303 } 304 305 protected synchronized void remove(IndexItem item){ 306 IndexItem prev=indexList.getPrevEntry(item); 307 IndexItem next=indexList.getNextEntry(item); 308 indexList.remove(item); 309 delete(item,prev,next); 310 } 311 312 317 public synchronized boolean containsAll(Collection c){ 318 load(); 319 boolean result=false; 320 for(Iterator i=c.iterator();i.hasNext();){ 321 Object obj=i.next(); 322 if(!(result=contains(obj))){ 323 result=false; 324 break; 325 } 326 } 327 return result; 328 } 329 330 335 public synchronized boolean addAll(Collection c){ 336 load(); 337 for(Iterator i=c.iterator();i.hasNext();){ 338 add(i.next()); 339 } 340 return true; 341 } 342 343 348 public synchronized boolean addAll(int index,Collection c){ 349 load(); 350 boolean result=false; 351 ListIterator e1=listIterator(index); 352 Iterator e2=c.iterator(); 353 while(e2.hasNext()){ 354 e1.add(e2.next()); 355 result=true; 356 } 357 return result; 358 } 359 360 365 public synchronized boolean removeAll(Collection c){ 366 load(); 367 boolean result=true; 368 for(Iterator i=c.iterator();i.hasNext();){ 369 Object obj=i.next(); 370 result&=remove(obj); 371 } 372 return result; 373 } 374 375 380 public synchronized boolean retainAll(Collection c){ 381 load(); 382 List tmpList=new ArrayList (); 383 IndexItem next=indexList.getFirst(); 384 while(next!=null){ 385 Object o=getValue(next); 386 if(!c.contains(o)){ 387 tmpList.add(o); 388 } 389 next=indexList.getNextEntry(next); 390 } 391 for(Iterator i=tmpList.iterator();i.hasNext();){ 392 remove(i.next()); 393 } 394 return !tmpList.isEmpty(); 395 } 396 397 402 public synchronized void clear(){ 403 checkClosed(); 404 super.clear(); 405 doClear(); 406 407 } 408 409 414 public synchronized Object get(int index){ 415 load(); 416 Object result = null; 417 IndexItem item=indexList.get(index); 418 if(item!=null){ 419 result=getValue(item); 420 } 421 return result; 422 } 423 424 429 public synchronized Object set(int index,Object element){ 430 load(); 431 Object result=null; 432 IndexItem replace=indexList.isEmpty()?null:(IndexItem)indexList.get(index); 433 IndexItem prev=(indexList.isEmpty()||(index-1)<0)?null:(IndexItem)indexList.get(index-1); 434 IndexItem next=(indexList.isEmpty()||(index+1)>=size())?null:(IndexItem)indexList.get(index+1); 435 result=getValue(replace); 436 indexList.remove(index); 437 delete(replace,prev,next); 438 itemRemoved(index); 439 add(index,element); 440 return result; 441 } 442 443 protected synchronized IndexItem internalSet(int index,Object element){ 444 IndexItem replace=indexList.isEmpty()?null:(IndexItem)indexList.get(index); 445 IndexItem prev=(indexList.isEmpty()||(index-1)<0)?null:(IndexItem)indexList.get(index-1); 446 IndexItem next=(indexList.isEmpty()||(index+1)>=size())?null:(IndexItem)indexList.get(index+1); 447 indexList.remove(index); 448 delete(replace,prev,next); 449 itemRemoved(index); 450 return internalAdd(index,element); 451 } 452 453 458 public synchronized void add(int index,Object element){ 459 load(); 460 IndexItem item=insert(index,element); 461 indexList.add(index,item); 462 itemAdded(item,index,element); 463 } 464 465 protected synchronized StoreEntry internalAddLast(Object o){ 466 load(); 467 IndexItem item=writeLast(o); 468 indexList.addLast(item); 469 itemAdded(item,indexList.size()-1,o); 470 return item; 471 } 472 473 protected synchronized StoreEntry internalAddFirst(Object o){ 474 load(); 475 IndexItem item=writeFirst(o); 476 indexList.addFirst(item); 477 itemAdded(item,0,o); 478 return item; 479 } 480 481 protected synchronized IndexItem internalAdd(int index,Object element){ 482 load(); 483 IndexItem item=insert(index,element); 484 indexList.add(index,item); 485 itemAdded(item,index,element); 486 return item; 487 } 488 489 protected synchronized StoreEntry internalGet(int index){ 490 load(); 491 if(index>=0&&index<indexList.size()){ 492 return indexList.get(index); 493 } 494 return null; 495 } 496 497 502 public synchronized boolean doRemove(int index){ 503 load(); 504 boolean result=false; 505 IndexItem item=indexList.get(index); 506 if(item!=null){ 507 result=true; 508 IndexItem prev=indexList.getPrevEntry(item); 509 prev=prev!=null?prev:root; 510 IndexItem next=indexList.getNextEntry(prev); 511 indexList.remove(index); 512 itemRemoved(index); 513 delete(item,prev,next); 514 } 515 return result; 516 } 517 518 523 public synchronized Object remove(int index){ 524 load(); 525 Object result=null; 526 IndexItem item=indexList.get(index); 527 if(item!=null){ 528 itemRemoved(index); 529 result=getValue(item); 530 IndexItem prev=indexList.getPrevEntry(item); 531 prev=prev!=null?prev:root; 532 IndexItem next=indexList.getNextEntry(item); 533 indexList.remove(index); 534 delete(item,prev,next); 535 } 536 return result; 537 } 538 539 544 public synchronized int indexOf(Object o){ 545 load(); 546 int result=-1; 547 if(o!=null){ 548 int count=0; 549 IndexItem next=indexList.getFirst(); 550 while(next!=null){ 551 Object value=getValue(next); 552 if(value!=null&&value.equals(o)){ 553 result=count; 554 break; 555 } 556 count++; 557 next=indexList.getNextEntry(next); 558 } 559 } 560 return result; 561 } 562 563 568 public synchronized int lastIndexOf(Object o){ 569 load(); 570 int result=-1; 571 if(o!=null){ 572 int count=indexList.size()-1; 573 IndexItem next=indexList.getLast(); 574 while(next!=null){ 575 Object value=getValue(next); 576 if(value!=null&&value.equals(o)){ 577 result=count; 578 break; 579 } 580 count--; 581 next=indexList.getPrevEntry(next); 582 } 583 } 584 return result; 585 } 586 587 592 public synchronized ListIterator listIterator(){ 593 load(); 594 IndexItem start= indexList.getFirst(); 595 return new ContainerListIterator(this,indexList,indexList.getRoot()); 596 } 597 598 603 public synchronized ListIterator listIterator(int index){ 604 load(); 605 IndexItem start = (index-1) >0 ?indexList.get(index-1):indexList.getRoot(); 606 return new ContainerListIterator(this,indexList,start); 607 } 608 609 614 public synchronized List subList(int fromIndex,int toIndex){ 615 load(); 616 List result=new ArrayList (); 617 int count=fromIndex; 618 IndexItem next=indexList.get(fromIndex); 619 while(next!=null&&count++<toIndex){ 620 result.add(getValue(next)); 621 next=indexList.getNextEntry(next); 622 } 623 return result; 624 } 625 626 632 public synchronized StoreEntry placeLast(Object object){ 633 StoreEntry item=internalAddLast(object); 634 return item; 635 } 636 637 643 public synchronized StoreEntry placeFirst(Object object){ 644 StoreEntry item=internalAddFirst(object); 645 return item; 646 } 647 648 653 public synchronized void update(StoreEntry entry,Object object){ 654 try{ 655 dataManager.updateItem(entry.getValueDataItem(),marshaller,object); 656 }catch(IOException e){ 657 throw new RuntimeException (e); 658 } 659 } 660 661 667 public synchronized Object get(final StoreEntry entry){ 668 load(); 669 StoreEntry entryToUse = refresh(entry); 670 return getValue(entryToUse); 671 } 672 673 679 public synchronized boolean remove(StoreEntry entry){ 680 IndexItem item=(IndexItem)entry; 681 load(); 682 boolean result=false; 683 if(item!=null){ 684 685 remove(item); 686 result = true; 687 } 688 return result; 689 } 690 691 696 public synchronized StoreEntry getFirst(){ 697 load(); 698 return indexList.getFirst(); 699 } 700 701 706 public synchronized StoreEntry getLast(){ 707 load(); 708 return indexList.getLast(); 709 } 710 711 717 public synchronized StoreEntry getNext(StoreEntry entry){ 718 load(); 719 IndexItem item=(IndexItem)entry; 720 return indexList.getNextEntry(item); 721 } 722 723 729 public synchronized StoreEntry getPrevious(StoreEntry entry){ 730 load(); 731 IndexItem item=(IndexItem)entry; 732 return indexList.getPrevEntry(item); 733 } 734 735 741 public synchronized StoreEntry refresh(StoreEntry entry) { 742 load(); 743 return indexList.getEntry(entry); 744 } 745 746 protected synchronized IndexItem writeLast(Object value){ 747 IndexItem index=null; 748 try{ 749 if(value!=null){ 750 StoreLocation data=dataManager.storeDataItem(marshaller,value); 751 index=indexManager.createNewIndex(); 752 index.setValueData(data); 753 IndexItem prev=indexList.getLast(); 754 prev=prev!=null?prev:root; 755 IndexItem next=indexList.getNextEntry(prev); 756 prev.setNextItem(index.getOffset()); 757 index.setPreviousItem(prev.getOffset()); 758 updateIndexes(prev); 759 if(next!=null){ 760 next.setPreviousItem(index.getOffset()); 761 index.setNextItem(next.getOffset()); 762 updateIndexes(next); 763 } 764 storeIndex(index); 765 } 766 }catch(IOException e){ 767 log.error("Failed to write "+value,e); 768 throw new RuntimeStoreException(e); 769 } 770 return index; 771 } 772 773 protected synchronized IndexItem writeFirst(Object value){ 774 IndexItem index=null; 775 try{ 776 if(value!=null){ 777 StoreLocation data=dataManager.storeDataItem(marshaller,value); 778 index=indexManager.createNewIndex(); 779 index.setValueData(data); 780 IndexItem prev=root; 781 IndexItem next=indexList.getNextEntry(prev); 782 prev.setNextItem(index.getOffset()); 783 index.setPreviousItem(prev.getOffset()); 784 updateIndexes(prev); 785 if(next!=null){ 786 next.setPreviousItem(index.getOffset()); 787 index.setNextItem(next.getOffset()); 788 updateIndexes(next); 789 } 790 storeIndex(index); 791 } 792 }catch(IOException e){ 793 log.error("Failed to write "+value,e); 794 throw new RuntimeStoreException(e); 795 } 796 return index; 797 } 798 799 protected synchronized IndexItem insert(int insertPos,Object value){ 800 IndexItem index=null; 801 try{ 802 if(value!=null){ 803 StoreLocation data=dataManager.storeDataItem(marshaller,value); 804 index=indexManager.createNewIndex(); 805 index.setValueData(data); 806 IndexItem prev=null; 807 IndexItem next=null; 808 if(insertPos<=0){ 809 prev=root; 810 next=indexList.getNextEntry(root); 811 }else if(insertPos>=indexList.size()){ 812 prev=indexList.getLast(); 813 next=null; 814 }else{ 815 prev=indexList.get(insertPos); 816 prev=prev!=null?prev:root; 817 next=indexList.getNextEntry(prev); 818 } 819 prev.setNextItem(index.getOffset()); 820 index.setPreviousItem(prev.getOffset()); 821 updateIndexes(prev); 822 if(next!=null){ 823 next.setPreviousItem(index.getOffset()); 824 index.setNextItem(next.getOffset()); 825 updateIndexes(next); 826 } 827 storeIndex(index); 828 } 829 }catch(IOException e){ 830 log.error("Failed to insert "+value,e); 831 throw new RuntimeStoreException(e); 832 } 833 return index; 834 } 835 836 protected synchronized Object getValue(StoreEntry item){ 837 Object result=null; 838 if(item!=null){ 839 try{ 840 StoreLocation data=item.getValueDataItem(); 841 result=dataManager.readItem(marshaller,data); 842 }catch(IOException e){ 843 log.error("Failed to get value for "+item,e); 844 throw new RuntimeStoreException(e); 845 } 846 } 847 return result; 848 } 849 850 853 public synchronized String toString(){ 854 StringBuffer result=new StringBuffer (); 855 result.append("["); 856 Iterator i=iterator(); 857 boolean hasNext=i.hasNext(); 858 while(hasNext){ 859 Object o=i.next(); 860 result.append(String.valueOf(o)); 861 hasNext=i.hasNext(); 862 if(hasNext) 863 result.append(", "); 864 } 865 result.append("]"); 866 return result.toString(); 867 } 868 869 protected synchronized void itemAdded(IndexItem item,int pos,Object value){ 870 871 } 872 873 protected synchronized void itemRemoved(int pos){ 874 875 } 876 } 877 | Popular Tags |