1 9 package javolution.util; 10 11 import java.io.IOException ; 12 import java.util.NoSuchElementException ; 13 14 import j2me.io.ObjectInputStream; 15 import j2me.io.ObjectOutputStream; 16 import j2me.lang.IllegalStateException; 17 import j2me.lang.UnsupportedOperationException; 18 import j2me.util.Collection; 19 import j2me.util.Iterator; 20 import j2me.util.List; 21 import j2me.util.ListIterator; 22 import j2me.util.RandomAccess; 23 import j2mex.realtime.MemoryArea; 24 import javolution.context.PersistentContext; 25 import javolution.context.RealtimeObject; 26 import javolution.lang.Reusable; 27 28 62 public class FastTableextends FastCollectionimplements 63 List, Reusable, RandomAccess { 64 65 68 private static final Factory FACTORY = new Factory() { 69 public Object create() { 70 return new FastTable(); 71 } 72 73 public void cleanup(Object obj) { 74 ((FastTable) obj).reset(); 75 } 76 }; 77 78 86 private static final int D0 = 5; 87 88 private static final int M0 = (1 << D0) - 1; 89 90 private static final int C0 = 1 << D0; 92 private static final int D1 = D0 + 2; 93 94 private static final int R1 = D0; 95 96 private static final int M1 = (1 << D1) - 1; 97 98 private static final int C1 = 1 << (D0 + D1); 100 private static final int D2 = D1 + 2; 101 102 private static final int R2 = D0 + D1; 103 104 private static final int M2 = (1 << D2) - 1; 105 106 private static final int C2 = 1 << (D0 + D1 + D2); 108 private static final int D3 = D2 + 2; 109 110 private static final int R3 = D0 + D1 + D2; 111 112 private transient Object [][] _elems1; 114 115 private transient Object [][][] _elems2; 117 118 private transient Object [][][][] _elems3; 120 121 124 private transient int _capacity = C0; 125 126 129 private transient int _size; 130 131 134 private transient FastComparator _valueComparator = FastComparator.DEFAULT; 135 136 139 public FastTable() { 140 _elems1 = (Object [][]) new Object [1][]; 141 _elems1[0] = (Object []) new Object [C0]; 142 } 143 144 152 public FastTable(String id) { 153 this(); 154 new PersistentContext.Reference(id, this) { 155 protected void notifyChange() { 156 FastTable.this.clear(); 157 FastTable.this.addAll((FastList) this.get()); 158 } 159 }; 160 } 161 162 169 public FastTable(int capacity) { 170 this(); 171 while (capacity > _capacity) { 172 increaseCapacity(); 173 } 174 } 175 176 182 public FastTable(Collectionvalues) { 183 this(values.size()); 184 addAll(values); 185 } 186 187 194 public staticFastTablenewInstance() { 195 return (FastTable) FACTORY.object(); 196 } 197 198 203 public static void recycle(FastTable instance) { 204 FACTORY.recycle(instance); 205 } 206 207 212 protected final int getCapacity() { 213 return _capacity; 214 } 215 216 224 public final Object get(int index) { if (((index >> R2) == 0) && (index < _size)) 226 return _elems1[(index >> R1)][index & M0]; 227 return get2(index); 228 } 229 230 private final Object get2(int index) { 231 if ((index < 0) || (index >= _size)) 232 throw new IndexOutOfBoundsException ("index: " + index); 233 return (index < C2) ? _elems2[(index >> R2)][(index >> R1) & M1][index 234 & M0] 235 : _elems3[(index >> R3)][(index >> R2) & M2][(index >> R1) & M1][index 236 & M0]; 237 } 238 239 248 public final Object set(int index, Object value) { 249 if ((index < 0) || (index >= _size)) 250 throw new IndexOutOfBoundsException ("index: " + index); 251 final Object [] elems = (index < C1) ? _elems1[(index >> R1)] 252 : (index < C2) ? _elems2[(index >> R2)][(index >> R1) & M1] 253 : _elems3[(index >> R3)][(index >> R2) & M2][(index >> R1) 254 & M1]; 255 final Object oldValue = elems[index & M0]; 256 elems[index & M0] = value; 257 return oldValue; 258 } 259 260 267 public final boolean add(Object value) { 268 final int i = _size; 269 if (i >= _capacity) { 270 increaseCapacity(); 271 } 272 final Object [] elems = (i < C1) ? _elems1[(i >> R1)] 273 : (i < C2) ? _elems2[(i >> R2)][(i >> R1) & M1] 274 : _elems3[(i >> R3)][(i >> R2) & M2][(i >> R1) & M1]; 275 elems[i & M0] = value; 276 _size++; 279 return true; 280 } 281 282 288 public final Object getFirst() { 289 if (_size == 0) 290 throw new NoSuchElementException (); 291 return _elems1[0][0]; 292 } 293 294 300 public final Object getLast() { 301 if (_size == 0) 302 throw new NoSuchElementException (); 303 final int i = _size - 1; 304 final Object [] elems = (i < C1) ? _elems1[(i >> R1)] 305 : (i < C2) ? _elems2[(i >> R2)][(i >> R1) & M1] 306 : _elems3[(i >> R3)][(i >> R2) & M2][(i >> R1) & M1]; 307 return elems[i & M0]; 308 } 309 310 315 public final void addLast(Object value) { 316 add(value); 317 } 318 319 325 public final Object removeLast() { 326 if (_size == 0) 327 throw new NoSuchElementException (); 328 final int i = --_size; 329 final Object [] elems = (i < C1) ? _elems1[(i >> R1)] 330 : (i < C2) ? _elems2[(i >> R2)][(i >> R1) & M1] 331 : _elems3[(i >> R3)][(i >> R2) & M2][(i >> R1) & M1]; 332 final Object oldValue = elems[i & M0]; 333 elems[i & M0] = null; 334 return oldValue; 335 } 336 337 public final void clear() { 339 final int size = _size; 340 _size = 0; 341 final int blockSize = Math.min(size, C0); 342 for (int i = 0; i < size; i += C0) { 343 final Object [] elems = (i < C1) ? _elems1[(i >> R1)] 344 : (i < C2) ? _elems2[(i >> R2)][(i >> R1) & M1] 345 : _elems3[(i >> R3)][(i >> R2) & M2][(i >> R1) & M1]; 346 System.arraycopy(NULL_BLOCK, 0, elems, 0, blockSize); 347 } 348 } 349 350 private static final Object [] NULL_BLOCK = (Object []) new Object [C0]; 351 352 366 public final boolean addAll(int index, Collectionvalues) { 367 if ((index < 0) || (index > _size)) 368 throw new IndexOutOfBoundsException ("index: " + index); 369 final int shift = values.size(); 370 final int prevSize = _size; 371 final int newSize = prevSize + shift; 372 while (newSize >= _capacity) { 373 increaseCapacity(); 374 } 375 _size = newSize; for (int i = prevSize; --i >= index;) { 378 this.set(i + shift, this.get(i)); 379 } 380 IteratorvaluesIterator = values.iterator(); 381 for (int i = index, n = index + shift; i < n; i++) { 382 this.set(i, valuesIterator.next()); 383 } 384 return shift != 0; 385 } 386 387 398 public final void add(int index, Object value) { 399 if ((index < 0) || (index > _size)) 400 throw new IndexOutOfBoundsException ("index: " + index); 401 final int prevSize = _size; 402 final int newSize = prevSize + 1; 403 if (newSize >= _capacity) { 404 increaseCapacity(); 405 } 406 _size = newSize; 407 for (int i = index, n = newSize; i < n;) { 408 value = this.set(i++, value); 409 } 410 } 411 412 423 public final Object remove(int index) { 424 if ((index < 0) || (index >= _size)) 425 throw new IndexOutOfBoundsException ("index: " + index); 426 final int lastIndex = _size - 1; 427 Object obj = this.get(lastIndex); 428 for (int i = lastIndex; --i >= index;) { 429 obj = this.set(i, obj); 430 } 431 this.set(lastIndex, null); _size = lastIndex; 433 return obj; 434 } 435 436 445 public final void removeRange(int fromIndex, int toIndex) { 446 final int prevSize = _size; 447 if ((fromIndex < 0) || (toIndex < 0) || (fromIndex > toIndex) 448 || (toIndex > prevSize)) 449 throw new IndexOutOfBoundsException (); 450 for (int i = toIndex, j = fromIndex; i < prevSize;) { 451 this.set(j++, this.get(i++)); 452 } 453 final int newSize = prevSize - toIndex + fromIndex; 454 for (int i = newSize; i < prevSize;) { 455 this.set(i++, null); } 457 _size = newSize; 458 } 459 460 468 public final int indexOf(Object value) { 469 final FastComparator comp = this.getValueComparator(); 470 for (int i = -1; ++i < _size;) { 471 if (comp.areEqual(value, get(i))) 472 return i; 473 } 474 return -1; 475 } 476 477 485 public final int lastIndexOf(Object value) { 486 final FastComparator comp = this.getValueComparator(); 487 for (int i = _size; --i >= 0;) { 488 if (comp.areEqual(value, get(i))) 489 return i; 490 } 491 return -1; 492 } 493 494 501 public Iteratoriterator() { 502 FastTableIterator i = (FastTableIterator) FastTableIterator.FACTORY 503 .object(); 504 i._table = this; 505 i._start = 0; 506 i._end = this._size; 507 i._nextIndex = 0; 508 i._currentIndex = -1; 509 return i; 510 } 511 512 519 public ListIteratorlistIterator() { 520 FastTableIterator i = (FastTableIterator) FastTableIterator.FACTORY 521 .object(); 522 i._table = this; 523 i._start = 0; 524 i._end = this._size; 525 i._nextIndex = 0; 526 i._currentIndex = -1; 527 return i; 528 } 529 530 543 public ListIteratorlistIterator(int index) { 544 if ((index >= 0) && (index <= _size)) { 545 FastTableIterator i = (FastTableIterator) FastTableIterator.FACTORY 546 .object(); 547 i._table = this; 548 i._start = 0; 549 i._end = this._size; 550 i._nextIndex = index; 551 i._currentIndex = -1; 552 return i; 553 } else { 554 throw new IndexOutOfBoundsException ("index: " + index 555 + " for table of size: " + _size); 556 } 557 } 558 559 590 public final ListsubList(int fromIndex, int toIndex) { 591 if ((fromIndex < 0) || (toIndex > _size) || (fromIndex > toIndex)) 592 throw new IndexOutOfBoundsException ("fromIndex: " + fromIndex 593 + ", toIndex: " + toIndex + " for list of size: " + _size); 594 SubTable st = (SubTable) SubTable.FACTORY.object(); 595 st._table = this; 596 st._offset = fromIndex; 597 st._size = toIndex - fromIndex; 598 return st; 599 } 600 601 605 public final void trimToSize() { 606 while (_capacity > _size + C0) { 607 decreaseCapacity(); 608 } 609 } 610 611 615 public final void sort() { 616 if (_size > 1) { 617 quicksort(0, _size - 1, this.getValueComparator()); 618 } 619 } 620 621 private void quicksort(int first, int last, FastComparator cmp) { 624 int pivIndex = 0; 625 if (first < last) { 626 pivIndex = partition(first, last, cmp); 627 quicksort(first, (pivIndex - 1), cmp); 628 quicksort((pivIndex + 1), last, cmp); 629 } 630 } 631 632 private int partition(int f, int l, FastComparator cmp) { 633 int up, down; 634 Object piv = this.get(f); 635 up = f; 636 down = l; 637 do { 638 while (cmp.compare(get(up), piv) <= 0 && up < l) { 639 up++; 640 } 641 while (cmp.compare(get(down), piv) > 0 && down > f) { 642 down--; 643 } 644 if (up < down) { Object temp = get(up); 646 set(up, get(down)); 647 set(down, temp); 648 } 649 } while (down > up); 650 set(f, get(down)); 651 set(down, piv); 652 return down; 653 } 654 655 656 662 public FastTable setValueComparator(FastComparator comparator) { 663 _valueComparator = comparator; 664 return this; 665 } 666 667 public FastComparator getValueComparator() { 669 return _valueComparator; 670 } 671 672 public final int size() { 674 return _size; 675 } 676 677 public final Record head() { 679 return Index.valueOf(-1); 680 } 681 682 public final Record tail() { 684 return Index.valueOf(_size); 685 } 686 687 public final Object valueOf(Record record) { 689 return get(((Index) record).intValue()); 690 } 691 692 public final void delete(Record record) { 694 remove(((Index) record).intValue()); 695 } 696 697 public Collectionunmodifiable() { 699 return (Collection) super.unmodifiable(); 700 } 701 702 private void readObject(ObjectInputStream stream) throws IOException , 704 ClassNotFoundException { 705 _capacity = C0; 707 _elems1 = (Object [][]) new Object [1][]; 708 _elems1[0] = (Object []) new Object [C0]; 709 710 setValueComparator((FastComparator) stream.readObject()); 711 final int size = stream.readInt(); 712 for (int i = 0; i < size; i++) { 713 addLast((Object ) stream.readObject()); 714 } 715 } 716 717 private void writeObject(ObjectOutputStream stream) throws IOException { 719 stream.writeObject(getValueComparator()); 720 final int size = _size; 721 stream.writeInt(size); 722 for (int i = 0; i < size; i++) { 723 stream.writeObject(get(i)); 724 } 725 } 726 727 730 protected void increaseCapacity() { 731 MemoryArea.getMemoryArea(this).executeInArea(new Runnable () { 732 public void run() { 733 final int c = _capacity; 734 _capacity += C0; 735 if (c < C1) { 736 if (_elems1.length == 1) { Object [][] tmp = (Object [][]) new Object [1 << D1][]; 738 tmp[0] = _elems1[0]; 739 _elems1 = tmp; 740 } 741 _elems1[(c >> R1)] = (Object []) new Object [1 << D0]; 742 743 } else if (c < C2) { 744 if (_elems2 == null) { 745 _elems2 = (Object [][][]) new Object [1 << D2][][]; 746 } 747 if (_elems2[(c >> R2)] == null) { 748 _elems2[(c >> R2)] = (Object [][]) new Object [1 << D1][]; 749 } 750 _elems2[(c >> R2)][(c >> R1) & M1] = (Object []) new Object [1 << D0]; 751 752 } else { 753 if (_elems3 == null) { 754 _elems3 = (Object [][][][]) new Object [D3][][][]; 755 } 756 if (_elems3[(c >> R3)] == null) { 757 _elems3[(c >> R3)] = (Object [][][]) new Object [D2][][]; 758 } 759 if (_elems3[(c >> R3)][(c >> R2) & M2] == null) { 760 _elems3[(c >> R3)][(c >> R2) & M2] = (Object [][]) new Object [D1][]; 761 } 762 _elems3[(c >> R3)][(c >> R2) & M2][(c >> R1) & M1] = (Object []) new Object [D0]; 763 } 764 } 765 }); 766 } 767 768 771 protected void decreaseCapacity() { 772 if (_size >= _capacity - C0) return; 773 final int c = _capacity; 774 _capacity -= C0; 775 if (c < C1) { 776 _elems1[(c >> R1)] = null; 777 _elems2 = null; 778 _elems3 = null; 779 } else if (c < C2) { 780 _elems2[(c >> R2)][(c >> R1) & M1] = null; 781 _elems3 = null; 782 } else { 783 _elems3[(c >> R3)][(c >> R2) & M2][(c >> R1) & M1] = null; 784 } 785 } 786 787 790 private static final class FastTableIterator extends RealtimeObject 791 implements ListIterator { 792 793 private static final Factory FACTORY = new Factory() { 794 protected Object create() { 795 return new FastTableIterator(); 796 } 797 798 protected void cleanup(Object obj) { 799 FastTableIterator i = (FastTableIterator) obj; 800 i._table = null; 801 } 802 }; 803 804 private FastTable _table; 805 806 private int _currentIndex; 807 808 private int _start; 810 private int _end; 812 private int _nextIndex; 813 814 public boolean hasNext() { 815 return (_nextIndex != _end); 816 } 817 818 public Object next() { 819 if (_nextIndex == _end) 820 throw new NoSuchElementException (); 821 return _table.get(_currentIndex = _nextIndex++); 822 } 823 824 public int nextIndex() { 825 return _nextIndex; 826 } 827 828 public boolean hasPrevious() { 829 return _nextIndex != _start; 830 } 831 832 public Object previous() { 833 if (_nextIndex == _start) 834 throw new NoSuchElementException (); 835 return _table.get(_currentIndex = --_nextIndex); 836 } 837 838 public int previousIndex() { 839 return _nextIndex - 1; 840 } 841 842 public void add(Object o) { 843 _table.add(_nextIndex++, o); 844 _end++; 845 _currentIndex = -1; 846 } 847 848 public void set(Object o) { 849 if (_currentIndex >= 0) { 850 _table.set(_currentIndex, o); 851 } else { 852 throw new IllegalStateException (); 853 } 854 } 855 856 public void remove() { 857 if (_currentIndex >= 0) { 858 _table.remove(_currentIndex); 859 _end--; 860 if (_currentIndex < _nextIndex) { 861 _nextIndex--; 862 } 863 _currentIndex = -1; 864 } else { 865 throw new IllegalStateException (); 866 } 867 } 868 } 869 870 873 private static final class SubTable extends FastCollection implements List, 874 RandomAccess { 875 876 private static final Factory FACTORY = new Factory() { 877 protected Object create() { 878 return new SubTable(); 879 } 880 881 protected void cleanup(Object obj) { 882 SubTable st = (SubTable) obj; 883 st._table = null; 884 } 885 }; 886 887 private FastTable _table; 888 889 private int _offset; 890 891 private int _size; 892 893 public int size() { 894 return _size; 895 } 896 897 public Record head() { 898 return Index.valueOf(-1); 899 } 900 901 public Record tail() { 902 return Index.valueOf(_size); 903 } 904 905 public Object valueOf(Record record) { 906 return _table.get(((Index) record).intValue() + _offset); 907 } 908 909 public void delete(Record record) { 910 throw new UnsupportedOperationException ( 911 "Deletion not supported, thread-safe collections."); 912 } 913 914 public boolean addAll(int index, Collection values) { 915 throw new UnsupportedOperationException ( 916 "Insertion not supported, thread-safe collections."); 917 } 918 919 public Object get(int index) { 920 if ((index < 0) || (index >= _size)) 921 throw new IndexOutOfBoundsException ("index: " + index); 922 return _table.get(index + _offset); 923 } 924 925 public Object set(int index, Object value) { 926 if ((index < 0) || (index >= _size)) 927 throw new IndexOutOfBoundsException ("index: " + index); 928 return _table.set(index + _offset, value); 929 } 930 931 public void add(int index, Object element) { 932 throw new UnsupportedOperationException ( 933 "Insertion not supported, thread-safe collections."); 934 } 935 936 public Object remove(int index) { 937 throw new UnsupportedOperationException ( 938 "Deletion not supported, thread-safe collections."); 939 } 940 941 public int indexOf(Object value) { 942 final FastComparator comp = _table.getValueComparator(); 943 for (int i = -1; ++i < _size;) { 944 if (comp.areEqual(value, _table.get(i + _offset))) 945 return i; 946 } 947 return -1; 948 } 949 950 public int lastIndexOf(Object value) { 951 final FastComparator comp = _table.getValueComparator(); 952 for (int i = _size; --i >= 0;) { 953 if (comp.areEqual(value, _table.get(i + _offset))) 954 return i; 955 } 956 return -1; 957 } 958 959 public ListIterator listIterator() { 960 return listIterator(0); 961 } 962 963 public ListIterator listIterator(int index) { 964 if ((index >= 0) && (index <= _size)) { 965 FastTableIterator i = (FastTableIterator) FastTableIterator.FACTORY 966 .object(); 967 i._table = _table; 968 i._start = _offset; 969 i._end = _offset + _size; 970 i._nextIndex = index + _offset; 971 return i; 972 } else { 973 throw new IndexOutOfBoundsException ("index: " + index 974 + " for table of size: " + _size); 975 } 976 } 977 978 public List subList(int fromIndex, int toIndex) { 979 if ((fromIndex < 0) || (toIndex > _size) || (fromIndex > toIndex)) 980 throw new IndexOutOfBoundsException ("fromIndex: " + fromIndex 981 + ", toIndex: " + toIndex + " for list of size: " 982 + _size); 983 SubTable st = (SubTable) SubTable.FACTORY.object(); 984 st._table = _table; 985 st._offset = _offset + fromIndex; 986 st._size = toIndex - fromIndex; 987 return st; 988 } 989 } 990 991 private static final long serialVersionUID = 1L; 992 } | Popular Tags |