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.78 by jsr166, Fri Jun 24 20:44:49 2005 UTC vs.
Revision 1.79 by dl, Fri Aug 19 13:05:11 2005 UTC

# Line 1050 | Line 1050 | public class ConcurrentHashMap<K, V> ext
1050  
1051      /* ---------------- Iterator Support -------------- */
1052  
1053 <    abstract class HashIterator {
1053 >    class HashIterator {
1054          int nextSegmentIndex;
1055          int nextTableIndex;
1056          HashEntry<K,V>[] currentTable;
# Line 1117 | Line 1117 | public class ConcurrentHashMap<K, V> ext
1117      }
1118  
1119  
1120
1120      /**
1121 <     * Entry iterator. Exported Entry objects must write-through
1122 <     * changes in setValue, even if the nodes have been cloned. So we
1123 <     * cannot return internal HashEntry objects. Instead, the iterator
1124 <     * itself acts as a forwarding pseudo-entry.
1125 <     */
1126 <    final class EntryIterator extends HashIterator implements Map.Entry<K,V>, Iterator<Entry<K,V>> {
1127 <        public Map.Entry<K,V> next() {
1128 <            nextEntry();
1129 <            return this;
1130 <        }
1131 <
1132 <        public K getKey() {
1133 <            if (lastReturned == null)
1134 <                throw new IllegalStateException("Entry was removed");
1135 <            return lastReturned.key;
1136 <        }
1137 <
1138 <        public V getValue() {
1139 <            if (lastReturned == null)
1140 <                throw new IllegalStateException("Entry was removed");
1141 <            return ConcurrentHashMap.this.get(lastReturned.key);
1142 <        }
1143 <
1144 <        public V setValue(V value) {
1146 <            if (lastReturned == null)
1147 <                throw new IllegalStateException("Entry was removed");
1148 <            return ConcurrentHashMap.this.put(lastReturned.key, value);
1149 <        }
1150 <
1151 <        public boolean equals(Object o) {
1152 <            // If not acting as entry, just use default.
1153 <            if (lastReturned == null)
1154 <                return super.equals(o);
1155 <            if (!(o instanceof Map.Entry))
1156 <                return false;
1157 <            Map.Entry<?,?> e = (Map.Entry<?,?>)o;
1158 <            return eq(getKey(), e.getKey()) && eq(getValue(), e.getValue());
1159 <        }
1160 <
1161 <        public int hashCode() {
1162 <            // If not acting as entry, just use default.
1163 <            if (lastReturned == null)
1164 <                return super.hashCode();
1165 <
1166 <            Object k = getKey();
1167 <            Object v = getValue();
1168 <            return ((k == null) ? 0 : k.hashCode()) ^
1169 <                   ((v == null) ? 0 : v.hashCode());
1170 <        }
1171 <
1172 <        public String toString() {
1173 <            // If not acting as entry, just use default.
1174 <            if (lastReturned == null)
1175 <                return super.toString();
1176 <            else
1177 <                return getKey() + "=" + getValue();
1121 >     * Custom Entry class used by EntryIterator.next(), that relays
1122 >     * setValue changes to the underlying map.
1123 >     */
1124 >    static final class WriteThroughEntry<K,V> extends AbstractMap.SimpleEntry<K,V> {
1125 >        private final ConcurrentHashMap<K,V> map;
1126 >        WriteThroughEntry(ConcurrentHashMap map, K k, V v) {
1127 >            super(k,v);
1128 >            this.map = map;
1129 >        }
1130 >
1131 >        /**
1132 >         * Set our entry's value and write through to the map. The
1133 >         * value to return is somewhat arbitrary here. Since a
1134 >         * WriteThroughEntry does not necessarily track asynchronous
1135 >         * changes, the most recent "previous" value could be
1136 >         * different than what we return (or could even have been
1137 >         * removed in which case the put will re-establish). We do not
1138 >         * and cannot guarantee more.
1139 >         */
1140 >        public V setValue(V value) {
1141 >            if (value == null) throw new NullPointerException();
1142 >            V v = super.setValue(value);
1143 >            map.put(getKey(), value);
1144 >            return v;
1145          }
1146 +    }
1147  
1148 <        boolean eq(Object o1, Object o2) {
1149 <            return (o1 == null ? o2 == null : o1.equals(o2));
1148 >    final class EntryIterator extends HashIterator implements Iterator<Entry<K,V>> {
1149 >        public Map.Entry<K,V> next() {
1150 >            HashEntry<K,V> e = super.nextEntry();
1151 >            return new WriteThroughEntry<K,V>(ConcurrentHashMap.this,
1152 >                                              e.key, e.value);
1153          }
1183
1154      }
1155  
1156      final class KeySet extends AbstractSet<K> {
# Line 1264 | Line 1234 | public class ConcurrentHashMap<K, V> ext
1234              ConcurrentHashMap.this.clear();
1235          }
1236          public Object[] toArray() {
1267            // Since we don't ordinarily have distinct Entry objects, we
1268            // must pack elements using exportable SimpleEntry
1237              Collection<Map.Entry<K,V>> c = new ArrayList<Map.Entry<K,V>>(size());
1238              for (Iterator<Map.Entry<K,V>> i = iterator(); i.hasNext(); )
1239 <                c.add(new AbstractMap.SimpleEntry<K,V>(i.next()));
1239 >                c.add(i.next());
1240              return c.toArray();
1241          }
1242          public <T> T[] toArray(T[] a) {
1243              Collection<Map.Entry<K,V>> c = new ArrayList<Map.Entry<K,V>>(size());
1244              for (Iterator<Map.Entry<K,V>> i = iterator(); i.hasNext(); )
1245 <                c.add(new AbstractMap.SimpleEntry<K,V>(i.next()));
1245 >                c.add(i.next());
1246              return c.toArray(a);
1247          }
1280
1248      }
1249  
1250      /* ---------------- Serialization Support -------------- */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines