| 1 17 package org.eclipse.emf.common.util; 18 19 20 import java.io.IOException ; 21 import java.io.ObjectInputStream ; 22 import java.io.ObjectOutputStream ; 23 import java.io.Serializable ; 24 import java.util.AbstractCollection ; 25 import java.util.AbstractSet ; 26 import java.util.Collection ; 27 import java.util.ConcurrentModificationException ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import java.util.ListIterator ; 31 import java.util.Map ; 32 import java.util.NoSuchElementException ; 33 import java.util.Set ; 34 35 36 39 public class BasicEMap implements EMap, Cloneable , Serializable 40 { 41 47 public interface Entry extends Map.Entry  48 { 49 55 void setKey(Object key); 56 57 61 int getHash(); 62 63 69 void setHash(int hash); 70 } 71 72 75 protected transient EList delegateEList; 76 77 80 protected int size; 81 82 85 protected transient BasicEList entryData[]; 86 87 90 protected transient int modCount; 91 92 95 protected static class View 96 { 97 100 public transient Map map; 101 102 105 public transient Set keySet; 106 107 110 public transient Set entrySet; 111 112 115 public transient Collection values; 116 117 120 public View() 121 { 122 } 123 } 124 125 128 protected transient View view; 129 130 133 public BasicEMap() 134 { 135 initializeDelegateEList(); 136 } 137 138 143 protected void initializeDelegateEList() 144 { 145 delegateEList = 146 new BasicEList() 147 { 148 protected void didAdd(int index, Object newObject) 149 { 150 doPut((Entry)newObject); 151 } 152 153 protected void didSet(int index, Object newObject, Object oldObject) 154 { 155 didRemove(index, oldObject); 156 didAdd(index, newObject); 157 } 158 159 protected void didRemove(int index, Object oldObject) 160 { 161 doRemove((Entry)oldObject); 162 } 163 164 protected void didClear(int size, Object [] oldObjects) 165 { 166 doClear(); 167 } 168 169 protected void didMove(int index, Object movedObject, int oldIndex) 170 { 171 doMove((Entry)movedObject); 172 } 173 }; 174 } 175 176 181 public BasicEMap(int initialCapacity) 182 { 183 this(); 184 185 if (initialCapacity < 0) 186 { 187 throw new IllegalArgumentException ("Illegal Capacity:" + initialCapacity); 188 } 189 190 entryData = newEntryData(initialCapacity); 191 } 192 193 197 public BasicEMap(Map map) 198 { 199 this(); 200 int mapSize = map.size(); 201 if (mapSize > 0) 202 { 203 entryData = newEntryData(2 * mapSize); 204 putAll(map); 205 } 206 } 207 208 215 protected BasicEList [] newEntryData(int capacity) 216 { 217 return new BasicEList[capacity]; 218 } 219 220 224 protected void ensureEntryDataExists() 225 { 226 if (entryData == null) 227 { 228 entryData = newEntryData(2 * size + 1); 229 230 int oldModCount = modCount; 233 size = 0; 234 for (Iterator i = delegateEList.iterator(); i.hasNext(); ) 235 { 236 Entry entry = (Entry)i.next(); 237 doPut(entry); 238 } 239 modCount = oldModCount; 240 } 241 } 242 243 251 protected BasicEList newList() 252 { 253 return 254 new BasicEList() 255 { 256 public Object [] newData(int listCapacity) 257 { 258 return new EntryImpl [listCapacity]; 259 } 260 }; 261 } 262 263 274 protected Entry newEntry(int hash, Object key, Object value) 275 { 276 validateKey(key); 277 validateValue(value); 278 return new EntryImpl(hash, key, value); 279 } 280 281 288 protected Object putEntry(Entry entry, Object value) 289 { 290 return entry.setValue(value); 291 } 292 293 299 protected boolean useEqualsForKey() 300 { 301 return true; 302 } 303 304 310 protected boolean useEqualsForValue() 311 { 312 return true; 313 } 314 315 323 protected Object resolve(Object key, Object value) 324 { 325 return value; 326 } 327 328 336 protected void validateKey(Object key) 337 { 338 } 339 340 348 protected void validateValue(Object value) 349 { 350 } 351 352 358 protected void didAdd(Entry entry) 359 { 360 } 361 362 368 protected void didModify(Entry entry, Object oldValue) 369 { 370 } 371 372 378 protected void didRemove(Entry entry) 379 { 380 } 381 382 388 protected void didClear(BasicEList [] oldEntryData) 389 { 390 if (oldEntryData != null) 391 { 392 for (int i = 0; i < oldEntryData.length; ++i) 393 { 394 BasicEList eList = oldEntryData[i]; 395 if (eList != null) 396 { 397 Entry [] entries = (Entry [])eList.data; 398 int size = eList.size; 399 for (int j = 0; j < size; ++j) 400 { 401 Entry entry = entries[j]; 402 didRemove(entry); 403 } 404 } 405 } 406 } 407 } 408 409 413 public int size() 414 { 415 return size; 416 } 417 418 422 public boolean isEmpty() 423 { 424 return size == 0; 425 } 426 427 430 public int indexOfKey(Object key) 431 { 432 if (useEqualsForKey() && key != null) 433 { 434 for (int i = 0, size = delegateEList.size(); i < size; ++i) 435 { 436 Entry entry = (Entry)delegateEList.get(i); 437 if (key.equals(entry.getKey())) 438 { 439 return i; 440 } 441 } 442 } 443 else 444 { 445 for (int i = 0, size = delegateEList.size(); i < size; ++i) 446 { 447 Entry entry = (Entry)delegateEList.get(i); 448 if (key == entry.getKey()) 449 { 450 return i; 451 } 452 } 453 } 454 455 return -1; 456 } 457 458 461 public boolean containsKey(Object key) 462 { 463 if (size > 0) 464 { 465 ensureEntryDataExists(); 466 int hash = hashOf(key); 467 int index = indexOf(hash); 468 int entryIndex = entryIndexForKey(index, hash, key); 469 return entryIndex != -1; 470 } 471 else 472 { 473 return false; 474 } 475 } 476 477 480 public boolean containsValue(Object value) 481 { 482 if (size > 0) 483 { 484 ensureEntryDataExists(); 485 486 if (useEqualsForValue() && value != null) 487 { 488 for (int i = 0; i < entryData.length; ++i) 489 { 490 BasicEList eList = entryData[i]; 491 if (eList != null) 492 { 493 Entry [] entries = (Entry [])eList.data; 494 int size = eList.size; 495 for (int j = 0; j < size; ++j) 496 { 497 Entry entry = entries[j]; 498 if (value.equals(entry.getValue())) 499 { 500 return true; 501 } 502 } 503 } 504 } 505 } 506 else 507 { 508 for (int i = 0; i < entryData.length; ++i) 509 { 510 BasicEList eList = entryData[i]; 511 if (eList != null) 512 { 513 Entry [] entries = (Entry [])eList.data; 514 int size = eList.size; 515 for (int j = 0; j < size; ++j) 516 { 517 Entry entry = entries[j]; 518 if (value == entry.getValue()) 519 { 520 return true; 521 } 522 } 523 } 524 } 525 } 526 } 527 528 return false; 529 } 530 531 534 public Object get(Object key) 535 { 536 if (size > 0) 537 { 538 ensureEntryDataExists(); 539 int hash = hashOf(key); 540 int index = indexOf(hash); 541 Entry entry = entryForKey(index, hash, key); 542 if (entry != null) 543 { 544 return resolve(key, entry.getValue()); 545 } 546 } 547 548 return null; 549 } 550 551 554 public Object put(Object key, Object value) 555 { 556 ensureEntryDataExists(); 557 558 int hash = hashOf(key); 559 if (size > 0) 560 { 561 int index = indexOf(hash); 562 Entry entry = entryForKey(index, hash, key); 563 if (entry != null) 564 { 565 Object result = putEntry(entry, value); 566 didModify(entry, result); 567 return result; 568 } 569 } 570 571 Entry entry = newEntry(hash, key, value); 572 delegateEList.add(entry); 573 return null; 574 } 575 576 580 protected void doPut(Entry entry) 581 { 582 if (entryData == null) 583 { 584 ++modCount; 585 ++size; 586 } 587 else 588 { 589 int hash = entry.getHash(); 590 grow(size + 1); 591 int index = indexOf(hash); 592 BasicEList eList = entryData[index]; 593 if (eList == null) 594 { 595 eList = entryData[index] = newList(); 596 } 597 eList.add(entry); 598 ++size; 599 didAdd(entry); 600 } 601 } 602 603 606 public Object removeKey(Object key) 607 { 608 ensureEntryDataExists(); 609 610 int hash = hashOf(key); 611 int index = indexOf(hash); 612 Entry entry = entryForKey(index, hash, key); 613 if (entry != null) 614 { 615 remove(entry); 616 return entry.getValue(); 617 } 618 else 619 { 620 return null; 621 } 622 } 623 624 628 protected void doRemove(Entry entry) 629 { 630 if (entryData == null) 631 { 632 ++modCount; 633 --size; 634 } 635 else 636 { 637 Object key = entry.getKey(); 638 int hash = entry.getHash(); 639 int index = indexOf(hash); 640 removeEntry(index, entryIndexForKey(index, hash, key)); 641 didRemove(entry); 642 } 643 } 644 645 651 protected Object removeEntry(int index, int entryIndex) 652 { 653 ++modCount; 654 --size; 655 656 Entry entry = (Entry)entryData[index].remove(entryIndex); 657 return entry.getValue(); 658 } 659 660 663 public void putAll(Map map) 664 { 665 for (Iterator i = map.entrySet().iterator(); i.hasNext(); ) 666 { 667 Map.Entry entry = (Map.Entry )i.next(); 668 put(entry.getKey(), entry.getValue()); 669 } 670 } 671 672 675 public void putAll(EMap map) 676 { 677 for (Iterator i = map.iterator(); i.hasNext(); ) 678 { 679 Map.Entry entry = (Map.Entry )i.next(); 680 put(entry.getKey(), entry.getValue()); 681 } 682 } 683 684 687 protected void doClear() 688 { 689 if (entryData == null) 690 { 691 ++modCount; 692 size = 0; 693 didClear(null); 694 } 695 else 696 { 697 ++modCount; 698 BasicEList [] oldEntryData = entryData; 699 entryData = null; 700 size = 0; 701 didClear(oldEntryData); 702 } 703 } 704 705 708 protected void doMove(Entry entry) 709 { 710 ++modCount; 711 } 712 713 717 public Object clone() 718 { 719 try 720 { 721 BasicEMap result = (BasicEMap)super.clone(); 722 if (entryData != null) 723 { 724 result.entryData = newEntryData(entryData.length); 725 for (int i = 0; i < entryData.length; ++i) 726 { 727 result.entryData[i] = (entryData[i] == null ? null : (BasicEList)entryData[i].clone()); 728 } 729 } 730 result.view = null; 731 result.modCount = 0; 732 return result; 733 } 734 catch (CloneNotSupportedException exception) 735 { 736 throw new InternalError (); 737 } 738 } 739 740 protected class DelegatingMap implements EMap.InternalMapView 741 { 742 public DelegatingMap() 743 { 744 } 745 746 public EMap eMap() 747 { 748 return BasicEMap.this; 749 } 750 751 public int size() 752 { 753 return BasicEMap.this.size(); 754 } 755 756 public boolean isEmpty() 757 { 758 return BasicEMap.this.isEmpty(); 759 } 760 761 public boolean containsKey(Object key) 762 { 763 return BasicEMap.this.containsKey(key); 764 } 765 766 public boolean containsValue(Object value) 767 { 768 return BasicEMap.this.containsValue(value); 769 } 770 771 public Object get(Object key) 772 { 773 return BasicEMap.this.get(key); 774 } 775 776 public Object put(Object key, Object value) 777 { 778 return BasicEMap.this.put(key, value); 779 } 780 781 public Object remove(Object key) 782 { 783 return BasicEMap.this.removeKey(key); 784 } 785 786 public void putAll(Map map) 787 { 788 BasicEMap.this.putAll(map); 789 } 790 791 public void clear() 792 { 793 BasicEMap.this.clear(); 794 } 795 796 public Set keySet() 797 { 798 return BasicEMap.this.keySet(); 799 } 800 801 public Collection values() 802 { 803 return BasicEMap.this.values(); 804 } 805 806 public Set entrySet() 807 { 808 return BasicEMap.this.entrySet(); 809 } 810 811 public boolean equals(Object object) 812 { 813 return BasicEMap.this.equals(object); 814 } 815 816 public int hashCode() 817 { 818 return BasicEMap.this.hashCode(); 819 } 820 } 821 822 825 public Map map() 826 { 827 if (view == null) 828 { 829 view = new View(); 830 } 831 if (view.map == null) 832 { 833 view.map = new DelegatingMap(); 834 } 835 836 return view.map; 837 } 838 839 842 public Set keySet() 843 { 844 if (view == null) 845 { 846 view = new View(); 847 } 848 if (view.keySet == null) 849 { 850 view.keySet = 851 new AbstractSet () 852 { 853 public Iterator iterator() 854 { 855 return BasicEMap.this.size == 0 ? ECollections.EMPTY_ELIST.iterator() : new BasicEMap.BasicEMapKeyIterator(); 856 } 857 858 public int size() 859 { 860 return BasicEMap.this.size; 861 } 862 863 public boolean contains(Object key) 864 { 865 return BasicEMap.this.containsKey(key); 866 } 867 868 public boolean remove(Object key) 869 { 870 int oldSize = BasicEMap.this.size; 871 BasicEMap.this.removeKey(key); 872 return BasicEMap.this.size != oldSize; 873 } 874 875 public void clear() 876 { 877 BasicEMap.this.clear(); 878 } 879 }; 880 } 881 return view.keySet; 882 } 883 884 887 public Collection values() 888 { 889 if (view == null) 890 { 891 view = new View(); 892 } 893 if (view.values == null) 894 { 895 view.values = 896 new AbstractCollection () 897 { 898 public Iterator iterator() 899 { 900 return BasicEMap.this.size == 0 ? ECollections.EMPTY_ELIST.iterator() : new BasicEMap.BasicEMapValueIterator(); 901 } 902 public int size() 903 { 904 return size; 905 } 906 public boolean contains(Object value) 907 { 908 return containsValue(value); 909 } 910 public void clear() 911 { 912 BasicEMap.this.clear(); 913 } 914 }; 915 } 916 return view.values; 917 } 918 919 922 public Set entrySet() 923 { 924 if (view == null) 925 { 926 view = new View(); 927 } 928 if (view.entrySet == null) 929 { 930 view.entrySet = new AbstractSet () 931 { 932 public int size() 933 { 934 return BasicEMap.this.size; 935 } 936 937 public boolean contains(Object object) 938 { 939 if (BasicEMap.this.size > 0 && object instanceof Map.Entry ) 940 { 941 BasicEMap.this.ensureEntryDataExists(); 942 Map.Entry otherEntry = (Map.Entry )object; 943 Object key = otherEntry.getKey(); 944 945 int hash = key == null ? 0 : key.hashCode(); 946 int index = BasicEMap.this.indexOf(hash); 947 BasicEList eList = entryData[index]; 948 if (eList != null) 949 { 950 Entry [] entries = (Entry [])eList.data; 951 int size = eList.size; 952 for (int j = 0; j < size; ++j) 953 { 954 Entry entry = entries[j]; 955 if (entry.getHash() == hash && entry.equals(otherEntry)) 956 { 957 return true; 958 } 959 } 960 } 961 } 962 return false; 963 } 964 965 public boolean remove(Object object) 966 { 967 if (BasicEMap.this.size > 0 && object instanceof Map.Entry ) 968 { 969 BasicEMap.this.ensureEntryDataExists(); 970 Map.Entry otherEntry = (Map.Entry )object; 971 Object key = otherEntry.getKey(); 972 int hash = key == null ? 0 : key.hashCode(); 973 int index = BasicEMap.this.indexOf(hash); 974 BasicEList eList = entryData[index]; 975 if (eList != null) 976 { 977 Entry [] entries = (Entry [])eList.data; 978 int size = eList.size; 979 for (int j = 0; j < size; ++j) 980 { 981 Entry entry = entries[j]; 982 if (entry.getHash() == hash && entry.equals(otherEntry)) 983 { 984 remove(otherEntry); 986 return true; 987 } 988 } 989 } 990 } 991 return false; 992 } 993 994 public void clear() 995 { 996 BasicEMap.this.clear(); 997 } 998 999 public Iterator iterator() 1000 { 1001 return BasicEMap.this.size == 0 ? ECollections.EMPTY_ELIST.iterator() : new BasicEMap.BasicEMapIterator(); 1002 } 1003 }; 1004 } 1005 1006 return view.entrySet; 1007 } 1008 1009 1012 protected class EntryImpl implements Entry 1013 { 1014 1017 protected int hash; 1018 1019 1022 protected Object key; 1023 1024 1027 protected Object value; 1028 1029 |