ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentHashMap.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/ConcurrentHashMap.java (file contents):
Revision 1.29 by dl, Wed Nov 12 01:04:24 2003 UTC vs.
Revision 1.30 by dl, Fri Nov 21 17:50:28 2003 UTC

# Line 437 | Line 437 | public class ConcurrentHashMap<K, V> ext
437      }
438  
439      /**
440 <     * ConcurrentHashMap list entry.
440 >     * ConcurrentHashMap list entry. Note that this is never exported
441 >     * out as a user-visible Map.Entry
442       */
443 <    private static class HashEntry<K,V> implements Entry<K,V> {
443 >    private static class HashEntry<K,V> {
444          private final K key;
445          private V value;
446          private final int hash;
# Line 451 | Line 452 | public class ConcurrentHashMap<K, V> ext
452              this.key = key;
453              this.next = next;
454          }
454
455        public K getKey() {
456            return key;
457        }
458
459        public V getValue() {
460            return value;
461        }
462
463        public V setValue(V newValue) {
464            // We aren't required to, and don't provide any
465            // visibility barriers for setting value.
466            if (newValue == null)
467                throw new NullPointerException();
468            V oldValue = this.value;
469            this.value = newValue;
470            return oldValue;
471        }
472
473        public boolean equals(Object o) {
474            if (!(o instanceof Entry))
475                return false;
476            Entry<K,V> e = (Entry<K,V>)o;
477            return (key.equals(e.getKey()) && value.equals(e.getValue()));
478        }
479
480        public int hashCode() {
481            return  key.hashCode() ^ value.hashCode();
482        }
483
484        public String toString() {
485            return key + "=" + value;
486        }
455      }
456  
457  
# Line 952 | Line 920 | public class ConcurrentHashMap<K, V> ext
920          private int nextTableIndex;
921          private HashEntry[] currentTable;
922          private HashEntry<K, V> nextEntry;
923 <        private HashEntry<K, V> lastReturned;
923 >        HashEntry<K, V> lastReturned;
924  
925          private HashIterator() {
926              nextSegmentIndex = segments.length - 1;
# Line 1013 | Line 981 | public class ConcurrentHashMap<K, V> ext
981          public V nextElement() { return super.nextEntry().value; }
982      }
983  
984 <    private class EntryIterator extends HashIterator implements Iterator<Entry<K,V>> {
985 <        public Map.Entry<K,V> next() { return super.nextEntry(); }
984 >    
985 >
986 >    /**
987 >     * Exported Entry objects must write-through changes in setValue,
988 >     * even if the nodes have been cloned. So we cannot return
989 >     * internal HashEntry objects. Instead, the iterator itself acts
990 >     * as a forwarding pseudo-entry.
991 >     */
992 >    private class EntryIterator extends HashIterator implements Map.Entry<K,V>, Iterator<Entry<K,V>> {
993 >        public Map.Entry<K,V> next() {
994 >            nextEntry();
995 >            return this;
996 >        }
997 >
998 >        public K getKey() {
999 >            if (lastReturned == null)
1000 >                throw new IllegalStateException("Entry was removed");
1001 >            return lastReturned.key;
1002 >        }
1003 >
1004 >        public V getValue() {
1005 >            if (lastReturned == null)
1006 >                throw new IllegalStateException("Entry was removed");
1007 >            return ConcurrentHashMap.this.get(lastReturned.key);
1008 >        }
1009 >
1010 >        public V setValue(V value) {
1011 >            if (lastReturned == null)
1012 >                throw new IllegalStateException("Entry was removed");
1013 >            return ConcurrentHashMap.this.put(lastReturned.key, value);
1014 >        }
1015 >
1016 >        public boolean equals(Object o) {
1017 >            if (!(o instanceof Map.Entry))
1018 >                return false;
1019 >            Map.Entry e = (Map.Entry)o;
1020 >            return eq(getKey(), e.getKey()) && eq(getValue(), e.getValue());
1021 >        }
1022 >
1023 >        public int hashCode() {
1024 >            Object k = getKey();
1025 >            Object v = getValue();
1026 >            return ((k == null) ? 0 : k.hashCode()) ^
1027 >                   ((v == null) ? 0 : v.hashCode());
1028 >        }
1029 >
1030 >        public String toString() {
1031 >            return getKey() + "=" + getValue();
1032 >        }
1033 >
1034 >        private boolean eq(Object o1, Object o2) {
1035 >            return (o1 == null ? o2 == null : o1.equals(o2));
1036 >        }
1037 >
1038      }
1039  
1040      private class KeySet extends AbstractSet<K> {
# Line 1073 | Line 1093 | public class ConcurrentHashMap<K, V> ext
1093          public void clear() {
1094              ConcurrentHashMap.this.clear();
1095          }
1096 +        public Object[] toArray() {
1097 +            // Since we don't ordinarily have distinct Entry objects, we
1098 +            // must pack elements using exportable SimpleEntry
1099 +            Collection<Map.Entry<K,V>> c = new ArrayList<Map.Entry<K,V>>(size());
1100 +            for (Iterator<Map.Entry<K,V>> i = iterator(); i.hasNext(); )
1101 +                c.add(new SimpleEntry<K,V>(i.next()));
1102 +            return c.toArray();
1103 +        }
1104 +        public <T> T[] toArray(T[] a) {
1105 +            Collection<Map.Entry<K,V>> c = new ArrayList<Map.Entry<K,V>>(size());
1106 +            for (Iterator<Map.Entry<K,V>> i = iterator(); i.hasNext(); )
1107 +                c.add(new SimpleEntry<K,V>(i.next()));
1108 +            return c.toArray(a);
1109 +        }
1110 +
1111 +    }
1112 +
1113 +    /**
1114 +     * This duplicates java.util.AbstractMap.SimpleEntry until this class
1115 +     * is made accessible.
1116 +     */
1117 +    static class SimpleEntry<K,V> implements Entry<K,V> {
1118 +        K key;
1119 +        V value;
1120 +
1121 +        public SimpleEntry(K key, V value) {
1122 +            this.key   = key;
1123 +            this.value = value;
1124 +        }
1125 +
1126 +        public SimpleEntry(Entry<K,V> e) {
1127 +            this.key   = e.getKey();
1128 +            this.value = e.getValue();
1129 +        }
1130 +
1131 +        public K getKey() {
1132 +            return key;
1133 +        }
1134 +
1135 +        public V getValue() {
1136 +            return value;
1137 +        }
1138 +
1139 +        public V setValue(V value) {
1140 +            V oldValue = this.value;
1141 +            this.value = value;
1142 +            return oldValue;
1143 +        }
1144 +
1145 +        public boolean equals(Object o) {
1146 +            if (!(o instanceof Map.Entry))
1147 +                return false;
1148 +            Map.Entry e = (Map.Entry)o;
1149 +            return eq(key, e.getKey()) && eq(value, e.getValue());
1150 +        }
1151 +
1152 +        public int hashCode() {
1153 +            return ((key   == null)   ? 0 :   key.hashCode()) ^
1154 +                   ((value == null)   ? 0 : value.hashCode());
1155 +        }
1156 +
1157 +        public String toString() {
1158 +            return key + "=" + value;
1159 +        }
1160 +
1161 +        private static boolean eq(Object o1, Object o2) {
1162 +            return (o1 == null ? o2 == null : o1.equals(o2));
1163 +        }
1164      }
1165  
1166      /* ---------------- Serialization Support -------------- */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines