1 /*
2 * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
812 tab[i] = null;
813 tab[i + 1] = null;
814 d = i;
815 }
816 }
817 }
818 }
819
820 private class KeyIterator extends IdentityHashMapIterator<K> {
821 public K next() {
822 return (K) unmaskNull(traversalTable[nextIndex()]);
823 }
824 }
825
826 private class ValueIterator extends IdentityHashMapIterator<V> {
827 public V next() {
828 return (V) traversalTable[nextIndex() + 1];
829 }
830 }
831
832 /**
833 * Since we don't use Entry objects, we use the Iterator
834 * itself as an entry.
835 */
836 private class EntryIterator
837 extends IdentityHashMapIterator<Map.Entry<K,V>>
838 implements Map.Entry<K,V>
839 {
840 public Map.Entry<K,V> next() {
841 nextIndex();
842 return this;
843 }
844
845 public K getKey() {
846 // Provide a better exception than out of bounds index
847 if (lastReturnedIndex < 0)
848 throw new IllegalStateException("Entry was removed");
849
850 return (K) unmaskNull(traversalTable[lastReturnedIndex]);
851 }
852
853 public V getValue() {
854 // Provide a better exception than out of bounds index
855 if (lastReturnedIndex < 0)
856 throw new IllegalStateException("Entry was removed");
857
858 return (V) traversalTable[lastReturnedIndex+1];
859 }
860
861 public V setValue(V value) {
862 // It would be mean-spirited to proceed here if remove() called
863 if (lastReturnedIndex < 0)
864 throw new IllegalStateException("Entry was removed");
865 V oldValue = (V) traversalTable[lastReturnedIndex+1];
866 traversalTable[lastReturnedIndex+1] = value;
867 // if shadowing, force into main table
868 if (traversalTable != IdentityHashMap.this.table)
869 put((K) traversalTable[lastReturnedIndex], value);
870 return oldValue;
871 }
872
873 public boolean equals(Object o) {
874 if (lastReturnedIndex < 0)
875 return super.equals(o);
876
877 if (!(o instanceof Map.Entry))
878 return false;
879 Map.Entry e = (Map.Entry)o;
880 return e.getKey() == getKey() &&
881 e.getValue() == getValue();
882 }
883
884 public int hashCode() {
885 if (lastReturnedIndex < 0)
886 return super.hashCode();
887
888 return System.identityHashCode(getKey()) ^
889 System.identityHashCode(getValue());
890 }
891
892 public String toString() {
893 if (lastReturnedIndex < 0)
894 return super.toString();
895
896 return getKey() + "=" + getValue();
897 }
898 }
899
900 // Views
901
902 /**
903 * This field is initialized to contain an instance of the entry set
904 * view the first time this view is requested. The view is stateless,
905 * so there's no reason to create more than one.
906 */
907 private transient Set<Map.Entry<K,V>> entrySet = null;
908
909 /**
910 * Returns an identity-based set view of the keys contained in this map.
911 * The set is backed by the map, so changes to the map are reflected in
912 * the set, and vice-versa. If the map is modified while an iteration
913 * over the set is in progress, the results of the iteration are
914 * undefined. The set supports element removal, which removes the
915 * corresponding mapping from the map, via the <tt>Iterator.remove</tt>,
916 * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
|
1 /*
2 * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
812 tab[i] = null;
813 tab[i + 1] = null;
814 d = i;
815 }
816 }
817 }
818 }
819
820 private class KeyIterator extends IdentityHashMapIterator<K> {
821 public K next() {
822 return (K) unmaskNull(traversalTable[nextIndex()]);
823 }
824 }
825
826 private class ValueIterator extends IdentityHashMapIterator<V> {
827 public V next() {
828 return (V) traversalTable[nextIndex() + 1];
829 }
830 }
831
832 private class EntryIterator
833 extends IdentityHashMapIterator<Map.Entry<K,V>>
834 {
835 private Entry lastReturnedEntry = null;
836
837 public Map.Entry<K,V> next() {
838 lastReturnedEntry = new Entry(nextIndex());
839 return lastReturnedEntry;
840 }
841
842 public void remove() {
843 lastReturnedIndex =
844 ((null == lastReturnedEntry) ? -1 : lastReturnedEntry.index);
845 super.remove();
846 lastReturnedEntry.index = lastReturnedIndex;
847 lastReturnedEntry = null;
848 }
849
850 private class Entry implements Map.Entry<K,V> {
851 private int index;
852
853 private Entry(int index) {
854 this.index = index;
855 }
856
857 public K getKey() {
858 checkIndexForEntryUse();
859 return (K) unmaskNull(traversalTable[index]);
860 }
861
862 public V getValue() {
863 checkIndexForEntryUse();
864 return (V) traversalTable[index+1];
865 }
866
867 public V setValue(V value) {
868 checkIndexForEntryUse();
869 V oldValue = (V) traversalTable[index+1];
870 traversalTable[index+1] = value;
871 // if shadowing, force into main table
872 if (traversalTable != IdentityHashMap.this.table)
873 put((K) traversalTable[index], value);
874 return oldValue;
875 }
876
877 public boolean equals(Object o) {
878 if (index < 0)
879 return super.equals(o);
880
881 if (!(o instanceof Map.Entry))
882 return false;
883 Map.Entry e = (Map.Entry)o;
884 return (e.getKey() == unmaskNull(traversalTable[index]) &&
885 e.getValue() == traversalTable[index+1]);
886 }
887
888 public int hashCode() {
889 if (lastReturnedIndex < 0)
890 return super.hashCode();
891
892 return (System.identityHashCode(unmaskNull(traversalTable[index])) ^
893 System.identityHashCode(traversalTable[index+1]));
894 }
895
896 public String toString() {
897 if (index < 0)
898 return super.toString();
899
900 return (unmaskNull(traversalTable[index]) + "="
901 + traversalTable[index+1]);
902 }
903
904 private void checkIndexForEntryUse() {
905 if (index < 0)
906 throw new IllegalStateException("Entry was removed");
907 }
908 }
909 }
910
911 // Views
912
913 /**
914 * This field is initialized to contain an instance of the entry set
915 * view the first time this view is requested. The view is stateless,
916 * so there's no reason to create more than one.
917 */
918 private transient Set<Map.Entry<K,V>> entrySet = null;
919
920 /**
921 * Returns an identity-based set view of the keys contained in this map.
922 * The set is backed by the map, so changes to the map are reflected in
923 * the set, and vice-versa. If the map is modified while an iteration
924 * over the set is in progress, the results of the iteration are
925 * undefined. The set supports element removal, which removes the
926 * corresponding mapping from the map, via the <tt>Iterator.remove</tt>,
927 * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
|