1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package io.netty.util.internal.chmv8;
24
25 import io.netty.util.internal.IntegerHolder;
26 import io.netty.util.internal.InternalThreadLocalMap;
27
28 import java.io.ObjectStreamField;
29 import java.io.Serializable;
30 import java.lang.reflect.ParameterizedType;
31 import java.lang.reflect.Type;
32 import java.util.Arrays;
33 import java.util.Collection;
34 import java.util.ConcurrentModificationException;
35 import java.util.Enumeration;
36 import java.util.HashMap;
37 import java.util.Hashtable;
38 import java.util.Iterator;
39 import java.util.Map;
40 import java.util.NoSuchElementException;
41 import java.util.Set;
42 import java.util.concurrent.ConcurrentMap;
43 import java.util.concurrent.atomic.AtomicInteger;
44 import java.util.concurrent.atomic.AtomicReference;
45 import java.util.concurrent.locks.LockSupport;
46 import java.util.concurrent.locks.ReentrantLock;
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237 @SuppressWarnings("all")
238 public class ConcurrentHashMapV8<K,V>
239 implements ConcurrentMap<K,V>, Serializable {
240 private static final long serialVersionUID = 7249069246763182397L;
241
242
243
244
245
246
247 public static interface ConcurrentHashMapSpliterator<T> {
248
249
250
251
252
253
254 ConcurrentHashMapSpliterator<T> trySplit();
255
256
257
258
259 long estimateSize();
260
261
262 void forEachRemaining(Action<? super T> action);
263
264 boolean tryAdvance(Action<? super T> action);
265 }
266
267
268
269 public interface Action<A> { void apply(A a); }
270
271 public interface BiAction<A,B> { void apply(A a, B b); }
272
273 public interface Fun<A,T> { T apply(A a); }
274
275 public interface BiFun<A,B,T> { T apply(A a, B b); }
276
277 public interface ObjectToDouble<A> { double apply(A a); }
278
279 public interface ObjectToLong<A> { long apply(A a); }
280
281 public interface ObjectToInt<A> {int apply(A a); }
282
283 public interface ObjectByObjectToDouble<A,B> { double apply(A a, B b); }
284
285 public interface ObjectByObjectToLong<A,B> { long apply(A a, B b); }
286
287 public interface ObjectByObjectToInt<A,B> {int apply(A a, B b); }
288
289 public interface DoubleByDoubleToDouble { double apply(double a, double b); }
290
291 public interface LongByLongToLong { long apply(long a, long b); }
292
293 public interface IntByIntToInt { int apply(int a, int b); }
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522 private static final int MAXIMUM_CAPACITY = 1 << 30;
523
524
525
526
527
528 private static final int DEFAULT_CAPACITY = 16;
529
530
531
532
533
534 static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
535
536
537
538
539
540 private static final int DEFAULT_CONCURRENCY_LEVEL = 16;
541
542
543
544
545
546
547
548
549 private static final float LOAD_FACTOR = 0.75f;
550
551
552
553
554
555
556
557
558
559 static final int TREEIFY_THRESHOLD = 8;
560
561
562
563
564
565
566 static final int UNTREEIFY_THRESHOLD = 6;
567
568
569
570
571
572
573
574 static final int MIN_TREEIFY_CAPACITY = 64;
575
576
577
578
579
580
581
582
583 private static final int MIN_TRANSFER_STRIDE = 16;
584
585
586
587
588 static final int MOVED = -1;
589 static final int TREEBIN = -2;
590 static final int RESERVED = -3;
591 static final int HASH_BITS = 0x7fffffff;
592
593
594 static final int NCPU = Runtime.getRuntime().availableProcessors();
595
596
597 private static final ObjectStreamField[] serialPersistentFields = {
598 new ObjectStreamField("segments", Segment[].class),
599 new ObjectStreamField("segmentMask", Integer.TYPE),
600 new ObjectStreamField("segmentShift", Integer.TYPE)
601 };
602
603
604
605
606
607
608
609
610
611
612
613 static class Node<K,V> implements Map.Entry<K,V> {
614 final int hash;
615 final K key;
616 volatile V val;
617 volatile Node<K,V> next;
618
619 Node(int hash, K key, V val, Node<K,V> next) {
620 this.hash = hash;
621 this.key = key;
622 this.val = val;
623 this.next = next;
624 }
625
626 public final K getKey() { return key; }
627 public final V getValue() { return val; }
628 public final int hashCode() { return key.hashCode() ^ val.hashCode(); }
629 public final String toString(){ return key + "=" + val; }
630 public final V setValue(V value) {
631 throw new UnsupportedOperationException();
632 }
633
634 public final boolean equals(Object o) {
635 Object k, v, u; Map.Entry<?,?> e;
636 return ((o instanceof Map.Entry) &&
637 (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
638 (v = e.getValue()) != null &&
639 (k == key || k.equals(key)) &&
640 (v == (u = val) || v.equals(u)));
641 }
642
643
644
645
646 Node<K,V> find(int h, Object k) {
647 Node<K,V> e = this;
648 if (k != null) {
649 do {
650 K ek;
651 if (e.hash == h &&
652 ((ek = e.key) == k || (ek != null && k.equals(ek))))
653 return e;
654 } while ((e = e.next) != null);
655 }
656 return null;
657 }
658 }
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678 static final int spread(int h) {
679 return (h ^ (h >>> 16)) & HASH_BITS;
680 }
681
682
683
684
685
686 private static final int tableSizeFor(int c) {
687 int n = c - 1;
688 n |= n >>> 1;
689 n |= n >>> 2;
690 n |= n >>> 4;
691 n |= n >>> 8;
692 n |= n >>> 16;
693 return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
694 }
695
696
697
698
699
700 static Class<?> comparableClassFor(Object x) {
701 if (x instanceof Comparable) {
702 Class<?> c; Type[] ts, as; Type t; ParameterizedType p;
703 if ((c = x.getClass()) == String.class)
704 return c;
705 if ((ts = c.getGenericInterfaces()) != null) {
706 for (int i = 0; i < ts.length; ++i) {
707 if (((t = ts[i]) instanceof ParameterizedType) &&
708 ((p = (ParameterizedType)t).getRawType() ==
709 Comparable.class) &&
710 (as = p.getActualTypeArguments()) != null &&
711 as.length == 1 && as[0] == c)
712 return c;
713 }
714 }
715 }
716 return null;
717 }
718
719
720
721
722
723 @SuppressWarnings({"rawtypes","unchecked"})
724 static int compareComparables(Class<?> kc, Object k, Object x) {
725 return (x == null || x.getClass() != kc ? 0 :
726 ((Comparable)k).compareTo(x));
727 }
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747 @SuppressWarnings("unchecked")
748 static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) {
749 return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);
750 }
751
752 static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i,
753 Node<K,V> c, Node<K,V> v) {
754 return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v);
755 }
756
757 static final <K,V> void setTabAt(Node<K,V>[] tab, int i, Node<K,V> v) {
758 U.putObjectVolatile(tab, ((long)i << ASHIFT) + ABASE, v);
759 }
760
761
762
763
764
765
766
767 transient volatile Node<K,V>[] table;
768
769
770
771
772 private transient volatile Node<K,V>[] nextTable;
773
774
775
776
777
778
779 private transient volatile long baseCount;
780
781
782
783
784
785
786
787
788
789 private transient volatile int sizeCtl;
790
791
792
793
794 private transient volatile int transferIndex;
795
796
797
798
799 private transient volatile int transferOrigin;
800
801
802
803
804 private transient volatile int cellsBusy;
805
806
807
808
809 private transient volatile CounterCell[] counterCells;
810
811
812 private transient KeySetView<K,V> keySet;
813 private transient ValuesView<K,V> values;
814 private transient EntrySetView<K,V> entrySet;
815
816
817
818
819
820
821
822 public ConcurrentHashMapV8() {
823 }
824
825
826
827
828
829
830
831
832
833
834
835 public ConcurrentHashMapV8(int initialCapacity) {
836 if (initialCapacity < 0)
837 throw new IllegalArgumentException();
838 int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ?
839 MAXIMUM_CAPACITY :
840 tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1));
841 this.sizeCtl = cap;
842 }
843
844
845
846
847
848
849 public ConcurrentHashMapV8(Map<? extends K, ? extends V> m) {
850 this.sizeCtl = DEFAULT_CAPACITY;
851 putAll(m);
852 }
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869 public ConcurrentHashMapV8(int initialCapacity, float loadFactor) {
870 this(initialCapacity, loadFactor, 1);
871 }
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891 public ConcurrentHashMapV8(int initialCapacity,
892 float loadFactor, int concurrencyLevel) {
893 if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0)
894 throw new IllegalArgumentException();
895 if (initialCapacity < concurrencyLevel)
896 initialCapacity = concurrencyLevel;
897 long size = (long)(1.0 + (long)initialCapacity / loadFactor);
898 int cap = (size >= (long)MAXIMUM_CAPACITY) ?
899 MAXIMUM_CAPACITY : tableSizeFor((int)size);
900 this.sizeCtl = cap;
901 }
902
903
904
905
906
907
908 public int size() {
909 long n = sumCount();
910 return ((n < 0L) ? 0 :
911 (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE :
912 (int)n);
913 }
914
915
916
917
918 public boolean isEmpty() {
919 return sumCount() <= 0L;
920 }
921
922
923
924
925
926
927
928
929
930
931
932
933 public V get(Object key) {
934 Node<K,V>[] tab; Node<K,V> e, p; int n, eh; K ek;
935 int h = spread(key.hashCode());
936 if ((tab = table) != null && (n = tab.length) > 0 &&
937 (e = tabAt(tab, (n - 1) & h)) != null) {
938 if ((eh = e.hash) == h) {
939 if ((ek = e.key) == key || (ek != null && key.equals(ek)))
940 return e.val;
941 }
942 else if (eh < 0)
943 return (p = e.find(h, key)) != null ? p.val : null;
944 while ((e = e.next) != null) {
945 if (e.hash == h &&
946 ((ek = e.key) == key || (ek != null && key.equals(ek))))
947 return e.val;
948 }
949 }
950 return null;
951 }
952
953
954
955
956
957
958
959
960
961
962 public boolean containsKey(Object key) {
963 return get(key) != null;
964 }
965
966
967
968
969
970
971
972
973
974
975
976 public boolean containsValue(Object value) {
977 if (value == null)
978 throw new NullPointerException();
979 Node<K,V>[] t;
980 if ((t = table) != null) {
981 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
982 for (Node<K,V> p; (p = it.advance()) != null; ) {
983 V v;
984 if ((v = p.val) == value || (v != null && value.equals(v)))
985 return true;
986 }
987 }
988 return false;
989 }
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004 public V put(K key, V value) {
1005 return putVal(key, value, false);
1006 }
1007
1008
1009 final V putVal(K key, V value, boolean onlyIfAbsent) {
1010 if (key == null || value == null) throw new NullPointerException();
1011 int hash = spread(key.hashCode());
1012 int binCount = 0;
1013 for (Node<K,V>[] tab = table;;) {
1014 Node<K,V> f; int n, i, fh;
1015 if (tab == null || (n = tab.length) == 0)
1016 tab = initTable();
1017 else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
1018 if (casTabAt(tab, i, null,
1019 new Node<K,V>(hash, key, value, null)))
1020 break;
1021 }
1022 else if ((fh = f.hash) == MOVED)
1023 tab = helpTransfer(tab, f);
1024 else {
1025 V oldVal = null;
1026 synchronized (f) {
1027 if (tabAt(tab, i) == f) {
1028 if (fh >= 0) {
1029 binCount = 1;
1030 for (Node<K,V> e = f;; ++binCount) {
1031 K ek;
1032 if (e.hash == hash &&
1033 ((ek = e.key) == key ||
1034 (ek != null && key.equals(ek)))) {
1035 oldVal = e.val;
1036 if (!onlyIfAbsent)
1037 e.val = value;
1038 break;
1039 }
1040 Node<K,V> pred = e;
1041 if ((e = e.next) == null) {
1042 pred.next = new Node<K,V>(hash, key,
1043 value, null);
1044 break;
1045 }
1046 }
1047 }
1048 else if (f instanceof TreeBin) {
1049 Node<K,V> p;
1050 binCount = 2;
1051 if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
1052 value)) != null) {
1053 oldVal = p.val;
1054 if (!onlyIfAbsent)
1055 p.val = value;
1056 }
1057 }
1058 }
1059 }
1060 if (binCount != 0) {
1061 if (binCount >= TREEIFY_THRESHOLD)
1062 treeifyBin(tab, i);
1063 if (oldVal != null)
1064 return oldVal;
1065 break;
1066 }
1067 }
1068 }
1069 addCount(1L, binCount);
1070 return null;
1071 }
1072
1073
1074
1075
1076
1077
1078
1079
1080 public void putAll(Map<? extends K, ? extends V> m) {
1081 tryPresize(m.size());
1082 for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
1083 putVal(e.getKey(), e.getValue(), false);
1084 }
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095 public V remove(Object key) {
1096 return replaceNode(key, null, null);
1097 }
1098
1099
1100
1101
1102
1103
1104 final V replaceNode(Object key, V value, Object cv) {
1105 int hash = spread(key.hashCode());
1106 for (Node<K,V>[] tab = table;;) {
1107 Node<K,V> f; int n, i, fh;
1108 if (tab == null || (n = tab.length) == 0 ||
1109 (f = tabAt(tab, i = (n - 1) & hash)) == null)
1110 break;
1111 else if ((fh = f.hash) == MOVED)
1112 tab = helpTransfer(tab, f);
1113 else {
1114 V oldVal = null;
1115 boolean validated = false;
1116 synchronized (f) {
1117 if (tabAt(tab, i) == f) {
1118 if (fh >= 0) {
1119 validated = true;
1120 for (Node<K,V> e = f, pred = null;;) {
1121 K ek;
1122 if (e.hash == hash &&
1123 ((ek = e.key) == key ||
1124 (ek != null && key.equals(ek)))) {
1125 V ev = e.val;
1126 if (cv == null || cv == ev ||
1127 (ev != null && cv.equals(ev))) {
1128 oldVal = ev;
1129 if (value != null)
1130 e.val = value;
1131 else if (pred != null)
1132 pred.next = e.next;
1133 else
1134 setTabAt(tab, i, e.next);
1135 }
1136 break;
1137 }
1138 pred = e;
1139 if ((e = e.next) == null)
1140 break;
1141 }
1142 }
1143 else if (f instanceof TreeBin) {
1144 validated = true;
1145 TreeBin<K,V> t = (TreeBin<K,V>)f;
1146 TreeNode<K,V> r, p;
1147 if ((r = t.root) != null &&
1148 (p = r.findTreeNode(hash, key, null)) != null) {
1149 V pv = p.val;
1150 if (cv == null || cv == pv ||
1151 (pv != null && cv.equals(pv))) {
1152 oldVal = pv;
1153 if (value != null)
1154 p.val = value;
1155 else if (t.removeTreeNode(p))
1156 setTabAt(tab, i, untreeify(t.first));
1157 }
1158 }
1159 }
1160 }
1161 }
1162 if (validated) {
1163 if (oldVal != null) {
1164 if (value == null)
1165 addCount(-1L, -1);
1166 return oldVal;
1167 }
1168 break;
1169 }
1170 }
1171 }
1172 return null;
1173 }
1174
1175
1176
1177
1178 public void clear() {
1179 long delta = 0L;
1180 int i = 0;
1181 Node<K,V>[] tab = table;
1182 while (tab != null && i < tab.length) {
1183 int fh;
1184 Node<K,V> f = tabAt(tab, i);
1185 if (f == null)
1186 ++i;
1187 else if ((fh = f.hash) == MOVED) {
1188 tab = helpTransfer(tab, f);
1189 i = 0;
1190 }
1191 else {
1192 synchronized (f) {
1193 if (tabAt(tab, i) == f) {
1194 Node<K,V> p = (fh >= 0 ? f :
1195 (f instanceof TreeBin) ?
1196 ((TreeBin<K,V>)f).first : null);
1197 while (p != null) {
1198 --delta;
1199 p = p.next;
1200 }
1201 setTabAt(tab, i++, null);
1202 }
1203 }
1204 }
1205 }
1206 if (delta != 0L)
1207 addCount(delta, -1);
1208 }
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228 public KeySetView<K,V> keySet() {
1229 KeySetView<K,V> ks;
1230 return (ks = keySet) != null ? ks : (keySet = new KeySetView<K,V>(this, null));
1231 }
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251 public Collection<V> values() {
1252 ValuesView<K,V> vs;
1253 return (vs = values) != null ? vs : (values = new ValuesView<K,V>(this));
1254 }
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273 public Set<Map.Entry<K,V>> entrySet() {
1274 EntrySetView<K,V> es;
1275 return (es = entrySet) != null ? es : (entrySet = new EntrySetView<K,V>(this));
1276 }
1277
1278
1279
1280
1281
1282
1283
1284
1285 public int hashCode() {
1286 int h = 0;
1287 Node<K,V>[] t;
1288 if ((t = table) != null) {
1289 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
1290 for (Node<K,V> p; (p = it.advance()) != null; )
1291 h += p.key.hashCode() ^ p.val.hashCode();
1292 }
1293 return h;
1294 }
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307 public String toString() {
1308 Node<K,V>[] t;
1309 int f = (t = table) == null ? 0 : t.length;
1310 Traverser<K,V> it = new Traverser<K,V>(t, f, 0, f);
1311 StringBuilder sb = new StringBuilder();
1312 sb.append('{');
1313 Node<K,V> p;
1314 if ((p = it.advance()) != null) {
1315 for (;;) {
1316 K k = p.key;
1317 V v = p.val;
1318 sb.append(k == this ? "(this Map)" : k);
1319 sb.append('=');
1320 sb.append(v == this ? "(this Map)" : v);
1321 if ((p = it.advance()) == null)
1322 break;
1323 sb.append(',').append(' ');
1324 }
1325 }
1326 return sb.append('}').toString();
1327 }
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339 public boolean equals(Object o) {
1340 if (o != this) {
1341 if (!(o instanceof Map))
1342 return false;
1343 Map<?,?> m = (Map<?,?>) o;
1344 Node<K,V>[] t;
1345 int f = (t = table) == null ? 0 : t.length;
1346 Traverser<K,V> it = new Traverser<K,V>(t, f, 0, f);
1347 for (Node<K,V> p; (p = it.advance()) != null; ) {
1348 V val = p.val;
1349 Object v = m.get(p.key);
1350 if (v == null || (v != val && !v.equals(val)))
1351 return false;
1352 }
1353 for (Map.Entry<?,?> e : m.entrySet()) {
1354 Object mk, mv, v;
1355 if ((mk = e.getKey()) == null ||
1356 (mv = e.getValue()) == null ||
1357 (v = get(mk)) == null ||
1358 (mv != v && !mv.equals(v)))
1359 return false;
1360 }
1361 }
1362 return true;
1363 }
1364
1365
1366
1367
1368
1369 static class Segment<K,V> extends ReentrantLock implements Serializable {
1370 private static final long serialVersionUID = 2249069246763182397L;
1371 final float loadFactor;
1372 Segment(float lf) { this.loadFactor = lf; }
1373 }
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384 private void writeObject(java.io.ObjectOutputStream s)
1385 throws java.io.IOException {
1386
1387
1388 int sshift = 0;
1389 int ssize = 1;
1390 while (ssize < DEFAULT_CONCURRENCY_LEVEL) {
1391 ++sshift;
1392 ssize <<= 1;
1393 }
1394 int segmentShift = 32 - sshift;
1395 int segmentMask = ssize - 1;
1396 @SuppressWarnings("unchecked") Segment<K,V>[] segments = (Segment<K,V>[])
1397 new Segment<?,?>[DEFAULT_CONCURRENCY_LEVEL];
1398 for (int i = 0; i < segments.length; ++i)
1399 segments[i] = new Segment<K,V>(LOAD_FACTOR);
1400 s.putFields().put("segments", segments);
1401 s.putFields().put("segmentShift", segmentShift);
1402 s.putFields().put("segmentMask", segmentMask);
1403 s.writeFields();
1404
1405 Node<K,V>[] t;
1406 if ((t = table) != null) {
1407 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
1408 for (Node<K,V> p; (p = it.advance()) != null; ) {
1409 s.writeObject(p.key);
1410 s.writeObject(p.val);
1411 }
1412 }
1413 s.writeObject(null);
1414 s.writeObject(null);
1415 segments = null;
1416 }
1417
1418
1419
1420
1421
1422 private void readObject(java.io.ObjectInputStream s)
1423 throws java.io.IOException, ClassNotFoundException {
1424
1425
1426
1427
1428
1429
1430
1431 sizeCtl = -1;
1432 s.defaultReadObject();
1433 long size = 0L;
1434 Node<K,V> p = null;
1435 for (;;) {
1436 @SuppressWarnings("unchecked") K k = (K) s.readObject();
1437 @SuppressWarnings("unchecked") V v = (V) s.readObject();
1438 if (k != null && v != null) {
1439 p = new Node<K,V>(spread(k.hashCode()), k, v, p);
1440 ++size;
1441 }
1442 else
1443 break;
1444 }
1445 if (size == 0L)
1446 sizeCtl = 0;
1447 else {
1448 int n;
1449 if (size >= (long)(MAXIMUM_CAPACITY >>> 1))
1450 n = MAXIMUM_CAPACITY;
1451 else {
1452 int sz = (int)size;
1453 n = tableSizeFor(sz + (sz >>> 1) + 1);
1454 }
1455 @SuppressWarnings({"rawtypes","unchecked"})
1456 Node<K,V>[] tab = (Node<K,V>[])new Node[n];
1457 int mask = n - 1;
1458 long added = 0L;
1459 while (p != null) {
1460 boolean insertAtFront;
1461 Node<K,V> next = p.next, first;
1462 int h = p.hash, j = h & mask;
1463 if ((first = tabAt(tab, j)) == null)
1464 insertAtFront = true;
1465 else {
1466 K k = p.key;
1467 if (first.hash < 0) {
1468 TreeBin<K,V> t = (TreeBin<K,V>)first;
1469 if (t.putTreeVal(h, k, p.val) == null)
1470 ++added;
1471 insertAtFront = false;
1472 }
1473 else {
1474 int binCount = 0;
1475 insertAtFront = true;
1476 Node<K,V> q; K qk;
1477 for (q = first; q != null; q = q.next) {
1478 if (q.hash == h &&
1479 ((qk = q.key) == k ||
1480 (qk != null && k.equals(qk)))) {
1481 insertAtFront = false;
1482 break;
1483 }
1484 ++binCount;
1485 }
1486 if (insertAtFront && binCount >= TREEIFY_THRESHOLD) {
1487 insertAtFront = false;
1488 ++added;
1489 p.next = first;
1490 TreeNode<K,V> hd = null, tl = null;
1491 for (q = p; q != null; q = q.next) {
1492 TreeNode<K,V> t = new TreeNode<K,V>
1493 (q.hash, q.key, q.val, null, null);
1494 if ((t.prev = tl) == null)
1495 hd = t;
1496 else
1497 tl.next = t;
1498 tl = t;
1499 }
1500 setTabAt(tab, j, new TreeBin<K,V>(hd));
1501 }
1502 }
1503 }
1504 if (insertAtFront) {
1505 ++added;
1506 p.next = first;
1507 setTabAt(tab, j, p);
1508 }
1509 p = next;
1510 }
1511 table = tab;
1512 sizeCtl = n - (n >>> 2);
1513 baseCount = added;
1514 }
1515 }
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526 public V putIfAbsent(K key, V value) {
1527 return putVal(key, value, true);
1528 }
1529
1530
1531
1532
1533
1534
1535 public boolean remove(Object key, Object value) {
1536 if (key == null)
1537 throw new NullPointerException();
1538 return value != null && replaceNode(key, null, value) != null;
1539 }
1540
1541
1542
1543
1544
1545
1546 public boolean replace(K key, V oldValue, V newValue) {
1547 if (key == null || oldValue == null || newValue == null)
1548 throw new NullPointerException();
1549 return replaceNode(key, newValue, oldValue) != null;
1550 }
1551
1552
1553
1554
1555
1556
1557
1558
1559 public V replace(K key, V value) {
1560 if (key == null || value == null)
1561 throw new NullPointerException();
1562 return replaceNode(key, value, null);
1563 }
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578 public V getOrDefault(Object key, V defaultValue) {
1579 V v;
1580 return (v = get(key)) == null ? defaultValue : v;
1581 }
1582
1583 public void forEach(BiAction<? super K, ? super V> action) {
1584 if (action == null) throw new NullPointerException();
1585 Node<K,V>[] t;
1586 if ((t = table) != null) {
1587 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
1588 for (Node<K,V> p; (p = it.advance()) != null; ) {
1589 action.apply(p.key, p.val);
1590 }
1591 }
1592 }
1593
1594 public void replaceAll(BiFun<? super K, ? super V, ? extends V> function) {
1595 if (function == null) throw new NullPointerException();
1596 Node<K,V>[] t;
1597 if ((t = table) != null) {
1598 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
1599 for (Node<K,V> p; (p = it.advance()) != null; ) {
1600 V oldValue = p.val;
1601 for (K key = p.key;;) {
1602 V newValue = function.apply(key, oldValue);
1603 if (newValue == null)
1604 throw new NullPointerException();
1605 if (replaceNode(key, newValue, oldValue) != null ||
1606 (oldValue = get(key)) == null)
1607 break;
1608 }
1609 }
1610 }
1611 }
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635 public V computeIfAbsent(K key, Fun<? super K, ? extends V> mappingFunction) {
1636 if (key == null || mappingFunction == null)
1637 throw new NullPointerException();
1638 int h = spread(key.hashCode());
1639 V val = null;
1640 int binCount = 0;
1641 for (Node<K,V>[] tab = table;;) {
1642 Node<K,V> f; int n, i, fh;
1643 if (tab == null || (n = tab.length) == 0)
1644 tab = initTable();
1645 else if ((f = tabAt(tab, i = (n - 1) & h)) == null) {
1646 Node<K,V> r = new ReservationNode<K,V>();
1647 synchronized (r) {
1648 if (casTabAt(tab, i, null, r)) {
1649 binCount = 1;
1650 Node<K,V> node = null;
1651 try {
1652 if ((val = mappingFunction.apply(key)) != null)
1653 node = new Node<K,V>(h, key, val, null);
1654 } finally {
1655 setTabAt(tab, i, node);
1656 }
1657 }
1658 }
1659 if (binCount != 0)
1660 break;
1661 }
1662 else if ((fh = f.hash) == MOVED)
1663 tab = helpTransfer(tab, f);
1664 else {
1665 boolean added = false;
1666 synchronized (f) {
1667 if (tabAt(tab, i) == f) {
1668 if (fh >= 0) {
1669 binCount = 1;
1670 for (Node<K,V> e = f;; ++binCount) {
1671 K ek; V ev;
1672 if (e.hash == h &&
1673 ((ek = e.key) == key ||
1674 (ek != null && key.equals(ek)))) {
1675 val = e.val;
1676 break;
1677 }
1678 Node<K,V> pred = e;
1679 if ((e = e.next) == null) {
1680 if ((val = mappingFunction.apply(key)) != null) {
1681 added = true;
1682 pred.next = new Node<K,V>(h, key, val, null);
1683 }
1684 break;
1685 }
1686 }
1687 }
1688 else if (f instanceof TreeBin) {
1689 binCount = 2;
1690 TreeBin<K,V> t = (TreeBin<K,V>)f;
1691 TreeNode<K,V> r, p;
1692 if ((r = t.root) != null &&
1693 (p = r.findTreeNode(h, key, null)) != null)
1694 val = p.val;
1695 else if ((val = mappingFunction.apply(key)) != null) {
1696 added = true;
1697 t.putTreeVal(h, key, val);
1698 }
1699 }
1700 }
1701 }
1702 if (binCount != 0) {
1703 if (binCount >= TREEIFY_THRESHOLD)
1704 treeifyBin(tab, i);
1705 if (!added)
1706 return val;
1707 break;
1708 }
1709 }
1710 }
1711 if (val != null)
1712 addCount(1L, binCount);
1713 return val;
1714 }
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736 public V computeIfPresent(K key, BiFun<? super K, ? super V, ? extends V> remappingFunction) {
1737 if (key == null || remappingFunction == null)
1738 throw new NullPointerException();
1739 int h = spread(key.hashCode());
1740 V val = null;
1741 int delta = 0;
1742 int binCount = 0;
1743 for (Node<K,V>[] tab = table;;) {
1744 Node<K,V> f; int n, i, fh;
1745 if (tab == null || (n = tab.length) == 0)
1746 tab = initTable();
1747 else if ((f = tabAt(tab, i = (n - 1) & h)) == null)
1748 break;
1749 else if ((fh = f.hash) == MOVED)
1750 tab = helpTransfer(tab, f);
1751 else {
1752 synchronized (f) {
1753 if (tabAt(tab, i) == f) {
1754 if (fh >= 0) {
1755 binCount = 1;
1756 for (Node<K,V> e = f, pred = null;; ++binCount) {
1757 K ek;
1758 if (e.hash == h &&
1759 ((ek = e.key) == key ||
1760 (ek != null && key.equals(ek)))) {
1761 val = remappingFunction.apply(key, e.val);
1762 if (val != null)
1763 e.val = val;
1764 else {
1765 delta = -1;
1766 Node<K,V> en = e.next;
1767 if (pred != null)
1768 pred.next = en;
1769 else
1770 setTabAt(tab, i, en);
1771 }
1772 break;
1773 }
1774 pred = e;
1775 if ((e = e.next) == null)
1776 break;
1777 }
1778 }
1779 else if (f instanceof TreeBin) {
1780 binCount = 2;
1781 TreeBin<K,V> t = (TreeBin<K,V>)f;
1782 TreeNode<K,V> r, p;
1783 if ((r = t.root) != null &&
1784 (p = r.findTreeNode(h, key, null)) != null) {
1785 val = remappingFunction.apply(key, p.val);
1786 if (val != null)
1787 p.val = val;
1788 else {
1789 delta = -1;
1790 if (t.removeTreeNode(p))
1791 setTabAt(tab, i, untreeify(t.first));
1792 }
1793 }
1794 }
1795 }
1796 }
1797 if (binCount != 0)
1798 break;
1799 }
1800 }
1801 if (delta != 0)
1802 addCount((long)delta, binCount);
1803 return val;
1804 }
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826 public V compute(K key,
1827 BiFun<? super K, ? super V, ? extends V> remappingFunction) {
1828 if (key == null || remappingFunction == null)
1829 throw new NullPointerException();
1830 int h = spread(key.hashCode());
1831 V val = null;
1832 int delta = 0;
1833 int binCount = 0;
1834 for (Node<K,V>[] tab = table;;) {
1835 Node<K,V> f; int n, i, fh;
1836 if (tab == null || (n = tab.length) == 0)
1837 tab = initTable();
1838 else if ((f = tabAt(tab, i = (n - 1) & h)) == null) {
1839 Node<K,V> r = new ReservationNode<K,V>();
1840 synchronized (r) {
1841 if (casTabAt(tab, i, null, r)) {
1842 binCount = 1;
1843 Node<K,V> node = null;
1844 try {
1845 if ((val = remappingFunction.apply(key, null)) != null) {
1846 delta = 1;
1847 node = new Node<K,V>(h, key, val, null);
1848 }
1849 } finally {
1850 setTabAt(tab, i, node);
1851 }
1852 }
1853 }
1854 if (binCount != 0)
1855 break;
1856 }
1857 else if ((fh = f.hash) == MOVED)
1858 tab = helpTransfer(tab, f);
1859 else {
1860 synchronized (f) {
1861 if (tabAt(tab, i) == f) {
1862 if (fh >= 0) {
1863 binCount = 1;
1864 for (Node<K,V> e = f, pred = null;; ++binCount) {
1865 K ek;
1866 if (e.hash == h &&
1867 ((ek = e.key) == key ||
1868 (ek != null && key.equals(ek)))) {
1869 val = remappingFunction.apply(key, e.val);
1870 if (val != null)
1871 e.val = val;
1872 else {
1873 delta = -1;
1874 Node<K,V> en = e.next;
1875 if (pred != null)
1876 pred.next = en;
1877 else
1878 setTabAt(tab, i, en);
1879 }
1880 break;
1881 }
1882 pred = e;
1883 if ((e = e.next) == null) {
1884 val = remappingFunction.apply(key, null);
1885 if (val != null) {
1886 delta = 1;
1887 pred.next =
1888 new Node<K,V>(h, key, val, null);
1889 }
1890 break;
1891 }
1892 }
1893 }
1894 else if (f instanceof TreeBin) {
1895 binCount = 1;
1896 TreeBin<K,V> t = (TreeBin<K,V>)f;
1897 TreeNode<K,V> r, p;
1898 if ((r = t.root) != null)
1899 p = r.findTreeNode(h, key, null);
1900 else
1901 p = null;
1902 V pv = (p == null) ? null : p.val;
1903 val = remappingFunction.apply(key, pv);
1904 if (val != null) {
1905 if (p != null)
1906 p.val = val;
1907 else {
1908 delta = 1;
1909 t.putTreeVal(h, key, val);
1910 }
1911 }
1912 else if (p != null) {
1913 delta = -1;
1914 if (t.removeTreeNode(p))
1915 setTabAt(tab, i, untreeify(t.first));
1916 }
1917 }
1918 }
1919 }
1920 if (binCount != 0) {
1921 if (binCount >= TREEIFY_THRESHOLD)
1922 treeifyBin(tab, i);
1923 break;
1924 }
1925 }
1926 }
1927 if (delta != 0)
1928 addCount((long)delta, binCount);
1929 return val;
1930 }
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952 public V merge(K key, V value, BiFun<? super V, ? super V, ? extends V> remappingFunction) {
1953 if (key == null || value == null || remappingFunction == null)
1954 throw new NullPointerException();
1955 int h = spread(key.hashCode());
1956 V val = null;
1957 int delta = 0;
1958 int binCount = 0;
1959 for (Node<K,V>[] tab = table;;) {
1960 Node<K,V> f; int n, i, fh;
1961 if (tab == null || (n = tab.length) == 0)
1962 tab = initTable();
1963 else if ((f = tabAt(tab, i = (n - 1) & h)) == null) {
1964 if (casTabAt(tab, i, null, new Node<K,V>(h, key, value, null))) {
1965 delta = 1;
1966 val = value;
1967 break;
1968 }
1969 }
1970 else if ((fh = f.hash) == MOVED)
1971 tab = helpTransfer(tab, f);
1972 else {
1973 synchronized (f) {
1974 if (tabAt(tab, i) == f) {
1975 if (fh >= 0) {
1976 binCount = 1;
1977 for (Node<K,V> e = f, pred = null;; ++binCount) {
1978 K ek;
1979 if (e.hash == h &&
1980 ((ek = e.key) == key ||
1981 (ek != null && key.equals(ek)))) {
1982 val = remappingFunction.apply(e.val, value);
1983 if (val != null)
1984 e.val = val;
1985 else {
1986 delta = -1;
1987 Node<K,V> en = e.next;
1988 if (pred != null)
1989 pred.next = en;
1990 else
1991 setTabAt(tab, i, en);
1992 }
1993 break;
1994 }
1995 pred = e;
1996 if ((e = e.next) == null) {
1997 delta = 1;
1998 val = value;
1999 pred.next =
2000 new Node<K,V>(h, key, val, null);
2001 break;
2002 }
2003 }
2004 }
2005 else if (f instanceof TreeBin) {
2006 binCount = 2;
2007 TreeBin<K,V> t = (TreeBin<K,V>)f;
2008 TreeNode<K,V> r = t.root;
2009 TreeNode<K,V> p = (r == null) ? null :
2010 r.findTreeNode(h, key, null);
2011 val = (p == null) ? value :
2012 remappingFunction.apply(p.val, value);
2013 if (val != null) {
2014 if (p != null)
2015 p.val = val;
2016 else {
2017 delta = 1;
2018 t.putTreeVal(h, key, val);
2019 }
2020 }
2021 else if (p != null) {
2022 delta = -1;
2023 if (t.removeTreeNode(p))
2024 setTabAt(tab, i, untreeify(t.first));
2025 }
2026 }
2027 }
2028 }
2029 if (binCount != 0) {
2030 if (binCount >= TREEIFY_THRESHOLD)
2031 treeifyBin(tab, i);
2032 break;
2033 }
2034 }
2035 }
2036 if (delta != 0)
2037 addCount((long)delta, binCount);
2038 return val;
2039 }
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058 @Deprecated public boolean contains(Object value) {
2059 return containsValue(value);
2060 }
2061
2062
2063
2064
2065
2066
2067
2068 public Enumeration<K> keys() {
2069 Node<K,V>[] t;
2070 int f = (t = table) == null ? 0 : t.length;
2071 return new KeyIterator<K,V>(t, f, 0, f, this);
2072 }
2073
2074
2075
2076
2077
2078
2079
2080 public Enumeration<V> elements() {
2081 Node<K,V>[] t;
2082 int f = (t = table) == null ? 0 : t.length;
2083 return new ValueIterator<K,V>(t, f, 0, f, this);
2084 }
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098 public long mappingCount() {
2099 long n = sumCount();
2100 return (n < 0L) ? 0L : n;
2101 }
2102
2103
2104
2105
2106
2107
2108
2109
2110 public static <K> KeySetView<K,Boolean> newKeySet() {
2111 return new KeySetView<K,Boolean>
2112 (new ConcurrentHashMapV8<K,Boolean>(), Boolean.TRUE);
2113 }
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126 public static <K> KeySetView<K,Boolean> newKeySet(int initialCapacity) {
2127 return new KeySetView<K,Boolean>
2128 (new ConcurrentHashMapV8<K,Boolean>(initialCapacity), Boolean.TRUE);
2129 }
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142 public KeySetView<K,V> keySet(V mappedValue) {
2143 if (mappedValue == null)
2144 throw new NullPointerException();
2145 return new KeySetView<K,V>(this, mappedValue);
2146 }
2147
2148
2149
2150
2151
2152
2153 static final class ForwardingNode<K,V> extends Node<K,V> {
2154 final Node<K,V>[] nextTable;
2155 ForwardingNode(Node<K,V>[] tab) {
2156 super(MOVED, null, null, null);
2157 this.nextTable = tab;
2158 }
2159
2160 Node<K,V> find(int h, Object k) {
2161
2162 outer: for (Node<K,V>[] tab = nextTable;;) {
2163 Node<K,V> e; int n;
2164 if (k == null || tab == null || (n = tab.length) == 0 ||
2165 (e = tabAt(tab, (n - 1) & h)) == null)
2166 return null;
2167 for (;;) {
2168 int eh; K ek;
2169 if ((eh = e.hash) == h &&
2170 ((ek = e.key) == k || (ek != null && k.equals(ek))))
2171 return e;
2172 if (eh < 0) {
2173 if (e instanceof ForwardingNode) {
2174 tab = ((ForwardingNode<K,V>)e).nextTable;
2175 continue outer;
2176 }
2177 else
2178 return e.find(h, k);
2179 }
2180 if ((e = e.next) == null)
2181 return null;
2182 }
2183 }
2184 }
2185 }
2186
2187
2188
2189
2190 static final class ReservationNode<K,V> extends Node<K,V> {
2191 ReservationNode() {
2192 super(RESERVED, null, null, null);
2193 }
2194
2195 Node<K,V> find(int h, Object k) {
2196 return null;
2197 }
2198 }
2199
2200
2201
2202
2203
2204
2205 private final Node<K,V>[] initTable() {
2206 Node<K,V>[] tab; int sc;
2207 while ((tab = table) == null || tab.length == 0) {
2208 if ((sc = sizeCtl) < 0)
2209 Thread.yield();
2210 else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
2211 try {
2212 if ((tab = table) == null || tab.length == 0) {
2213 int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
2214 @SuppressWarnings({"rawtypes","unchecked"})
2215 Node<K,V>[] nt = (Node<K,V>[])new Node[n];
2216 table = tab = nt;
2217 sc = n - (n >>> 2);
2218 }
2219 } finally {
2220 sizeCtl = sc;
2221 }
2222 break;
2223 }
2224 }
2225 return tab;
2226 }
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238 private final void addCount(long x, int check) {
2239 CounterCell[] as; long b, s;
2240 if ((as = counterCells) != null ||
2241 !U.compareAndSwapLong(this, BASECOUNT, b = baseCount, s = b + x)) {
2242 IntegerHolder hc; CounterCell a; long v; int m;
2243 boolean uncontended = true;
2244 InternalThreadLocalMap threadLocals = InternalThreadLocalMap.get();
2245 if ((hc = threadLocals.counterHashCode()) == null ||
2246 as == null || (m = as.length - 1) < 0 ||
2247 (a = as[m & hc.value]) == null ||
2248 !(uncontended =
2249 U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))) {
2250 fullAddCount(threadLocals, x, hc, uncontended);
2251 return;
2252 }
2253 if (check <= 1)
2254 return;
2255 s = sumCount();
2256 }
2257 if (check >= 0) {
2258 Node<K,V>[] tab, nt; int sc;
2259 while (s >= (long)(sc = sizeCtl) && (tab = table) != null &&
2260 tab.length < MAXIMUM_CAPACITY) {
2261 if (sc < 0) {
2262 if (sc == -1 || transferIndex <= transferOrigin ||
2263 (nt = nextTable) == null)
2264 break;
2265 if (U.compareAndSwapInt(this, SIZECTL, sc, sc - 1))
2266 transfer(tab, nt);
2267 }
2268 else if (U.compareAndSwapInt(this, SIZECTL, sc, -2))
2269 transfer(tab, null);
2270 s = sumCount();
2271 }
2272 }
2273 }
2274
2275
2276
2277
2278 final Node<K,V>[] helpTransfer(Node<K,V>[] tab, Node<K,V> f) {
2279 Node<K,V>[] nextTab; int sc;
2280 if ((f instanceof ForwardingNode) &&
2281 (nextTab = ((ForwardingNode<K,V>)f).nextTable) != null) {
2282 if (nextTab == nextTable && tab == table &&
2283 transferIndex > transferOrigin && (sc = sizeCtl) < -1 &&
2284 U.compareAndSwapInt(this, SIZECTL, sc, sc - 1))
2285 transfer(tab, nextTab);
2286 return nextTab;
2287 }
2288 return table;
2289 }
2290
2291
2292
2293
2294
2295
2296 private final void tryPresize(int size) {
2297 int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY :
2298 tableSizeFor(size + (size >>> 1) + 1);
2299 int sc;
2300 while ((sc = sizeCtl) >= 0) {
2301 Node<K,V>[] tab = table; int n;
2302 if (tab == null || (n = tab.length) == 0) {
2303 n = (sc > c) ? sc : c;
2304 if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
2305 try {
2306 if (table == tab) {
2307 @SuppressWarnings({"rawtypes","unchecked"})
2308 Node<K,V>[] nt = (Node<K,V>[])new Node[n];
2309 table = nt;
2310 sc = n - (n >>> 2);
2311 }
2312 } finally {
2313 sizeCtl = sc;
2314 }
2315 }
2316 }
2317 else if (c <= sc || n >= MAXIMUM_CAPACITY)
2318 break;
2319 else if (tab == table &&
2320 U.compareAndSwapInt(this, SIZECTL, sc, -2))
2321 transfer(tab, null);
2322 }
2323 }
2324
2325
2326
2327
2328
2329 private final void transfer(Node<K,V>[] tab, Node<K,V>[] nextTab) {
2330 int n = tab.length, stride;
2331 if ((stride = (NCPU > 1) ? (n >>> 3) / NCPU : n) < MIN_TRANSFER_STRIDE)
2332 stride = MIN_TRANSFER_STRIDE;
2333 if (nextTab == null) {
2334 try {
2335 @SuppressWarnings({"rawtypes","unchecked"})
2336 Node<K,V>[] nt = (Node<K,V>[])new Node[n << 1];
2337 nextTab = nt;
2338 } catch (Throwable ex) {
2339 sizeCtl = Integer.MAX_VALUE;
2340 return;
2341 }
2342 nextTable = nextTab;
2343 transferOrigin = n;
2344 transferIndex = n;
2345 ForwardingNode<K,V> rev = new ForwardingNode<K,V>(tab);
2346 for (int k = n; k > 0;) {
2347 int nextk = (k > stride) ? k - stride : 0;
2348 for (int m = nextk; m < k; ++m)
2349 nextTab[m] = rev;
2350 for (int m = n + nextk; m < n + k; ++m)
2351 nextTab[m] = rev;
2352 U.putOrderedInt(this, TRANSFERORIGIN, k = nextk);
2353 }
2354 }
2355 int nextn = nextTab.length;
2356 ForwardingNode<K,V> fwd = new ForwardingNode<K,V>(nextTab);
2357 boolean advance = true;
2358 boolean finishing = false;
2359 for (int i = 0, bound = 0;;) {
2360 int nextIndex, nextBound, fh; Node<K,V> f;
2361 while (advance) {
2362 if (--i >= bound || finishing)
2363 advance = false;
2364 else if ((nextIndex = transferIndex) <= transferOrigin) {
2365 i = -1;
2366 advance = false;
2367 }
2368 else if (U.compareAndSwapInt
2369 (this, TRANSFERINDEX, nextIndex,
2370 nextBound = (nextIndex > stride ?
2371 nextIndex - stride : 0))) {
2372 bound = nextBound;
2373 i = nextIndex - 1;
2374 advance = false;
2375 }
2376 }
2377 if (i < 0 || i >= n || i + n >= nextn) {
2378 if (finishing) {
2379 nextTable = null;
2380 table = nextTab;
2381 sizeCtl = (n << 1) - (n >>> 1);
2382 return;
2383 }
2384 for (int sc;;) {
2385 if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, ++sc)) {
2386 if (sc != -1)
2387 return;
2388 finishing = advance = true;
2389 i = n;
2390 break;
2391 }
2392 }
2393 }
2394 else if ((f = tabAt(tab, i)) == null) {
2395 if (casTabAt(tab, i, null, fwd)) {
2396 setTabAt(nextTab, i, null);
2397 setTabAt(nextTab, i + n, null);
2398 advance = true;
2399 }
2400 }
2401 else if ((fh = f.hash) == MOVED)
2402 advance = true;
2403 else {
2404 synchronized (f) {
2405 if (tabAt(tab, i) == f) {
2406 Node<K,V> ln, hn;
2407 if (fh >= 0) {
2408 int runBit = fh & n;
2409 Node<K,V> lastRun = f;
2410 for (Node<K,V> p = f.next; p != null; p = p.next) {
2411 int b = p.hash & n;
2412 if (b != runBit) {
2413 runBit = b;
2414 lastRun = p;
2415 }
2416 }
2417 if (runBit == 0) {
2418 ln = lastRun;
2419 hn = null;
2420 }
2421 else {
2422 hn = lastRun;
2423 ln = null;
2424 }
2425 for (Node<K,V> p = f; p != lastRun; p = p.next) {
2426 int ph = p.hash; K pk = p.key; V pv = p.val;
2427 if ((ph & n) == 0)
2428 ln = new Node<K,V>(ph, pk, pv, ln);
2429 else
2430 hn = new Node<K,V>(ph, pk, pv, hn);
2431 }
2432 setTabAt(nextTab, i, ln);
2433 setTabAt(nextTab, i + n, hn);
2434 setTabAt(tab, i, fwd);
2435 advance = true;
2436 }
2437 else if (f instanceof TreeBin) {
2438 TreeBin<K,V> t = (TreeBin<K,V>)f;
2439 TreeNode<K,V> lo = null, loTail = null;
2440 TreeNode<K,V> hi = null, hiTail = null;
2441 int lc = 0, hc = 0;
2442 for (Node<K,V> e = t.first; e != null; e = e.next) {
2443 int h = e.hash;
2444 TreeNode<K,V> p = new TreeNode<K,V>
2445 (h, e.key, e.val, null, null);
2446 if ((h & n) == 0) {
2447 if ((p.prev = loTail) == null)
2448 lo = p;
2449 else
2450 loTail.next = p;
2451 loTail = p;
2452 ++lc;
2453 }
2454 else {
2455 if ((p.prev = hiTail) == null)
2456 hi = p;
2457 else
2458 hiTail.next = p;
2459 hiTail = p;
2460 ++hc;
2461 }
2462 }
2463 ln = (lc <= UNTREEIFY_THRESHOLD) ? untreeify(lo) :
2464 (hc != 0) ? new TreeBin<K,V>(lo) : t;
2465 hn = (hc <= UNTREEIFY_THRESHOLD) ? untreeify(hi) :
2466 (lc != 0) ? new TreeBin<K,V>(hi) : t;
2467 setTabAt(nextTab, i, ln);
2468 setTabAt(nextTab, i + n, hn);
2469 setTabAt(tab, i, fwd);
2470 advance = true;
2471 }
2472 }
2473 }
2474 }
2475 }
2476 }
2477
2478
2479
2480
2481
2482
2483
2484 private final void treeifyBin(Node<K,V>[] tab, int index) {
2485 Node<K,V> b; int n, sc;
2486 if (tab != null) {
2487 if ((n = tab.length) < MIN_TREEIFY_CAPACITY) {
2488 if (tab == table && (sc = sizeCtl) >= 0 &&
2489 U.compareAndSwapInt(this, SIZECTL, sc, -2))
2490 transfer(tab, null);
2491 }
2492 else if ((b = tabAt(tab, index)) != null && b.hash >= 0) {
2493 synchronized (b) {
2494 if (tabAt(tab, index) == b) {
2495 TreeNode<K,V> hd = null, tl = null;
2496 for (Node<K,V> e = b; e != null; e = e.next) {
2497 TreeNode<K,V> p =
2498 new TreeNode<K,V>(e.hash, e.key, e.val,
2499 null, null);
2500 if ((p.prev = tl) == null)
2501 hd = p;
2502 else
2503 tl.next = p;
2504 tl = p;
2505 }
2506 setTabAt(tab, index, new TreeBin<K,V>(hd));
2507 }
2508 }
2509 }
2510 }
2511 }
2512
2513
2514
2515
2516 static <K,V> Node<K,V> untreeify(Node<K,V> b) {
2517 Node<K,V> hd = null, tl = null;
2518 for (Node<K,V> q = b; q != null; q = q.next) {
2519 Node<K,V> p = new Node<K,V>(q.hash, q.key, q.val, null);
2520 if (tl == null)
2521 hd = p;
2522 else
2523 tl.next = p;
2524 tl = p;
2525 }
2526 return hd;
2527 }
2528
2529
2530
2531
2532
2533
2534 static final class TreeNode<K,V> extends Node<K,V> {
2535 TreeNode<K,V> parent;
2536 TreeNode<K,V> left;
2537 TreeNode<K,V> right;
2538 TreeNode<K,V> prev;
2539 boolean red;
2540
2541 TreeNode(int hash, K key, V val, Node<K,V> next,
2542 TreeNode<K,V> parent) {
2543 super(hash, key, val, next);
2544 this.parent = parent;
2545 }
2546
2547 Node<K,V> find(int h, Object k) {
2548 return findTreeNode(h, k, null);
2549 }
2550
2551
2552
2553
2554
2555 final TreeNode<K,V> findTreeNode(int h, Object k, Class<?> kc) {
2556 if (k != null) {
2557 TreeNode<K,V> p = this;
2558 do {
2559 int ph, dir; K pk; TreeNode<K,V> q;
2560 TreeNode<K,V> pl = p.left, pr = p.right;
2561 if ((ph = p.hash) > h)
2562 p = pl;
2563 else if (ph < h)
2564 p = pr;
2565 else if ((pk = p.key) == k || (pk != null && k.equals(pk)))
2566 return p;
2567 else if (pl == null && pr == null)
2568 break;
2569 else if ((kc != null ||
2570 (kc = comparableClassFor(k)) != null) &&
2571 (dir = compareComparables(kc, k, pk)) != 0)
2572 p = (dir < 0) ? pl : pr;
2573 else if (pl == null)
2574 p = pr;
2575 else if (pr == null ||
2576 (q = pr.findTreeNode(h, k, kc)) == null)
2577 p = pl;
2578 else
2579 return q;
2580 } while (p != null);
2581 }
2582 return null;
2583 }
2584 }
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595 static final class TreeBin<K,V> extends Node<K,V> {
2596 TreeNode<K,V> root;
2597 volatile TreeNode<K,V> first;
2598 volatile Thread waiter;
2599 volatile int lockState;
2600
2601 static final int WRITER = 1;
2602 static final int WAITER = 2;
2603 static final int READER = 4;
2604
2605
2606
2607
2608 TreeBin(TreeNode<K,V> b) {
2609 super(TREEBIN, null, null, null);
2610 this.first = b;
2611 TreeNode<K,V> r = null;
2612 for (TreeNode<K,V> x = b, next; x != null; x = next) {
2613 next = (TreeNode<K,V>)x.next;
2614 x.left = x.right = null;
2615 if (r == null) {
2616 x.parent = null;
2617 x.red = false;
2618 r = x;
2619 }
2620 else {
2621 Object key = x.key;
2622 int hash = x.hash;
2623 Class<?> kc = null;
2624 for (TreeNode<K,V> p = r;;) {
2625 int dir, ph;
2626 if ((ph = p.hash) > hash)
2627 dir = -1;
2628 else if (ph < hash)
2629 dir = 1;
2630 else if ((kc != null ||
2631 (kc = comparableClassFor(key)) != null))
2632 dir = compareComparables(kc, key, p.key);
2633 else
2634 dir = 0;
2635 TreeNode<K,V> xp = p;
2636 if ((p = (dir <= 0) ? p.left : p.right) == null) {
2637 x.parent = xp;
2638 if (dir <= 0)
2639 xp.left = x;
2640 else
2641 xp.right = x;
2642 r = balanceInsertion(r, x);
2643 break;
2644 }
2645 }
2646 }
2647 }
2648 this.root = r;
2649 }
2650
2651
2652
2653
2654 private final void lockRoot() {
2655 if (!U.compareAndSwapInt(this, LOCKSTATE, 0, WRITER))
2656 contendedLock();
2657 }
2658
2659
2660
2661
2662 private final void unlockRoot() {
2663 lockState = 0;
2664 }
2665
2666
2667
2668
2669 private final void contendedLock() {
2670 boolean waiting = false;
2671 for (int s;;) {
2672 if (((s = lockState) & WRITER) == 0) {
2673 if (U.compareAndSwapInt(this, LOCKSTATE, s, WRITER)) {
2674 if (waiting)
2675 waiter = null;
2676 return;
2677 }
2678 }
2679 else if ((s & WAITER) == 0) {
2680 if (U.compareAndSwapInt(this, LOCKSTATE, s, s | WAITER)) {
2681 waiting = true;
2682 waiter = Thread.currentThread();
2683 }
2684 }
2685 else if (waiting)
2686 LockSupport.park(this);
2687 }
2688 }
2689
2690
2691
2692
2693
2694
2695 final Node<K,V> find(int h, Object k) {
2696 if (k != null) {
2697 for (Node<K,V> e = first; e != null; e = e.next) {
2698 int s; K ek;
2699 if (((s = lockState) & (WAITER|WRITER)) != 0) {
2700 if (e.hash == h &&
2701 ((ek = e.key) == k || (ek != null && k.equals(ek))))
2702 return e;
2703 }
2704 else if (U.compareAndSwapInt(this, LOCKSTATE, s,
2705 s + READER)) {
2706 TreeNode<K,V> r, p;
2707 try {
2708 p = ((r = root) == null ? null :
2709 r.findTreeNode(h, k, null));
2710 } finally {
2711 Thread w;
2712 int ls;
2713 do {} while (!U.compareAndSwapInt
2714 (this, LOCKSTATE,
2715 ls = lockState, ls - READER));
2716 if (ls == (READER|WAITER) && (w = waiter) != null)
2717 LockSupport.unpark(w);
2718 }
2719 return p;
2720 }
2721 }
2722 }
2723 return null;
2724 }
2725
2726
2727
2728
2729
2730 final TreeNode<K,V> putTreeVal(int h, K k, V v) {
2731 Class<?> kc = null;
2732 for (TreeNode<K,V> p = root;;) {
2733 int dir, ph; K pk; TreeNode<K,V> q, pr;
2734 if (p == null) {
2735 first = root = new TreeNode<K,V>(h, k, v, null, null);
2736 break;
2737 }
2738 else if ((ph = p.hash) > h)
2739 dir = -1;
2740 else if (ph < h)
2741 dir = 1;
2742 else if ((pk = p.key) == k || (pk != null && k.equals(pk)))
2743 return p;
2744 else if ((kc == null &&
2745 (kc = comparableClassFor(k)) == null) ||
2746 (dir = compareComparables(kc, k, pk)) == 0) {
2747 if (p.left == null)
2748 dir = 1;
2749 else if ((pr = p.right) == null ||
2750 (q = pr.findTreeNode(h, k, kc)) == null)
2751 dir = -1;
2752 else
2753 return q;
2754 }
2755 TreeNode<K,V> xp = p;
2756 if ((p = (dir < 0) ? p.left : p.right) == null) {
2757 TreeNode<K,V> x, f = first;
2758 first = x = new TreeNode<K,V>(h, k, v, f, xp);
2759 if (f != null)
2760 f.prev = x;
2761 if (dir < 0)
2762 xp.left = x;
2763 else
2764 xp.right = x;
2765 if (!xp.red)
2766 x.red = true;
2767 else {
2768 lockRoot();
2769 try {
2770 root = balanceInsertion(root, x);
2771 } finally {
2772 unlockRoot();
2773 }
2774 }
2775 break;
2776 }
2777 }
2778 assert checkInvariants(root);
2779 return null;
2780 }
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792 final boolean removeTreeNode(TreeNode<K,V> p) {
2793 TreeNode<K,V> next = (TreeNode<K,V>)p.next;
2794 TreeNode<K,V> pred = p.prev;
2795 TreeNode<K,V> r, rl;
2796 if (pred == null)
2797 first = next;
2798 else
2799 pred.next = next;
2800 if (next != null)
2801 next.prev = pred;
2802 if (first == null) {
2803 root = null;
2804 return true;
2805 }
2806 if ((r = root) == null || r.right == null ||
2807 (rl = r.left) == null || rl.left == null)
2808 return true;
2809 lockRoot();
2810 try {
2811 TreeNode<K,V> replacement;
2812 TreeNode<K,V> pl = p.left;
2813 TreeNode<K,V> pr = p.right;
2814 if (pl != null && pr != null) {
2815 TreeNode<K,V> s = pr, sl;
2816 while ((sl = s.left) != null)
2817 s = sl;
2818 boolean c = s.red; s.red = p.red; p.red = c;
2819 TreeNode<K,V> sr = s.right;
2820 TreeNode<K,V> pp = p.parent;
2821 if (s == pr) {
2822 p.parent = s;
2823 s.right = p;
2824 }
2825 else {
2826 TreeNode<K,V> sp = s.parent;
2827 if ((p.parent = sp) != null) {
2828 if (s == sp.left)
2829 sp.left = p;
2830 else
2831 sp.right = p;
2832 }
2833 s.right = pr;
2834 pr.parent = s;
2835 }
2836 p.left = null;
2837 s.left = pl;
2838 pl.parent = s;
2839 if ((p.right = sr) != null)
2840 sr.parent = p;
2841 if ((s.parent = pp) == null)
2842 r = s;
2843 else if (p == pp.left)
2844 pp.left = s;
2845 else
2846 pp.right = s;
2847 if (sr != null)
2848 replacement = sr;
2849 else
2850 replacement = p;
2851 }
2852 else if (pl != null)
2853 replacement = pl;
2854 else if (pr != null)
2855 replacement = pr;
2856 else
2857 replacement = p;
2858 if (replacement != p) {
2859 TreeNode<K,V> pp = replacement.parent = p.parent;
2860 if (pp == null)
2861 r = replacement;
2862 else if (p == pp.left)
2863 pp.left = replacement;
2864 else
2865 pp.right = replacement;
2866 p.left = p.right = p.parent = null;
2867 }
2868
2869 root = (p.red) ? r : balanceDeletion(r, replacement);
2870
2871 if (p == replacement) {
2872 TreeNode<K,V> pp;
2873 if ((pp = p.parent) != null) {
2874 if (p == pp.left)
2875 pp.left = null;
2876 else if (p == pp.right)
2877 pp.right = null;
2878 p.parent = null;
2879 }
2880 }
2881 } finally {
2882 unlockRoot();
2883 }
2884 assert checkInvariants(root);
2885 return false;
2886 }
2887
2888
2889
2890
2891 static <K,V> TreeNode<K,V> rotateLeft(TreeNode<K,V> root,
2892 TreeNode<K,V> p) {
2893 TreeNode<K,V> r, pp, rl;
2894 if (p != null && (r = p.right) != null) {
2895 if ((rl = p.right = r.left) != null)
2896 rl.parent = p;
2897 if ((pp = r.parent = p.parent) == null)
2898 (root = r).red = false;
2899 else if (pp.left == p)
2900 pp.left = r;
2901 else
2902 pp.right = r;
2903 r.left = p;
2904 p.parent = r;
2905 }
2906 return root;
2907 }
2908
2909 static <K,V> TreeNode<K,V> rotateRight(TreeNode<K,V> root,
2910 TreeNode<K,V> p) {
2911 TreeNode<K,V> l, pp, lr;
2912 if (p != null && (l = p.left) != null) {
2913 if ((lr = p.left = l.right) != null)
2914 lr.parent = p;
2915 if ((pp = l.parent = p.parent) == null)
2916 (root = l).red = false;
2917 else if (pp.right == p)
2918 pp.right = l;
2919 else
2920 pp.left = l;
2921 l.right = p;
2922 p.parent = l;
2923 }
2924 return root;
2925 }
2926
2927 static <K,V> TreeNode<K,V> balanceInsertion(TreeNode<K,V> root,
2928 TreeNode<K,V> x) {
2929 x.red = true;
2930 for (TreeNode<K,V> xp, xpp, xppl, xppr;;) {
2931 if ((xp = x.parent) == null) {
2932 x.red = false;
2933 return x;
2934 }
2935 else if (!xp.red || (xpp = xp.parent) == null)
2936 return root;
2937 if (xp == (xppl = xpp.left)) {
2938 if ((xppr = xpp.right) != null && xppr.red) {
2939 xppr.red = false;
2940 xp.red = false;
2941 xpp.red = true;
2942 x = xpp;
2943 }
2944 else {
2945 if (x == xp.right) {
2946 root = rotateLeft(root, x = xp);
2947 xpp = (xp = x.parent) == null ? null : xp.parent;
2948 }
2949 if (xp != null) {
2950 xp.red = false;
2951 if (xpp != null) {
2952 xpp.red = true;
2953 root = rotateRight(root, xpp);
2954 }
2955 }
2956 }
2957 }
2958 else {
2959 if (xppl != null && xppl.red) {
2960 xppl.red = false;
2961 xp.red = false;
2962 xpp.red = true;
2963 x = xpp;
2964 }
2965 else {
2966 if (x == xp.left) {
2967 root = rotateRight(root, x = xp);
2968 xpp = (xp = x.parent) == null ? null : xp.parent;
2969 }
2970 if (xp != null) {
2971 xp.red = false;
2972 if (xpp != null) {
2973 xpp.red = true;
2974 root = rotateLeft(root, xpp);
2975 }
2976 }
2977 }
2978 }
2979 }
2980 }
2981
2982 static <K,V> TreeNode<K,V> balanceDeletion(TreeNode<K,V> root,
2983 TreeNode<K,V> x) {
2984 for (TreeNode<K,V> xp, xpl, xpr;;) {
2985 if (x == null || x == root)
2986 return root;
2987 else if ((xp = x.parent) == null) {
2988 x.red = false;
2989 return x;
2990 }
2991 else if (x.red) {
2992 x.red = false;
2993 return root;
2994 }
2995 else if ((xpl = xp.left) == x) {
2996 if ((xpr = xp.right) != null && xpr.red) {
2997 xpr.red = false;
2998 xp.red = true;
2999 root = rotateLeft(root, xp);
3000 xpr = (xp = x.parent) == null ? null : xp.right;
3001 }
3002 if (xpr == null)
3003 x = xp;
3004 else {
3005 TreeNode<K,V> sl = xpr.left, sr = xpr.right;
3006 if ((sr == null || !sr.red) &&
3007 (sl == null || !sl.red)) {
3008 xpr.red = true;
3009 x = xp;
3010 }
3011 else {
3012 if (sr == null || !sr.red) {
3013 if (sl != null)
3014 sl.red = false;
3015 xpr.red = true;
3016 root = rotateRight(root, xpr);
3017 xpr = (xp = x.parent) == null ?
3018 null : xp.right;
3019 }
3020 if (xpr != null) {
3021 xpr.red = (xp == null) ? false : xp.red;
3022 if ((sr = xpr.right) != null)
3023 sr.red = false;
3024 }
3025 if (xp != null) {
3026 xp.red = false;
3027 root = rotateLeft(root, xp);
3028 }
3029 x = root;
3030 }
3031 }
3032 }
3033 else {
3034 if (xpl != null && xpl.red) {
3035 xpl.red = false;
3036 xp.red = true;
3037 root = rotateRight(root, xp);
3038 xpl = (xp = x.parent) == null ? null : xp.left;
3039 }
3040 if (xpl == null)
3041 x = xp;
3042 else {
3043 TreeNode<K,V> sl = xpl.left, sr = xpl.right;
3044 if ((sl == null || !sl.red) &&
3045 (sr == null || !sr.red)) {
3046 xpl.red = true;
3047 x = xp;
3048 }
3049 else {
3050 if (sl == null || !sl.red) {
3051 if (sr != null)
3052 sr.red = false;
3053 xpl.red = true;
3054 root = rotateLeft(root, xpl);
3055 xpl = (xp = x.parent) == null ?
3056 null : xp.left;
3057 }
3058 if (xpl != null) {
3059 xpl.red = (xp == null) ? false : xp.red;
3060 if ((sl = xpl.left) != null)
3061 sl.red = false;
3062 }
3063 if (xp != null) {
3064 xp.red = false;
3065 root = rotateRight(root, xp);
3066 }
3067 x = root;
3068 }
3069 }
3070 }
3071 }
3072 }
3073
3074
3075
3076
3077 static <K,V> boolean checkInvariants(TreeNode<K,V> t) {
3078 TreeNode<K,V> tp = t.parent, tl = t.left, tr = t.right,
3079 tb = t.prev, tn = (TreeNode<K,V>)t.next;
3080 if (tb != null && tb.next != t)
3081 return false;
3082 if (tn != null && tn.prev != t)
3083 return false;
3084 if (tp != null && t != tp.left && t != tp.right)
3085 return false;
3086 if (tl != null && (tl.parent != t || tl.hash > t.hash))
3087 return false;
3088 if (tr != null && (tr.parent != t || tr.hash < t.hash))
3089 return false;
3090 if (t.red && tl != null && tl.red && tr != null && tr.red)
3091 return false;
3092 if (tl != null && !checkInvariants(tl))
3093 return false;
3094 if (tr != null && !checkInvariants(tr))
3095 return false;
3096 return true;
3097 }
3098
3099 private static final sun.misc.Unsafe U;
3100 private static final long LOCKSTATE;
3101 static {
3102 try {
3103 U = getUnsafe();
3104 Class<?> k = TreeBin.class;
3105 LOCKSTATE = U.objectFieldOffset
3106 (k.getDeclaredField("lockState"));
3107 } catch (Exception e) {
3108 throw new Error(e);
3109 }
3110 }
3111 }
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136 static class Traverser<K,V> {
3137 Node<K,V>[] tab;
3138 Node<K,V> next;
3139 int index;
3140 int baseIndex;
3141 int baseLimit;
3142 final int baseSize;
3143
3144 Traverser(Node<K,V>[] tab, int size, int index, int limit) {
3145 this.tab = tab;
3146 this.baseSize = size;
3147 this.baseIndex = this.index = index;
3148 this.baseLimit = limit;
3149 this.next = null;
3150 }
3151
3152
3153
3154
3155 final Node<K,V> advance() {
3156 Node<K,V> e;
3157 if ((e = next) != null)
3158 e = e.next;
3159 for (;;) {
3160 Node<K,V>[] t; int i, n; K ek;
3161 if (e != null)
3162 return next = e;
3163 if (baseIndex >= baseLimit || (t = tab) == null ||
3164 (n = t.length) <= (i = index) || i < 0)
3165 return next = null;
3166 if ((e = tabAt(t, index)) != null && e.hash < 0) {
3167 if (e instanceof ForwardingNode) {
3168 tab = ((ForwardingNode<K,V>)e).nextTable;
3169 e = null;
3170 continue;
3171 }
3172 else if (e instanceof TreeBin)
3173 e = ((TreeBin<K,V>)e).first;
3174 else
3175 e = null;
3176 }
3177 if ((index += baseSize) >= n)
3178 index = ++baseIndex;
3179 }
3180 }
3181 }
3182
3183
3184
3185
3186
3187 static class BaseIterator<K,V> extends Traverser<K,V> {
3188 final ConcurrentHashMapV8<K,V> map;
3189 Node<K,V> lastReturned;
3190 BaseIterator(Node<K,V>[] tab, int size, int index, int limit,
3191 ConcurrentHashMapV8<K,V> map) {
3192 super(tab, size, index, limit);
3193 this.map = map;
3194 advance();
3195 }
3196
3197 public final boolean hasNext() { return next != null; }
3198 public final boolean hasMoreElements() { return next != null; }
3199
3200 public final void remove() {
3201 Node<K,V> p;
3202 if ((p = lastReturned) == null)
3203 throw new IllegalStateException();
3204 lastReturned = null;
3205 map.replaceNode(p.key, null, null);
3206 }
3207 }
3208
3209 static final class KeyIterator<K,V> extends BaseIterator<K,V>
3210 implements Iterator<K>, Enumeration<K> {
3211 KeyIterator(Node<K,V>[] tab, int index, int size, int limit,
3212 ConcurrentHashMapV8<K,V> map) {
3213 super(tab, index, size, limit, map);
3214 }
3215
3216 public final K next() {
3217 Node<K,V> p;
3218 if ((p = next) == null)
3219 throw new NoSuchElementException();
3220 K k = p.key;
3221 lastReturned = p;
3222 advance();
3223 return k;
3224 }
3225
3226 public final K nextElement() { return next(); }
3227 }
3228
3229 static final class ValueIterator<K,V> extends BaseIterator<K,V>
3230 implements Iterator<V>, Enumeration<V> {
3231 ValueIterator(Node<K,V>[] tab, int index, int size, int limit,
3232 ConcurrentHashMapV8<K,V> map) {
3233 super(tab, index, size, limit, map);
3234 }
3235
3236 public final V next() {
3237 Node<K,V> p;
3238 if ((p = next) == null)
3239 throw new NoSuchElementException();
3240 V v = p.val;
3241 lastReturned = p;
3242 advance();
3243 return v;
3244 }
3245
3246 public final V nextElement() { return next(); }
3247 }
3248
3249 static final class EntryIterator<K,V> extends BaseIterator<K,V>
3250 implements Iterator<Map.Entry<K,V>> {
3251 EntryIterator(Node<K,V>[] tab, int index, int size, int limit,
3252 ConcurrentHashMapV8<K,V> map) {
3253 super(tab, index, size, limit, map);
3254 }
3255
3256 public final Map.Entry<K,V> next() {
3257 Node<K,V> p;
3258 if ((p = next) == null)
3259 throw new NoSuchElementException();
3260 K k = p.key;
3261 V v = p.val;
3262 lastReturned = p;
3263 advance();
3264 return new MapEntry<K,V>(k, v, map);
3265 }
3266 }
3267
3268
3269
3270
3271 static final class MapEntry<K,V> implements Map.Entry<K,V> {
3272 final K key;
3273 V val;
3274 final ConcurrentHashMapV8<K,V> map;
3275 MapEntry(K key, V val, ConcurrentHashMapV8<K,V> map) {
3276 this.key = key;
3277 this.val = val;
3278 this.map = map;
3279 }
3280 public K getKey() { return key; }
3281 public V getValue() { return val; }
3282 public int hashCode() { return key.hashCode() ^ val.hashCode(); }
3283 public String toString() { return key + "=" + val; }
3284
3285 public boolean equals(Object o) {
3286 Object k, v; Map.Entry<?,?> e;
3287 return ((o instanceof Map.Entry) &&
3288 (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
3289 (v = e.getValue()) != null &&
3290 (k == key || k.equals(key)) &&
3291 (v == val || v.equals(val)));
3292 }
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302 public V setValue(V value) {
3303 if (value == null) throw new NullPointerException();
3304 V v = val;
3305 val = value;
3306 map.put(key, value);
3307 return v;
3308 }
3309 }
3310
3311 static final class KeySpliterator<K,V> extends Traverser<K,V>
3312 implements ConcurrentHashMapSpliterator<K> {
3313 long est;
3314 KeySpliterator(Node<K,V>[] tab, int size, int index, int limit,
3315 long est) {
3316 super(tab, size, index, limit);
3317 this.est = est;
3318 }
3319
3320 public ConcurrentHashMapSpliterator<K> trySplit() {
3321 int i, f, h;
3322 return (h = ((i = baseIndex) + (f = baseLimit)) >>> 1) <= i ? null :
3323 new KeySpliterator<K,V>(tab, baseSize, baseLimit = h,
3324 f, est >>>= 1);
3325 }
3326
3327 public void forEachRemaining(Action<? super K> action) {
3328 if (action == null) throw new NullPointerException();
3329 for (Node<K,V> p; (p = advance()) != null;)
3330 action.apply(p.key);
3331 }
3332
3333 public boolean tryAdvance(Action<? super K> action) {
3334 if (action == null) throw new NullPointerException();
3335 Node<K,V> p;
3336 if ((p = advance()) == null)
3337 return false;
3338 action.apply(p.key);
3339 return true;
3340 }
3341
3342 public long estimateSize() { return est; }
3343
3344 }
3345
3346 static final class ValueSpliterator<K,V> extends Traverser<K,V>
3347 implements ConcurrentHashMapSpliterator<V> {
3348 long est;
3349 ValueSpliterator(Node<K,V>[] tab, int size, int index, int limit,
3350 long est) {
3351 super(tab, size, index, limit);
3352 this.est = est;
3353 }
3354
3355 public ConcurrentHashMapSpliterator<V> trySplit() {
3356 int i, f, h;
3357 return (h = ((i = baseIndex) + (f = baseLimit)) >>> 1) <= i ? null :
3358 new ValueSpliterator<K,V>(tab, baseSize, baseLimit = h,
3359 f, est >>>= 1);
3360 }
3361
3362 public void forEachRemaining(Action<? super V> action) {
3363 if (action == null) throw new NullPointerException();
3364 for (Node<K,V> p; (p = advance()) != null;)
3365 action.apply(p.val);
3366 }
3367
3368 public boolean tryAdvance(Action<? super V> action) {
3369 if (action == null) throw new NullPointerException();
3370 Node<K,V> p;
3371 if ((p = advance()) == null)
3372 return false;
3373 action.apply(p.val);
3374 return true;
3375 }
3376
3377 public long estimateSize() { return est; }
3378
3379 }
3380
3381 static final class EntrySpliterator<K,V> extends Traverser<K,V>
3382 implements ConcurrentHashMapSpliterator<Map.Entry<K,V>> {
3383 final ConcurrentHashMapV8<K,V> map;
3384 long est;
3385 EntrySpliterator(Node<K,V>[] tab, int size, int index, int limit,
3386 long est, ConcurrentHashMapV8<K,V> map) {
3387 super(tab, size, index, limit);
3388 this.map = map;
3389 this.est = est;
3390 }
3391
3392 public ConcurrentHashMapSpliterator<Map.Entry<K,V>> trySplit() {
3393 int i, f, h;
3394 return (h = ((i = baseIndex) + (f = baseLimit)) >>> 1) <= i ? null :
3395 new EntrySpliterator<K,V>(tab, baseSize, baseLimit = h,
3396 f, est >>>= 1, map);
3397 }
3398
3399 public void forEachRemaining(Action<? super Map.Entry<K,V>> action) {
3400 if (action == null) throw new NullPointerException();
3401 for (Node<K,V> p; (p = advance()) != null; )
3402 action.apply(new MapEntry<K,V>(p.key, p.val, map));
3403 }
3404
3405 public boolean tryAdvance(Action<? super Map.Entry<K,V>> action) {
3406 if (action == null) throw new NullPointerException();
3407 Node<K,V> p;
3408 if ((p = advance()) == null)
3409 return false;
3410 action.apply(new MapEntry<K,V>(p.key, p.val, map));
3411 return true;
3412 }
3413
3414 public long estimateSize() { return est; }
3415
3416 }
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428 final int batchFor(long b) {
3429 long n;
3430 if (b == Long.MAX_VALUE || (n = sumCount()) <= 1L || n < b)
3431 return 0;
3432 int sp = ForkJoinPool.getCommonPoolParallelism() << 2;
3433 return (b <= 0L || (n /= b) >= sp) ? sp : (int)n;
3434 }
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444 public void forEach(long parallelismThreshold,
3445 BiAction<? super K,? super V> action) {
3446 if (action == null) throw new NullPointerException();
3447 new ForEachMappingTask<K,V>
3448 (null, batchFor(parallelismThreshold), 0, 0, table,
3449 action).invoke();
3450 }
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464 public <U> void forEach(long parallelismThreshold,
3465 BiFun<? super K, ? super V, ? extends U> transformer,
3466 Action<? super U> action) {
3467 if (transformer == null || action == null)
3468 throw new NullPointerException();
3469 new ForEachTransformedMappingTask<K,V,U>
3470 (null, batchFor(parallelismThreshold), 0, 0, table,
3471 transformer, action).invoke();
3472 }
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489 public <U> U search(long parallelismThreshold,
3490 BiFun<? super K, ? super V, ? extends U> searchFunction) {
3491 if (searchFunction == null) throw new NullPointerException();
3492 return new SearchMappingsTask<K,V,U>
3493 (null, batchFor(parallelismThreshold), 0, 0, table,
3494 searchFunction, new AtomicReference<U>()).invoke();
3495 }
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512 public <U> U reduce(long parallelismThreshold,
3513 BiFun<? super K, ? super V, ? extends U> transformer,
3514 BiFun<? super U, ? super U, ? extends U> reducer) {
3515 if (transformer == null || reducer == null)
3516 throw new NullPointerException();
3517 return new MapReduceMappingsTask<K,V,U>
3518 (null, batchFor(parallelismThreshold), 0, 0, table,
3519 null, transformer, reducer).invoke();
3520 }
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537 public double reduceToDouble(long parallelismThreshold,
3538 ObjectByObjectToDouble<? super K, ? super V> transformer,
3539 double basis,
3540 DoubleByDoubleToDouble reducer) {
3541 if (transformer == null || reducer == null)
3542 throw new NullPointerException();
3543 return new MapReduceMappingsToDoubleTask<K,V>
3544 (null, batchFor(parallelismThreshold), 0, 0, table,
3545 null, transformer, basis, reducer).invoke();
3546 }
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563 public long reduceToLong(long parallelismThreshold,
3564 ObjectByObjectToLong<? super K, ? super V> transformer,
3565 long basis,
3566 LongByLongToLong reducer) {
3567 if (transformer == null || reducer == null)
3568 throw new NullPointerException();
3569 return new MapReduceMappingsToLongTask<K,V>
3570 (null, batchFor(parallelismThreshold), 0, 0, table,
3571 null, transformer, basis, reducer).invoke();
3572 }
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589 public int reduceToInt(long parallelismThreshold,
3590 ObjectByObjectToInt<? super K, ? super V> transformer,
3591 int basis,
3592 IntByIntToInt reducer) {
3593 if (transformer == null || reducer == null)
3594 throw new NullPointerException();
3595 return new MapReduceMappingsToIntTask<K,V>
3596 (null, batchFor(parallelismThreshold), 0, 0, table,
3597 null, transformer, basis, reducer).invoke();
3598 }
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608 public void forEachKey(long parallelismThreshold,
3609 Action<? super K> action) {
3610 if (action == null) throw new NullPointerException();
3611 new ForEachKeyTask<K,V>
3612 (null, batchFor(parallelismThreshold), 0, 0, table,
3613 action).invoke();
3614 }
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628 public <U> void forEachKey(long parallelismThreshold,
3629 Fun<? super K, ? extends U> transformer,
3630 Action<? super U> action) {
3631 if (transformer == null || action == null)
3632 throw new NullPointerException();
3633 new ForEachTransformedKeyTask<K,V,U>
3634 (null, batchFor(parallelismThreshold), 0, 0, table,
3635 transformer, action).invoke();
3636 }
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653 public <U> U searchKeys(long parallelismThreshold,
3654 Fun<? super K, ? extends U> searchFunction) {
3655 if (searchFunction == null) throw new NullPointerException();
3656 return new SearchKeysTask<K,V,U>
3657 (null, batchFor(parallelismThreshold), 0, 0, table,
3658 searchFunction, new AtomicReference<U>()).invoke();
3659 }
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672 public K reduceKeys(long parallelismThreshold,
3673 BiFun<? super K, ? super K, ? extends K> reducer) {
3674 if (reducer == null) throw new NullPointerException();
3675 return new ReduceKeysTask<K,V>
3676 (null, batchFor(parallelismThreshold), 0, 0, table,
3677 null, reducer).invoke();
3678 }
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695 public <U> U reduceKeys(long parallelismThreshold,
3696 Fun<? super K, ? extends U> transformer,
3697 BiFun<? super U, ? super U, ? extends U> reducer) {
3698 if (transformer == null || reducer == null)
3699 throw new NullPointerException();
3700 return new MapReduceKeysTask<K,V,U>
3701 (null, batchFor(parallelismThreshold), 0, 0, table,
3702 null, transformer, reducer).invoke();
3703 }
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720 public double reduceKeysToDouble(long parallelismThreshold,
3721 ObjectToDouble<? super K> transformer,
3722 double basis,
3723 DoubleByDoubleToDouble reducer) {
3724 if (transformer == null || reducer == null)
3725 throw new NullPointerException();
3726 return new MapReduceKeysToDoubleTask<K,V>
3727 (null, batchFor(parallelismThreshold), 0, 0, table,
3728 null, transformer, basis, reducer).invoke();
3729 }
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746 public long reduceKeysToLong(long parallelismThreshold,
3747 ObjectToLong<? super K> transformer,
3748 long basis,
3749 LongByLongToLong reducer) {
3750 if (transformer == null || reducer == null)
3751 throw new NullPointerException();
3752 return new MapReduceKeysToLongTask<K,V>
3753 (null, batchFor(parallelismThreshold), 0, 0, table,
3754 null, transformer, basis, reducer).invoke();
3755 }
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772 public int reduceKeysToInt(long parallelismThreshold,
3773 ObjectToInt<? super K> transformer,
3774 int basis,
3775 IntByIntToInt reducer) {
3776 if (transformer == null || reducer == null)
3777 throw new NullPointerException();
3778 return new MapReduceKeysToIntTask<K,V>
3779 (null, batchFor(parallelismThreshold), 0, 0, table,
3780 null, transformer, basis, reducer).invoke();
3781 }
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791 public void forEachValue(long parallelismThreshold,
3792 Action<? super V> action) {
3793 if (action == null)
3794 throw new NullPointerException();
3795 new ForEachValueTask<K,V>
3796 (null, batchFor(parallelismThreshold), 0, 0, table,
3797 action).invoke();
3798 }
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812 public <U> void forEachValue(long parallelismThreshold,
3813 Fun<? super V, ? extends U> transformer,
3814 Action<? super U> action) {
3815 if (transformer == null || action == null)
3816 throw new NullPointerException();
3817 new ForEachTransformedValueTask<K,V,U>
3818 (null, batchFor(parallelismThreshold), 0, 0, table,
3819 transformer, action).invoke();
3820 }
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837 public <U> U searchValues(long parallelismThreshold,
3838 Fun<? super V, ? extends U> searchFunction) {
3839 if (searchFunction == null) throw new NullPointerException();
3840 return new SearchValuesTask<K,V,U>
3841 (null, batchFor(parallelismThreshold), 0, 0, table,
3842 searchFunction, new AtomicReference<U>()).invoke();
3843 }
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855 public V reduceValues(long parallelismThreshold,
3856 BiFun<? super V, ? super V, ? extends V> reducer) {
3857 if (reducer == null) throw new NullPointerException();
3858 return new ReduceValuesTask<K,V>
3859 (null, batchFor(parallelismThreshold), 0, 0, table,
3860 null, reducer).invoke();
3861 }
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878 public <U> U reduceValues(long parallelismThreshold,
3879 Fun<? super V, ? extends U> transformer,
3880 BiFun<? super U, ? super U, ? extends U> reducer) {
3881 if (transformer == null || reducer == null)
3882 throw new NullPointerException();
3883 return new MapReduceValuesTask<K,V,U>
3884 (null, batchFor(parallelismThreshold), 0, 0, table,
3885 null, transformer, reducer).invoke();
3886 }
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903 public double reduceValuesToDouble(long parallelismThreshold,
3904 ObjectToDouble<? super V> transformer,
3905 double basis,
3906 DoubleByDoubleToDouble reducer) {
3907 if (transformer == null || reducer == null)
3908 throw new NullPointerException();
3909 return new MapReduceValuesToDoubleTask<K,V>
3910 (null, batchFor(parallelismThreshold), 0, 0, table,
3911 null, transformer, basis, reducer).invoke();
3912 }
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929 public long reduceValuesToLong(long parallelismThreshold,
3930 ObjectToLong<? super V> transformer,
3931 long basis,
3932 LongByLongToLong reducer) {
3933 if (transformer == null || reducer == null)
3934 throw new NullPointerException();
3935 return new MapReduceValuesToLongTask<K,V>
3936 (null, batchFor(parallelismThreshold), 0, 0, table,
3937 null, transformer, basis, reducer).invoke();
3938 }
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955 public int reduceValuesToInt(long parallelismThreshold,
3956 ObjectToInt<? super V> transformer,
3957 int basis,
3958 IntByIntToInt reducer) {
3959 if (transformer == null || reducer == null)
3960 throw new NullPointerException();
3961 return new MapReduceValuesToIntTask<K,V>
3962 (null, batchFor(parallelismThreshold), 0, 0, table,
3963 null, transformer, basis, reducer).invoke();
3964 }
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974 public void forEachEntry(long parallelismThreshold,
3975 Action<? super Map.Entry<K,V>> action) {
3976 if (action == null) throw new NullPointerException();
3977 new ForEachEntryTask<K,V>(null, batchFor(parallelismThreshold), 0, 0, table,
3978 action).invoke();
3979 }
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993 public <U> void forEachEntry(long parallelismThreshold,
3994 Fun<Map.Entry<K,V>, ? extends U> transformer,
3995 Action<? super U> action) {
3996 if (transformer == null || action == null)
3997 throw new NullPointerException();
3998 new ForEachTransformedEntryTask<K,V,U>
3999 (null, batchFor(parallelismThreshold), 0, 0, table,
4000 transformer, action).invoke();
4001 }
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018 public <U> U searchEntries(long parallelismThreshold,
4019 Fun<Map.Entry<K,V>, ? extends U> searchFunction) {
4020 if (searchFunction == null) throw new NullPointerException();
4021 return new SearchEntriesTask<K,V,U>
4022 (null, batchFor(parallelismThreshold), 0, 0, table,
4023 searchFunction, new AtomicReference<U>()).invoke();
4024 }
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036 public Map.Entry<K,V> reduceEntries(long parallelismThreshold,
4037 BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
4038 if (reducer == null) throw new NullPointerException();
4039 return new ReduceEntriesTask<K,V>
4040 (null, batchFor(parallelismThreshold), 0, 0, table,
4041 null, reducer).invoke();
4042 }
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059 public <U> U reduceEntries(long parallelismThreshold,
4060 Fun<Map.Entry<K,V>, ? extends U> transformer,
4061 BiFun<? super U, ? super U, ? extends U> reducer) {
4062 if (transformer == null || reducer == null)
4063 throw new NullPointerException();
4064 return new MapReduceEntriesTask<K,V,U>
4065 (null, batchFor(parallelismThreshold), 0, 0, table,
4066 null, transformer, reducer).invoke();
4067 }
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084 public double reduceEntriesToDouble(long parallelismThreshold,
4085 ObjectToDouble<Map.Entry<K,V>> transformer,
4086 double basis,
4087 DoubleByDoubleToDouble reducer) {
4088 if (transformer == null || reducer == null)
4089 throw new NullPointerException();
4090 return new MapReduceEntriesToDoubleTask<K,V>
4091 (null, batchFor(parallelismThreshold), 0, 0, table,
4092 null, transformer, basis, reducer).invoke();
4093 }
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110 public long reduceEntriesToLong(long parallelismThreshold,
4111 ObjectToLong<Map.Entry<K,V>> transformer,
4112 long basis,
4113 LongByLongToLong reducer) {
4114 if (transformer == null || reducer == null)
4115 throw new NullPointerException();
4116 return new MapReduceEntriesToLongTask<K,V>
4117 (null, batchFor(parallelismThreshold), 0, 0, table,
4118 null, transformer, basis, reducer).invoke();
4119 }
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136 public int reduceEntriesToInt(long parallelismThreshold,
4137 ObjectToInt<Map.Entry<K,V>> transformer,
4138 int basis,
4139 IntByIntToInt reducer) {
4140 if (transformer == null || reducer == null)
4141 throw new NullPointerException();
4142 return new MapReduceEntriesToIntTask<K,V>
4143 (null, batchFor(parallelismThreshold), 0, 0, table,
4144 null, transformer, basis, reducer).invoke();
4145 }
4146
4147
4148
4149
4150
4151
4152
4153 abstract static class CollectionView<K,V,E>
4154 implements Collection<E>, java.io.Serializable {
4155 private static final long serialVersionUID = 7249069246763182397L;
4156 final ConcurrentHashMapV8<K,V> map;
4157 CollectionView(ConcurrentHashMapV8<K,V> map) { this.map = map; }
4158
4159
4160
4161
4162
4163
4164 public ConcurrentHashMapV8<K,V> getMap() { return map; }
4165
4166
4167
4168
4169
4170 public final void clear() { map.clear(); }
4171 public final int size() { return map.size(); }
4172 public final boolean isEmpty() { return map.isEmpty(); }
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184 public abstract Iterator<E> iterator();
4185 public abstract boolean contains(Object o);
4186 public abstract boolean remove(Object o);
4187
4188 private static final String oomeMsg = "Required array size too large";
4189
4190 public final Object[] toArray() {
4191 long sz = map.mappingCount();
4192 if (sz > MAX_ARRAY_SIZE)
4193 throw new OutOfMemoryError(oomeMsg);
4194 int n = (int)sz;
4195 Object[] r = new Object[n];
4196 int i = 0;
4197 for (E e : this) {
4198 if (i == n) {
4199 if (n >= MAX_ARRAY_SIZE)
4200 throw new OutOfMemoryError(oomeMsg);
4201 if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
4202 n = MAX_ARRAY_SIZE;
4203 else
4204 n += (n >>> 1) + 1;
4205 r = Arrays.copyOf(r, n);
4206 }
4207 r[i++] = e;
4208 }
4209 return (i == n) ? r : Arrays.copyOf(r, i);
4210 }
4211
4212 @SuppressWarnings("unchecked")
4213 public final <T> T[] toArray(T[] a) {
4214 long sz = map.mappingCount();
4215 if (sz > MAX_ARRAY_SIZE)
4216 throw new OutOfMemoryError(oomeMsg);
4217 int m = (int)sz;
4218 T[] r = (a.length >= m) ? a :
4219 (T[])java.lang.reflect.Array
4220 .newInstance(a.getClass().getComponentType(), m);
4221 int n = r.length;
4222 int i = 0;
4223 for (E e : this) {
4224 if (i == n) {
4225 if (n >= MAX_ARRAY_SIZE)
4226 throw new OutOfMemoryError(oomeMsg);
4227 if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
4228 n = MAX_ARRAY_SIZE;
4229 else
4230 n += (n >>> 1) + 1;
4231 r = Arrays.copyOf(r, n);
4232 }
4233 r[i++] = (T)e;
4234 }
4235 if (a == r && i < n) {
4236 r[i] = null;
4237 return r;
4238 }
4239 return (i == n) ? r : Arrays.copyOf(r, i);
4240 }
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253 public final String toString() {
4254 StringBuilder sb = new StringBuilder();
4255 sb.append('[');
4256 Iterator<E> it = iterator();
4257 if (it.hasNext()) {
4258 for (;;) {
4259 Object e = it.next();
4260 sb.append(e == this ? "(this Collection)" : e);
4261 if (!it.hasNext())
4262 break;
4263 sb.append(',').append(' ');
4264 }
4265 }
4266 return sb.append(']').toString();
4267 }
4268
4269 public final boolean containsAll(Collection<?> c) {
4270 if (c != this) {
4271 for (Object e : c) {
4272 if (e == null || !contains(e))
4273 return false;
4274 }
4275 }
4276 return true;
4277 }
4278
4279 public final boolean removeAll(Collection<?> c) {
4280 boolean modified = false;
4281 for (Iterator<E> it = iterator(); it.hasNext();) {
4282 if (c.contains(it.next())) {
4283 it.remove();
4284 modified = true;
4285 }
4286 }
4287 return modified;
4288 }
4289
4290 public final boolean retainAll(Collection<?> c) {
4291 boolean modified = false;
4292 for (Iterator<E> it = iterator(); it.hasNext();) {
4293 if (!c.contains(it.next())) {
4294 it.remove();
4295 modified = true;
4296 }
4297 }
4298 return modified;
4299 }
4300
4301 }
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314 public static class KeySetView<K,V> extends CollectionView<K,V,K>
4315 implements Set<K>, java.io.Serializable {
4316 private static final long serialVersionUID = 7249069246763182397L;
4317 private final V value;
4318 KeySetView(ConcurrentHashMapV8<K,V> map, V value) {
4319 super(map);
4320 this.value = value;
4321 }
4322
4323
4324
4325
4326
4327
4328
4329
4330 public V getMappedValue() { return value; }
4331
4332
4333
4334
4335
4336 public boolean contains(Object o) { return map.containsKey(o); }
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347 public boolean remove(Object o) { return map.remove(o) != null; }
4348
4349
4350
4351
4352 public Iterator<K> iterator() {
4353 Node<K,V>[] t;
4354 ConcurrentHashMapV8<K,V> m = map;
4355 int f = (t = m.table) == null ? 0 : t.length;
4356 return new KeyIterator<K,V>(t, f, 0, f, m);
4357 }
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369 public boolean add(K e) {
4370 V v;
4371 if ((v = value) == null)
4372 throw new UnsupportedOperationException();
4373 return map.putVal(e, v, true) == null;
4374 }
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387 public boolean addAll(Collection<? extends K> c) {
4388 boolean added = false;
4389 V v;
4390 if ((v = value) == null)
4391 throw new UnsupportedOperationException();
4392 for (K e : c) {
4393 if (map.putVal(e, v, true) == null)
4394 added = true;
4395 }
4396 return added;
4397 }
4398
4399 public int hashCode() {
4400 int h = 0;
4401 for (K e : this)
4402 h += e.hashCode();
4403 return h;
4404 }
4405
4406 public boolean equals(Object o) {
4407 Set<?> c;
4408 return ((o instanceof Set) &&
4409 ((c = (Set<?>)o) == this ||
4410 (containsAll(c) && c.containsAll(this))));
4411 }
4412
4413 public ConcurrentHashMapSpliterator<K> spliterator166() {
4414 Node<K,V>[] t;
4415 ConcurrentHashMapV8<K,V> m = map;
4416 long n = m.sumCount();
4417 int f = (t = m.table) == null ? 0 : t.length;
4418 return new KeySpliterator<K,V>(t, f, 0, f, n < 0L ? 0L : n);
4419 }
4420
4421 public void forEach(Action<? super K> action) {
4422 if (action == null) throw new NullPointerException();
4423 Node<K,V>[] t;
4424 if ((t = map.table) != null) {
4425 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
4426 for (Node<K,V> p; (p = it.advance()) != null; )
4427 action.apply(p.key);
4428 }
4429 }
4430 }
4431
4432
4433
4434
4435
4436
4437 static final class ValuesView<K,V> extends CollectionView<K,V,V>
4438 implements Collection<V>, java.io.Serializable {
4439 private static final long serialVersionUID = 2249069246763182397L;
4440 ValuesView(ConcurrentHashMapV8<K,V> map) { super(map); }
4441 public final boolean contains(Object o) {
4442 return map.containsValue(o);
4443 }
4444
4445 public final boolean remove(Object o) {
4446 if (o != null) {
4447 for (Iterator<V> it = iterator(); it.hasNext();) {
4448 if (o.equals(it.next())) {
4449 it.remove();
4450 return true;
4451 }
4452 }
4453 }
4454 return false;
4455 }
4456
4457 public final Iterator<V> iterator() {
4458 ConcurrentHashMapV8<K,V> m = map;
4459 Node<K,V>[] t;
4460 int f = (t = m.table) == null ? 0 : t.length;
4461 return new ValueIterator<K,V>(t, f, 0, f, m);
4462 }
4463
4464 public final boolean add(V e) {
4465 throw new UnsupportedOperationException();
4466 }
4467 public final boolean addAll(Collection<? extends V> c) {
4468 throw new UnsupportedOperationException();
4469 }
4470
4471 public ConcurrentHashMapSpliterator<V> spliterator166() {
4472 Node<K,V>[] t;
4473 ConcurrentHashMapV8<K,V> m = map;
4474 long n = m.sumCount();
4475 int f = (t = m.table) == null ? 0 : t.length;
4476 return new ValueSpliterator<K,V>(t, f, 0, f, n < 0L ? 0L : n);
4477 }
4478
4479 public void forEach(Action<? super V> action) {
4480 if (action == null) throw new NullPointerException();
4481 Node<K,V>[] t;
4482 if ((t = map.table) != null) {
4483 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
4484 for (Node<K,V> p; (p = it.advance()) != null; )
4485 action.apply(p.val);
4486 }
4487 }
4488 }
4489
4490
4491
4492
4493
4494
4495 static final class EntrySetView<K,V> extends CollectionView<K,V,Map.Entry<K,V>>
4496 implements Set<Map.Entry<K,V>>, java.io.Serializable {
4497 private static final long serialVersionUID = 2249069246763182397L;
4498 EntrySetView(ConcurrentHashMapV8<K,V> map) { super(map); }
4499
4500 public boolean contains(Object o) {
4501 Object k, v, r; Map.Entry<?,?> e;
4502 return ((o instanceof Map.Entry) &&
4503 (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
4504 (r = map.get(k)) != null &&
4505 (v = e.getValue()) != null &&
4506 (v == r || v.equals(r)));
4507 }
4508
4509 public boolean remove(Object o) {
4510 Object k, v; Map.Entry<?,?> e;
4511 return ((o instanceof Map.Entry) &&
4512 (k = (e = (Map.Entry<?,?>)o).getKey()) != null &&
4513 (v = e.getValue()) != null &&
4514 map.remove(k, v));
4515 }
4516
4517
4518
4519
4520 public Iterator<Map.Entry<K,V>> iterator() {
4521 ConcurrentHashMapV8<K,V> m = map;
4522 Node<K,V>[] t;
4523 int f = (t = m.table) == null ? 0 : t.length;
4524 return new EntryIterator<K,V>(t, f, 0, f, m);
4525 }
4526
4527 public boolean add(Entry<K,V> e) {
4528 return map.putVal(e.getKey(), e.getValue(), false) == null;
4529 }
4530
4531 public boolean addAll(Collection<? extends Entry<K,V>> c) {
4532 boolean added = false;
4533 for (Entry<K,V> e : c) {
4534 if (add(e))
4535 added = true;
4536 }
4537 return added;
4538 }
4539
4540 public final int hashCode() {
4541 int h = 0;
4542 Node<K,V>[] t;
4543 if ((t = map.table) != null) {
4544 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
4545 for (Node<K,V> p; (p = it.advance()) != null; ) {
4546 h += p.hashCode();
4547 }
4548 }
4549 return h;
4550 }
4551
4552 public final boolean equals(Object o) {
4553 Set<?> c;
4554 return ((o instanceof Set) &&
4555 ((c = (Set<?>)o) == this ||
4556 (containsAll(c) && c.containsAll(this))));
4557 }
4558
4559 public ConcurrentHashMapSpliterator<Map.Entry<K,V>> spliterator166() {
4560 Node<K,V>[] t;
4561 ConcurrentHashMapV8<K,V> m = map;
4562 long n = m.sumCount();
4563 int f = (t = m.table) == null ? 0 : t.length;
4564 return new EntrySpliterator<K,V>(t, f, 0, f, n < 0L ? 0L : n, m);
4565 }
4566
4567 public void forEach(Action<? super Map.Entry<K,V>> action) {
4568 if (action == null) throw new NullPointerException();
4569 Node<K,V>[] t;
4570 if ((t = map.table) != null) {
4571 Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
4572 for (Node<K,V> p; (p = it.advance()) != null; )
4573 action.apply(new MapEntry<K,V>(p.key, p.val, map));
4574 }
4575 }
4576
4577 }
4578
4579
4580
4581
4582
4583
4584
4585 abstract static class BulkTask<K,V,R> extends CountedCompleter<R> {
4586 Node<K,V>[] tab;
4587 Node<K,V> next;
4588 int index;
4589 int baseIndex;
4590 int baseLimit;
4591 final int baseSize;
4592 int batch;
4593
4594 BulkTask(BulkTask<K,V,?> par, int b, int i, int f, Node<K,V>[] t) {
4595 super(par);
4596 this.batch = b;
4597 this.index = this.baseIndex = i;
4598 if ((this.tab = t) == null)
4599 this.baseSize = this.baseLimit = 0;
4600 else if (par == null)
4601 this.baseSize = this.baseLimit = t.length;
4602 else {
4603 this.baseLimit = f;
4604 this.baseSize = par.baseSize;
4605 }
4606 }
4607
4608
4609
4610
4611 final Node<K,V> advance() {
4612 Node<K,V> e;
4613 if ((e = next) != null)
4614 e = e.next;
4615 for (;;) {
4616 Node<K,V>[] t; int i, n; K ek;
4617 if (e != null)
4618 return next = e;
4619 if (baseIndex >= baseLimit || (t = tab) == null ||
4620 (n = t.length) <= (i = index) || i < 0)
4621 return next = null;
4622 if ((e = tabAt(t, index)) != null && e.hash < 0) {
4623 if (e instanceof ForwardingNode) {
4624 tab = ((ForwardingNode<K,V>)e).nextTable;
4625 e = null;
4626 continue;
4627 }
4628 else if (e instanceof TreeBin)
4629 e = ((TreeBin<K,V>)e).first;
4630 else
4631 e = null;
4632 }
4633 if ((index += baseSize) >= n)
4634 index = ++baseIndex;
4635 }
4636 }
4637 }
4638
4639
4640
4641
4642
4643
4644
4645
4646 @SuppressWarnings("serial")
4647 static final class ForEachKeyTask<K,V>
4648 extends BulkTask<K,V,Void> {
4649 final Action<? super K> action;
4650 ForEachKeyTask
4651 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
4652 Action<? super K> action) {
4653 super(p, b, i, f, t);
4654 this.action = action;
4655 }
4656 public final void compute() {
4657 final Action<? super K> action;
4658 if ((action = this.action) != null) {
4659 for (int i = baseIndex, f, h; batch > 0 &&
4660 (h = ((f = baseLimit) + i) >>> 1) > i;) {
4661 addToPendingCount(1);
4662 new ForEachKeyTask<K,V>
4663 (this, batch >>>= 1, baseLimit = h, f, tab,
4664 action).fork();
4665 }
4666 for (Node<K,V> p; (p = advance()) != null;)
4667 action.apply(p.key);
4668 propagateCompletion();
4669 }
4670 }
4671 }
4672
4673 @SuppressWarnings("serial")
4674 static final class ForEachValueTask<K,V>
4675 extends BulkTask<K,V,Void> {
4676 final Action<? super V> action;
4677 ForEachValueTask
4678 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
4679 Action<? super V> action) {
4680 super(p, b, i, f, t);
4681 this.action = action;
4682 }
4683 public final void compute() {
4684 final Action<? super V> action;
4685 if ((action = this.action) != null) {
4686 for (int i = baseIndex, f, h; batch > 0 &&
4687 (h = ((f = baseLimit) + i) >>> 1) > i;) {
4688 addToPendingCount(1);
4689 new ForEachValueTask<K,V>
4690 (this, batch >>>= 1, baseLimit = h, f, tab,
4691 action).fork();
4692 }
4693 for (Node<K,V> p; (p = advance()) != null;)
4694 action.apply(p.val);
4695 propagateCompletion();
4696 }
4697 }
4698 }
4699
4700 @SuppressWarnings("serial")
4701 static final class ForEachEntryTask<K,V>
4702 extends BulkTask<K,V,Void> {
4703 final Action<? super Entry<K,V>> action;
4704 ForEachEntryTask
4705 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
4706 Action<? super Entry<K,V>> action) {
4707 super(p, b, i, f, t);
4708 this.action = action;
4709 }
4710 public final void compute() {
4711 final Action<? super Entry<K,V>> action;
4712 if ((action = this.action) != null) {
4713 for (int i = baseIndex, f, h; batch > 0 &&
4714 (h = ((f = baseLimit) + i) >>> 1) > i;) {
4715 addToPendingCount(1);
4716 new ForEachEntryTask<K,V>
4717 (this, batch >>>= 1, baseLimit = h, f, tab,
4718 action).fork();
4719 }
4720 for (Node<K,V> p; (p = advance()) != null; )
4721 action.apply(p);
4722 propagateCompletion();
4723 }
4724 }
4725 }
4726
4727 @SuppressWarnings("serial")
4728 static final class ForEachMappingTask<K,V>
4729 extends BulkTask<K,V,Void> {
4730 final BiAction<? super K, ? super V> action;
4731 ForEachMappingTask
4732 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
4733 BiAction<? super K,? super V> action) {
4734 super(p, b, i, f, t);
4735 this.action = action;
4736 }
4737 public final void compute() {
4738 final BiAction<? super K, ? super V> action;
4739 if ((action = this.action) != null) {
4740 for (int i = baseIndex, f, h; batch > 0 &&
4741 (h = ((f = baseLimit) + i) >>> 1) > i;) {
4742 addToPendingCount(1);
4743 new ForEachMappingTask<K,V>
4744 (this, batch >>>= 1, baseLimit = h, f, tab,
4745 action).fork();
4746 }
4747 for (Node<K,V> p; (p = advance()) != null; )
4748 action.apply(p.key, p.val);
4749 propagateCompletion();
4750 }
4751 }
4752 }
4753
4754 @SuppressWarnings("serial")
4755 static final class ForEachTransformedKeyTask<K,V,U>
4756 extends BulkTask<K,V,Void> {
4757 final Fun<? super K, ? extends U> transformer;
4758 final Action<? super U> action;
4759 ForEachTransformedKeyTask
4760 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
4761 Fun<? super K, ? extends U> transformer, Action<? super U> action) {
4762 super(p, b, i, f, t);
4763 this.transformer = transformer; this.action = action;
4764 }
4765 public final void compute() {
4766 final Fun<? super K, ? extends U> transformer;
4767 final Action<? super U> action;
4768 if ((transformer = this.transformer) != null &&
4769 (action = this.action) != null) {
4770 for (int i = baseIndex, f, h; batch > 0 &&
4771 (h = ((f = baseLimit) + i) >>> 1) > i;) {
4772 addToPendingCount(1);
4773 new ForEachTransformedKeyTask<K,V,U>
4774 (this, batch >>>= 1, baseLimit = h, f, tab,
4775 transformer, action).fork();
4776 }
4777 for (Node<K,V> p; (p = advance()) != null; ) {
4778 U u;
4779 if ((u = transformer.apply(p.key)) != null)
4780 action.apply(u);
4781 }
4782 propagateCompletion();
4783 }
4784 }
4785 }
4786
4787 @SuppressWarnings("serial")
4788 static final class ForEachTransformedValueTask<K,V,U>
4789 extends BulkTask<K,V,Void> {
4790 final Fun<? super V, ? extends U> transformer;
4791 final Action<? super U> action;
4792 ForEachTransformedValueTask
4793 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
4794 Fun<? super V, ? extends U> transformer, Action<? super U> action) {
4795 super(p, b, i, f, t);
4796 this.transformer = transformer; this.action = action;
4797 }
4798 public final void compute() {
4799 final Fun<? super V, ? extends U> transformer;
4800 final Action<? super U> action;
4801 if ((transformer = this.transformer) != null &&
4802 (action = this.action) != null) {
4803 for (int i = baseIndex, f, h; batch > 0 &&
4804 (h = ((f = baseLimit) + i) >>> 1) > i;) {
4805 addToPendingCount(1);
4806 new ForEachTransformedValueTask<K,V,U>
4807 (this, batch >>>= 1, baseLimit = h, f, tab,
4808 transformer, action).fork();
4809 }
4810 for (Node<K,V> p; (p = advance()) != null; ) {
4811 U u;
4812 if ((u = transformer.apply(p.val)) != null)
4813 action.apply(u);
4814 }
4815 propagateCompletion();
4816 }
4817 }
4818 }
4819
4820 @SuppressWarnings("serial")
4821 static final class ForEachTransformedEntryTask<K,V,U>
4822 extends BulkTask<K,V,Void> {
4823 final Fun<Map.Entry<K,V>, ? extends U> transformer;
4824 final Action<? super U> action;
4825 ForEachTransformedEntryTask
4826 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
4827 Fun<Map.Entry<K,V>, ? extends U> transformer, Action<? super U> action) {
4828 super(p, b, i, f, t);
4829 this.transformer = transformer; this.action = action;
4830 }
4831 public final void compute() {
4832 final Fun<Map.Entry<K,V>, ? extends U> transformer;
4833 final Action<? super U> action;
4834 if ((transformer = this.transformer) != null &&
4835 (action = this.action) != null) {
4836 for (int i = baseIndex, f, h; batch > 0 &&
4837 (h = ((f = baseLimit) + i) >>> 1) > i;) {
4838 addToPendingCount(1);
4839 new ForEachTransformedEntryTask<K,V,U>
4840 (this, batch >>>= 1, baseLimit = h, f, tab,
4841 transformer, action).fork();
4842 }
4843 for (Node<K,V> p; (p = advance()) != null; ) {
4844 U u;
4845 if ((u = transformer.apply(p)) != null)
4846 action.apply(u);
4847 }
4848 propagateCompletion();
4849 }
4850 }
4851 }
4852
4853 @SuppressWarnings("serial")
4854 static final class ForEachTransformedMappingTask<K,V,U>
4855 extends BulkTask<K,V,Void> {
4856 final BiFun<? super K, ? super V, ? extends U> transformer;
4857 final Action<? super U> action;
4858 ForEachTransformedMappingTask
4859 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
4860 BiFun<? super K, ? super V, ? extends U> transformer,
4861 Action<? super U> action) {
4862 super(p, b, i, f, t);
4863 this.transformer = transformer; this.action = action;
4864 }
4865 public final void compute() {
4866 final BiFun<? super K, ? super V, ? extends U> transformer;
4867 final Action<? super U> action;
4868 if ((transformer = this.transformer) != null &&
4869 (action = this.action) != null) {
4870 for (int i = baseIndex, f, h; batch > 0 &&
4871 (h = ((f = baseLimit) + i) >>> 1) > i;) {
4872 addToPendingCount(1);
4873 new ForEachTransformedMappingTask<K,V,U>
4874 (this, batch >>>= 1, baseLimit = h, f, tab,
4875 transformer, action).fork();
4876 }
4877 for (Node<K,V> p; (p = advance()) != null; ) {
4878 U u;
4879 if ((u = transformer.apply(p.key, p.val)) != null)
4880 action.apply(u);
4881 }
4882 propagateCompletion();
4883 }
4884 }
4885 }
4886
4887 @SuppressWarnings("serial")
4888 static final class SearchKeysTask<K,V,U>
4889 extends BulkTask<K,V,U> {
4890 final Fun<? super K, ? extends U> searchFunction;
4891 final AtomicReference<U> result;
4892 SearchKeysTask
4893 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
4894 Fun<? super K, ? extends U> searchFunction,
4895 AtomicReference<U> result) {
4896 super(p, b, i, f, t);
4897 this.searchFunction = searchFunction; this.result = result;
4898 }
4899 public final U getRawResult() { return result.get(); }
4900 public final void compute() {
4901 final Fun<? super K, ? extends U> searchFunction;
4902 final AtomicReference<U> result;
4903 if ((searchFunction = this.searchFunction) != null &&
4904 (result = this.result) != null) {
4905 for (int i = baseIndex, f, h; batch > 0 &&
4906 (h = ((f = baseLimit) + i) >>> 1) > i;) {
4907 if (result.get() != null)
4908 return;
4909 addToPendingCount(1);
4910 new SearchKeysTask<K,V,U>
4911 (this, batch >>>= 1, baseLimit = h, f, tab,
4912 searchFunction, result).fork();
4913 }
4914 while (result.get() == null) {
4915 U u;
4916 Node<K,V> p;
4917 if ((p = advance()) == null) {
4918 propagateCompletion();
4919 break;
4920 }
4921 if ((u = searchFunction.apply(p.key)) != null) {
4922 if (result.compareAndSet(null, u))
4923 quietlyCompleteRoot();
4924 break;
4925 }
4926 }
4927 }
4928 }
4929 }
4930
4931 @SuppressWarnings("serial")
4932 static final class SearchValuesTask<K,V,U>
4933 extends BulkTask<K,V,U> {
4934 final Fun<? super V, ? extends U> searchFunction;
4935 final AtomicReference<U> result;
4936 SearchValuesTask
4937 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
4938 Fun<? super V, ? extends U> searchFunction,
4939 AtomicReference<U> result) {
4940 super(p, b, i, f, t);
4941 this.searchFunction = searchFunction; this.result = result;
4942 }
4943 public final U getRawResult() { return result.get(); }
4944 public final void compute() {
4945 final Fun<? super V, ? extends U> searchFunction;
4946 final AtomicReference<U> result;
4947 if ((searchFunction = this.searchFunction) != null &&
4948 (result = this.result) != null) {
4949 for (int i = baseIndex, f, h; batch > 0 &&
4950 (h = ((f = baseLimit) + i) >>> 1) > i;) {
4951 if (result.get() != null)
4952 return;
4953 addToPendingCount(1);
4954 new SearchValuesTask<K,V,U>
4955 (this, batch >>>= 1, baseLimit = h, f, tab,
4956 searchFunction, result).fork();
4957 }
4958 while (result.get() == null) {
4959 U u;
4960 Node<K,V> p;
4961 if ((p = advance()) == null) {
4962 propagateCompletion();
4963 break;
4964 }
4965 if ((u = searchFunction.apply(p.val)) != null) {
4966 if (result.compareAndSet(null, u))
4967 quietlyCompleteRoot();
4968 break;
4969 }
4970 }
4971 }
4972 }
4973 }
4974
4975 @SuppressWarnings("serial")
4976 static final class SearchEntriesTask<K,V,U>
4977 extends BulkTask<K,V,U> {
4978 final Fun<Entry<K,V>, ? extends U> searchFunction;
4979 final AtomicReference<U> result;
4980 SearchEntriesTask
4981 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
4982 Fun<Entry<K,V>, ? extends U> searchFunction,
4983 AtomicReference<U> result) {
4984 super(p, b, i, f, t);
4985 this.searchFunction = searchFunction; this.result = result;
4986 }
4987 public final U getRawResult() { return result.get(); }
4988 public final void compute() {
4989 final Fun<Entry<K,V>, ? extends U> searchFunction;
4990 final AtomicReference<U> result;
4991 if ((searchFunction = this.searchFunction) != null &&
4992 (result = this.result) != null) {
4993 for (int i = baseIndex, f, h; batch > 0 &&
4994 (h = ((f = baseLimit) + i) >>> 1) > i;) {
4995 if (result.get() != null)
4996 return;
4997 addToPendingCount(1);
4998 new SearchEntriesTask<K,V,U>
4999 (this, batch >>>= 1, baseLimit = h, f, tab,
5000 searchFunction, result).fork();
5001 }
5002 while (result.get() == null) {
5003 U u;
5004 Node<K,V> p;
5005 if ((p = advance()) == null) {
5006 propagateCompletion();
5007 break;
5008 }
5009 if ((u = searchFunction.apply(p)) != null) {
5010 if (result.compareAndSet(null, u))
5011 quietlyCompleteRoot();
5012 return;
5013 }
5014 }
5015 }
5016 }
5017 }
5018
5019 @SuppressWarnings("serial")
5020 static final class SearchMappingsTask<K,V,U>
5021 extends BulkTask<K,V,U> {
5022 final BiFun<? super K, ? super V, ? extends U> searchFunction;
5023 final AtomicReference<U> result;
5024 SearchMappingsTask
5025 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5026 BiFun<? super K, ? super V, ? extends U> searchFunction,
5027 AtomicReference<U> result) {
5028 super(p, b, i, f, t);
5029 this.searchFunction = searchFunction; this.result = result;
5030 }
5031 public final U getRawResult() { return result.get(); }
5032 public final void compute() {
5033 final BiFun<? super K, ? super V, ? extends U> searchFunction;
5034 final AtomicReference<U> result;
5035 if ((searchFunction = this.searchFunction) != null &&
5036 (result = this.result) != null) {
5037 for (int i = baseIndex, f, h; batch > 0 &&
5038 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5039 if (result.get() != null)
5040 return;
5041 addToPendingCount(1);
5042 new SearchMappingsTask<K,V,U>
5043 (this, batch >>>= 1, baseLimit = h, f, tab,
5044 searchFunction, result).fork();
5045 }
5046 while (result.get() == null) {
5047 U u;
5048 Node<K,V> p;
5049 if ((p = advance()) == null) {
5050 propagateCompletion();
5051 break;
5052 }
5053 if ((u = searchFunction.apply(p.key, p.val)) != null) {
5054 if (result.compareAndSet(null, u))
5055 quietlyCompleteRoot();
5056 break;
5057 }
5058 }
5059 }
5060 }
5061 }
5062
5063 @SuppressWarnings("serial")
5064 static final class ReduceKeysTask<K,V>
5065 extends BulkTask<K,V,K> {
5066 final BiFun<? super K, ? super K, ? extends K> reducer;
5067 K result;
5068 ReduceKeysTask<K,V> rights, nextRight;
5069 ReduceKeysTask
5070 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5071 ReduceKeysTask<K,V> nextRight,
5072 BiFun<? super K, ? super K, ? extends K> reducer) {
5073 super(p, b, i, f, t); this.nextRight = nextRight;
5074 this.reducer = reducer;
5075 }
5076 public final K getRawResult() { return result; }
5077 public final void compute() {
5078 final BiFun<? super K, ? super K, ? extends K> reducer;
5079 if ((reducer = this.reducer) != null) {
5080 for (int i = baseIndex, f, h; batch > 0 &&
5081 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5082 addToPendingCount(1);
5083 (rights = new ReduceKeysTask<K,V>
5084 (this, batch >>>= 1, baseLimit = h, f, tab,
5085 rights, reducer)).fork();
5086 }
5087 K r = null;
5088 for (Node<K,V> p; (p = advance()) != null; ) {
5089 K u = p.key;
5090 r = (r == null) ? u : u == null ? r : reducer.apply(r, u);
5091 }
5092 result = r;
5093 CountedCompleter<?> c;
5094 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5095 @SuppressWarnings("unchecked") ReduceKeysTask<K,V>
5096 t = (ReduceKeysTask<K,V>)c,
5097 s = t.rights;
5098 while (s != null) {
5099 K tr, sr;
5100 if ((sr = s.result) != null)
5101 t.result = (((tr = t.result) == null) ? sr :
5102 reducer.apply(tr, sr));
5103 s = t.rights = s.nextRight;
5104 }
5105 }
5106 }
5107 }
5108 }
5109
5110 @SuppressWarnings("serial")
5111 static final class ReduceValuesTask<K,V>
5112 extends BulkTask<K,V,V> {
5113 final BiFun<? super V, ? super V, ? extends V> reducer;
5114 V result;
5115 ReduceValuesTask<K,V> rights, nextRight;
5116 ReduceValuesTask
5117 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5118 ReduceValuesTask<K,V> nextRight,
5119 BiFun<? super V, ? super V, ? extends V> reducer) {
5120 super(p, b, i, f, t); this.nextRight = nextRight;
5121 this.reducer = reducer;
5122 }
5123 public final V getRawResult() { return result; }
5124 public final void compute() {
5125 final BiFun<? super V, ? super V, ? extends V> reducer;
5126 if ((reducer = this.reducer) != null) {
5127 for (int i = baseIndex, f, h; batch > 0 &&
5128 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5129 addToPendingCount(1);
5130 (rights = new ReduceValuesTask<K,V>
5131 (this, batch >>>= 1, baseLimit = h, f, tab,
5132 rights, reducer)).fork();
5133 }
5134 V r = null;
5135 for (Node<K,V> p; (p = advance()) != null; ) {
5136 V v = p.val;
5137 r = (r == null) ? v : reducer.apply(r, v);
5138 }
5139 result = r;
5140 CountedCompleter<?> c;
5141 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5142 @SuppressWarnings("unchecked") ReduceValuesTask<K,V>
5143 t = (ReduceValuesTask<K,V>)c,
5144 s = t.rights;
5145 while (s != null) {
5146 V tr, sr;
5147 if ((sr = s.result) != null)
5148 t.result = (((tr = t.result) == null) ? sr :
5149 reducer.apply(tr, sr));
5150 s = t.rights = s.nextRight;
5151 }
5152 }
5153 }
5154 }
5155 }
5156
5157 @SuppressWarnings("serial")
5158 static final class ReduceEntriesTask<K,V>
5159 extends BulkTask<K,V,Map.Entry<K,V>> {
5160 final BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer;
5161 Map.Entry<K,V> result;
5162 ReduceEntriesTask<K,V> rights, nextRight;
5163 ReduceEntriesTask
5164 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5165 ReduceEntriesTask<K,V> nextRight,
5166 BiFun<Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer) {
5167 super(p, b, i, f, t); this.nextRight = nextRight;
5168 this.reducer = reducer;
5169 }
5170 public final Map.Entry<K,V> getRawResult() { return result; }
5171 public final void compute() {
5172 final BiFun<Map.Entry<K,V>, Map.Entry<K,V>, ? extends Map.Entry<K,V>> reducer;
5173 if ((reducer = this.reducer) != null) {
5174 for (int i = baseIndex, f, h; batch > 0 &&
5175 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5176 addToPendingCount(1);
5177 (rights = new ReduceEntriesTask<K,V>
5178 (this, batch >>>= 1, baseLimit = h, f, tab,
5179 rights, reducer)).fork();
5180 }
5181 Map.Entry<K,V> r = null;
5182 for (Node<K,V> p; (p = advance()) != null; )
5183 r = (r == null) ? p : reducer.apply(r, p);
5184 result = r;
5185 CountedCompleter<?> c;
5186 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5187 @SuppressWarnings("unchecked") ReduceEntriesTask<K,V>
5188 t = (ReduceEntriesTask<K,V>)c,
5189 s = t.rights;
5190 while (s != null) {
5191 Map.Entry<K,V> tr, sr;
5192 if ((sr = s.result) != null)
5193 t.result = (((tr = t.result) == null) ? sr :
5194 reducer.apply(tr, sr));
5195 s = t.rights = s.nextRight;
5196 }
5197 }
5198 }
5199 }
5200 }
5201
5202 @SuppressWarnings("serial")
5203 static final class MapReduceKeysTask<K,V,U>
5204 extends BulkTask<K,V,U> {
5205 final Fun<? super K, ? extends U> transformer;
5206 final BiFun<? super U, ? super U, ? extends U> reducer;
5207 U result;
5208 MapReduceKeysTask<K,V,U> rights, nextRight;
5209 MapReduceKeysTask
5210 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5211 MapReduceKeysTask<K,V,U> nextRight,
5212 Fun<? super K, ? extends U> transformer,
5213 BiFun<? super U, ? super U, ? extends U> reducer) {
5214 super(p, b, i, f, t); this.nextRight = nextRight;
5215 this.transformer = transformer;
5216 this.reducer = reducer;
5217 }
5218 public final U getRawResult() { return result; }
5219 public final void compute() {
5220 final Fun<? super K, ? extends U> transformer;
5221 final BiFun<? super U, ? super U, ? extends U> reducer;
5222 if ((transformer = this.transformer) != null &&
5223 (reducer = this.reducer) != null) {
5224 for (int i = baseIndex, f, h; batch > 0 &&
5225 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5226 addToPendingCount(1);
5227 (rights = new MapReduceKeysTask<K,V,U>
5228 (this, batch >>>= 1, baseLimit = h, f, tab,
5229 rights, transformer, reducer)).fork();
5230 }
5231 U r = null;
5232 for (Node<K,V> p; (p = advance()) != null; ) {
5233 U u;
5234 if ((u = transformer.apply(p.key)) != null)
5235 r = (r == null) ? u : reducer.apply(r, u);
5236 }
5237 result = r;
5238 CountedCompleter<?> c;
5239 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5240 @SuppressWarnings("unchecked") MapReduceKeysTask<K,V,U>
5241 t = (MapReduceKeysTask<K,V,U>)c,
5242 s = t.rights;
5243 while (s != null) {
5244 U tr, sr;
5245 if ((sr = s.result) != null)
5246 t.result = (((tr = t.result) == null) ? sr :
5247 reducer.apply(tr, sr));
5248 s = t.rights = s.nextRight;
5249 }
5250 }
5251 }
5252 }
5253 }
5254
5255 @SuppressWarnings("serial")
5256 static final class MapReduceValuesTask<K,V,U>
5257 extends BulkTask<K,V,U> {
5258 final Fun<? super V, ? extends U> transformer;
5259 final BiFun<? super U, ? super U, ? extends U> reducer;
5260 U result;
5261 MapReduceValuesTask<K,V,U> rights, nextRight;
5262 MapReduceValuesTask
5263 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5264 MapReduceValuesTask<K,V,U> nextRight,
5265 Fun<? super V, ? extends U> transformer,
5266 BiFun<? super U, ? super U, ? extends U> reducer) {
5267 super(p, b, i, f, t); this.nextRight = nextRight;
5268 this.transformer = transformer;
5269 this.reducer = reducer;
5270 }
5271 public final U getRawResult() { return result; }
5272 public final void compute() {
5273 final Fun<? super V, ? extends U> transformer;
5274 final BiFun<? super U, ? super U, ? extends U> reducer;
5275 if ((transformer = this.transformer) != null &&
5276 (reducer = this.reducer) != null) {
5277 for (int i = baseIndex, f, h; batch > 0 &&
5278 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5279 addToPendingCount(1);
5280 (rights = new MapReduceValuesTask<K,V,U>
5281 (this, batch >>>= 1, baseLimit = h, f, tab,
5282 rights, transformer, reducer)).fork();
5283 }
5284 U r = null;
5285 for (Node<K,V> p; (p = advance()) != null; ) {
5286 U u;
5287 if ((u = transformer.apply(p.val)) != null)
5288 r = (r == null) ? u : reducer.apply(r, u);
5289 }
5290 result = r;
5291 CountedCompleter<?> c;
5292 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5293 @SuppressWarnings("unchecked") MapReduceValuesTask<K,V,U>
5294 t = (MapReduceValuesTask<K,V,U>)c,
5295 s = t.rights;
5296 while (s != null) {
5297 U tr, sr;
5298 if ((sr = s.result) != null)
5299 t.result = (((tr = t.result) == null) ? sr :
5300 reducer.apply(tr, sr));
5301 s = t.rights = s.nextRight;
5302 }
5303 }
5304 }
5305 }
5306 }
5307
5308 @SuppressWarnings("serial")
5309 static final class MapReduceEntriesTask<K,V,U>
5310 extends BulkTask<K,V,U> {
5311 final Fun<Map.Entry<K,V>, ? extends U> transformer;
5312 final BiFun<? super U, ? super U, ? extends U> reducer;
5313 U result;
5314 MapReduceEntriesTask<K,V,U> rights, nextRight;
5315 MapReduceEntriesTask
5316 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5317 MapReduceEntriesTask<K,V,U> nextRight,
5318 Fun<Map.Entry<K,V>, ? extends U> transformer,
5319 BiFun<? super U, ? super U, ? extends U> reducer) {
5320 super(p, b, i, f, t); this.nextRight = nextRight;
5321 this.transformer = transformer;
5322 this.reducer = reducer;
5323 }
5324 public final U getRawResult() { return result; }
5325 public final void compute() {
5326 final Fun<Map.Entry<K,V>, ? extends U> transformer;
5327 final BiFun<? super U, ? super U, ? extends U> reducer;
5328 if ((transformer = this.transformer) != null &&
5329 (reducer = this.reducer) != null) {
5330 for (int i = baseIndex, f, h; batch > 0 &&
5331 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5332 addToPendingCount(1);
5333 (rights = new MapReduceEntriesTask<K,V,U>
5334 (this, batch >>>= 1, baseLimit = h, f, tab,
5335 rights, transformer, reducer)).fork();
5336 }
5337 U r = null;
5338 for (Node<K,V> p; (p = advance()) != null; ) {
5339 U u;
5340 if ((u = transformer.apply(p)) != null)
5341 r = (r == null) ? u : reducer.apply(r, u);
5342 }
5343 result = r;
5344 CountedCompleter<?> c;
5345 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5346 @SuppressWarnings("unchecked") MapReduceEntriesTask<K,V,U>
5347 t = (MapReduceEntriesTask<K,V,U>)c,
5348 s = t.rights;
5349 while (s != null) {
5350 U tr, sr;
5351 if ((sr = s.result) != null)
5352 t.result = (((tr = t.result) == null) ? sr :
5353 reducer.apply(tr, sr));
5354 s = t.rights = s.nextRight;
5355 }
5356 }
5357 }
5358 }
5359 }
5360
5361 @SuppressWarnings("serial")
5362 static final class MapReduceMappingsTask<K,V,U>
5363 extends BulkTask<K,V,U> {
5364 final BiFun<? super K, ? super V, ? extends U> transformer;
5365 final BiFun<? super U, ? super U, ? extends U> reducer;
5366 U result;
5367 MapReduceMappingsTask<K,V,U> rights, nextRight;
5368 MapReduceMappingsTask
5369 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5370 MapReduceMappingsTask<K,V,U> nextRight,
5371 BiFun<? super K, ? super V, ? extends U> transformer,
5372 BiFun<? super U, ? super U, ? extends U> reducer) {
5373 super(p, b, i, f, t); this.nextRight = nextRight;
5374 this.transformer = transformer;
5375 this.reducer = reducer;
5376 }
5377 public final U getRawResult() { return result; }
5378 public final void compute() {
5379 final BiFun<? super K, ? super V, ? extends U> transformer;
5380 final BiFun<? super U, ? super U, ? extends U> reducer;
5381 if ((transformer = this.transformer) != null &&
5382 (reducer = this.reducer) != null) {
5383 for (int i = baseIndex, f, h; batch > 0 &&
5384 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5385 addToPendingCount(1);
5386 (rights = new MapReduceMappingsTask<K,V,U>
5387 (this, batch >>>= 1, baseLimit = h, f, tab,
5388 rights, transformer, reducer)).fork();
5389 }
5390 U r = null;
5391 for (Node<K,V> p; (p = advance()) != null; ) {
5392 U u;
5393 if ((u = transformer.apply(p.key, p.val)) != null)
5394 r = (r == null) ? u : reducer.apply(r, u);
5395 }
5396 result = r;
5397 CountedCompleter<?> c;
5398 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5399 @SuppressWarnings("unchecked") MapReduceMappingsTask<K,V,U>
5400 t = (MapReduceMappingsTask<K,V,U>)c,
5401 s = t.rights;
5402 while (s != null) {
5403 U tr, sr;
5404 if ((sr = s.result) != null)
5405 t.result = (((tr = t.result) == null) ? sr :
5406 reducer.apply(tr, sr));
5407 s = t.rights = s.nextRight;
5408 }
5409 }
5410 }
5411 }
5412 }
5413
5414 @SuppressWarnings("serial")
5415 static final class MapReduceKeysToDoubleTask<K,V>
5416 extends BulkTask<K,V,Double> {
5417 final ObjectToDouble<? super K> transformer;
5418 final DoubleByDoubleToDouble reducer;
5419 final double basis;
5420 double result;
5421 MapReduceKeysToDoubleTask<K,V> rights, nextRight;
5422 MapReduceKeysToDoubleTask
5423 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5424 MapReduceKeysToDoubleTask<K,V> nextRight,
5425 ObjectToDouble<? super K> transformer,
5426 double basis,
5427 DoubleByDoubleToDouble reducer) {
5428 super(p, b, i, f, t); this.nextRight = nextRight;
5429 this.transformer = transformer;
5430 this.basis = basis; this.reducer = reducer;
5431 }
5432 public final Double getRawResult() { return result; }
5433 public final void compute() {
5434 final ObjectToDouble<? super K> transformer;
5435 final DoubleByDoubleToDouble reducer;
5436 if ((transformer = this.transformer) != null &&
5437 (reducer = this.reducer) != null) {
5438 double r = this.basis;
5439 for (int i = baseIndex, f, h; batch > 0 &&
5440 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5441 addToPendingCount(1);
5442 (rights = new MapReduceKeysToDoubleTask<K,V>
5443 (this, batch >>>= 1, baseLimit = h, f, tab,
5444 rights, transformer, r, reducer)).fork();
5445 }
5446 for (Node<K,V> p; (p = advance()) != null; )
5447 r = reducer.apply(r, transformer.apply(p.key));
5448 result = r;
5449 CountedCompleter<?> c;
5450 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5451 @SuppressWarnings("unchecked") MapReduceKeysToDoubleTask<K,V>
5452 t = (MapReduceKeysToDoubleTask<K,V>)c,
5453 s = t.rights;
5454 while (s != null) {
5455 t.result = reducer.apply(t.result, s.result);
5456 s = t.rights = s.nextRight;
5457 }
5458 }
5459 }
5460 }
5461 }
5462
5463 @SuppressWarnings("serial")
5464 static final class MapReduceValuesToDoubleTask<K,V>
5465 extends BulkTask<K,V,Double> {
5466 final ObjectToDouble<? super V> transformer;
5467 final DoubleByDoubleToDouble reducer;
5468 final double basis;
5469 double result;
5470 MapReduceValuesToDoubleTask<K,V> rights, nextRight;
5471 MapReduceValuesToDoubleTask
5472 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5473 MapReduceValuesToDoubleTask<K,V> nextRight,
5474 ObjectToDouble<? super V> transformer,
5475 double basis,
5476 DoubleByDoubleToDouble reducer) {
5477 super(p, b, i, f, t); this.nextRight = nextRight;
5478 this.transformer = transformer;
5479 this.basis = basis; this.reducer = reducer;
5480 }
5481 public final Double getRawResult() { return result; }
5482 public final void compute() {
5483 final ObjectToDouble<? super V> transformer;
5484 final DoubleByDoubleToDouble reducer;
5485 if ((transformer = this.transformer) != null &&
5486 (reducer = this.reducer) != null) {
5487 double r = this.basis;
5488 for (int i = baseIndex, f, h; batch > 0 &&
5489 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5490 addToPendingCount(1);
5491 (rights = new MapReduceValuesToDoubleTask<K,V>
5492 (this, batch >>>= 1, baseLimit = h, f, tab,
5493 rights, transformer, r, reducer)).fork();
5494 }
5495 for (Node<K,V> p; (p = advance()) != null; )
5496 r = reducer.apply(r, transformer.apply(p.val));
5497 result = r;
5498 CountedCompleter<?> c;
5499 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5500 @SuppressWarnings("unchecked") MapReduceValuesToDoubleTask<K,V>
5501 t = (MapReduceValuesToDoubleTask<K,V>)c,
5502 s = t.rights;
5503 while (s != null) {
5504 t.result = reducer.apply(t.result, s.result);
5505 s = t.rights = s.nextRight;
5506 }
5507 }
5508 }
5509 }
5510 }
5511
5512 @SuppressWarnings("serial")
5513 static final class MapReduceEntriesToDoubleTask<K,V>
5514 extends BulkTask<K,V,Double> {
5515 final ObjectToDouble<Map.Entry<K,V>> transformer;
5516 final DoubleByDoubleToDouble reducer;
5517 final double basis;
5518 double result;
5519 MapReduceEntriesToDoubleTask<K,V> rights, nextRight;
5520 MapReduceEntriesToDoubleTask
5521 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5522 MapReduceEntriesToDoubleTask<K,V> nextRight,
5523 ObjectToDouble<Map.Entry<K,V>> transformer,
5524 double basis,
5525 DoubleByDoubleToDouble reducer) {
5526 super(p, b, i, f, t); this.nextRight = nextRight;
5527 this.transformer = transformer;
5528 this.basis = basis; this.reducer = reducer;
5529 }
5530 public final Double getRawResult() { return result; }
5531 public final void compute() {
5532 final ObjectToDouble<Map.Entry<K,V>> transformer;
5533 final DoubleByDoubleToDouble reducer;
5534 if ((transformer = this.transformer) != null &&
5535 (reducer = this.reducer) != null) {
5536 double r = this.basis;
5537 for (int i = baseIndex, f, h; batch > 0 &&
5538 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5539 addToPendingCount(1);
5540 (rights = new MapReduceEntriesToDoubleTask<K,V>
5541 (this, batch >>>= 1, baseLimit = h, f, tab,
5542 rights, transformer, r, reducer)).fork();
5543 }
5544 for (Node<K,V> p; (p = advance()) != null; )
5545 r = reducer.apply(r, transformer.apply(p));
5546 result = r;
5547 CountedCompleter<?> c;
5548 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5549 @SuppressWarnings("unchecked") MapReduceEntriesToDoubleTask<K,V>
5550 t = (MapReduceEntriesToDoubleTask<K,V>)c,
5551 s = t.rights;
5552 while (s != null) {
5553 t.result = reducer.apply(t.result, s.result);
5554 s = t.rights = s.nextRight;
5555 }
5556 }
5557 }
5558 }
5559 }
5560
5561 @SuppressWarnings("serial")
5562 static final class MapReduceMappingsToDoubleTask<K,V>
5563 extends BulkTask<K,V,Double> {
5564 final ObjectByObjectToDouble<? super K, ? super V> transformer;
5565 final DoubleByDoubleToDouble reducer;
5566 final double basis;
5567 double result;
5568 MapReduceMappingsToDoubleTask<K,V> rights, nextRight;
5569 MapReduceMappingsToDoubleTask
5570 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5571 MapReduceMappingsToDoubleTask<K,V> nextRight,
5572 ObjectByObjectToDouble<? super K, ? super V> transformer,
5573 double basis,
5574 DoubleByDoubleToDouble reducer) {
5575 super(p, b, i, f, t); this.nextRight = nextRight;
5576 this.transformer = transformer;
5577 this.basis = basis; this.reducer = reducer;
5578 }
5579 public final Double getRawResult() { return result; }
5580 public final void compute() {
5581 final ObjectByObjectToDouble<? super K, ? super V> transformer;
5582 final DoubleByDoubleToDouble reducer;
5583 if ((transformer = this.transformer) != null &&
5584 (reducer = this.reducer) != null) {
5585 double r = this.basis;
5586 for (int i = baseIndex, f, h; batch > 0 &&
5587 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5588 addToPendingCount(1);
5589 (rights = new MapReduceMappingsToDoubleTask<K,V>
5590 (this, batch >>>= 1, baseLimit = h, f, tab,
5591 rights, transformer, r, reducer)).fork();
5592 }
5593 for (Node<K,V> p; (p = advance()) != null; )
5594 r = reducer.apply(r, transformer.apply(p.key, p.val));
5595 result = r;
5596 CountedCompleter<?> c;
5597 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5598 @SuppressWarnings("unchecked") MapReduceMappingsToDoubleTask<K,V>
5599 t = (MapReduceMappingsToDoubleTask<K,V>)c,
5600 s = t.rights;
5601 while (s != null) {
5602 t.result = reducer.apply(t.result, s.result);
5603 s = t.rights = s.nextRight;
5604 }
5605 }
5606 }
5607 }
5608 }
5609
5610 @SuppressWarnings("serial")
5611 static final class MapReduceKeysToLongTask<K,V>
5612 extends BulkTask<K,V,Long> {
5613 final ObjectToLong<? super K> transformer;
5614 final LongByLongToLong reducer;
5615 final long basis;
5616 long result;
5617 MapReduceKeysToLongTask<K,V> rights, nextRight;
5618 MapReduceKeysToLongTask
5619 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5620 MapReduceKeysToLongTask<K,V> nextRight,
5621 ObjectToLong<? super K> transformer,
5622 long basis,
5623 LongByLongToLong reducer) {
5624 super(p, b, i, f, t); this.nextRight = nextRight;
5625 this.transformer = transformer;
5626 this.basis = basis; this.reducer = reducer;
5627 }
5628 public final Long getRawResult() { return result; }
5629 public final void compute() {
5630 final ObjectToLong<? super K> transformer;
5631 final LongByLongToLong reducer;
5632 if ((transformer = this.transformer) != null &&
5633 (reducer = this.reducer) != null) {
5634 long r = this.basis;
5635 for (int i = baseIndex, f, h; batch > 0 &&
5636 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5637 addToPendingCount(1);
5638 (rights = new MapReduceKeysToLongTask<K,V>
5639 (this, batch >>>= 1, baseLimit = h, f, tab,
5640 rights, transformer, r, reducer)).fork();
5641 }
5642 for (Node<K,V> p; (p = advance()) != null; )
5643 r = reducer.apply(r, transformer.apply(p.key));
5644 result = r;
5645 CountedCompleter<?> c;
5646 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5647 @SuppressWarnings("unchecked") MapReduceKeysToLongTask<K,V>
5648 t = (MapReduceKeysToLongTask<K,V>)c,
5649 s = t.rights;
5650 while (s != null) {
5651 t.result = reducer.apply(t.result, s.result);
5652 s = t.rights = s.nextRight;
5653 }
5654 }
5655 }
5656 }
5657 }
5658
5659 @SuppressWarnings("serial")
5660 static final class MapReduceValuesToLongTask<K,V>
5661 extends BulkTask<K,V,Long> {
5662 final ObjectToLong<? super V> transformer;
5663 final LongByLongToLong reducer;
5664 final long basis;
5665 long result;
5666 MapReduceValuesToLongTask<K,V> rights, nextRight;
5667 MapReduceValuesToLongTask
5668 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5669 MapReduceValuesToLongTask<K,V> nextRight,
5670 ObjectToLong<? super V> transformer,
5671 long basis,
5672 LongByLongToLong reducer) {
5673 super(p, b, i, f, t); this.nextRight = nextRight;
5674 this.transformer = transformer;
5675 this.basis = basis; this.reducer = reducer;
5676 }
5677 public final Long getRawResult() { return result; }
5678 public final void compute() {
5679 final ObjectToLong<? super V> transformer;
5680 final LongByLongToLong reducer;
5681 if ((transformer = this.transformer) != null &&
5682 (reducer = this.reducer) != null) {
5683 long r = this.basis;
5684 for (int i = baseIndex, f, h; batch > 0 &&
5685 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5686 addToPendingCount(1);
5687 (rights = new MapReduceValuesToLongTask<K,V>
5688 (this, batch >>>= 1, baseLimit = h, f, tab,
5689 rights, transformer, r, reducer)).fork();
5690 }
5691 for (Node<K,V> p; (p = advance()) != null; )
5692 r = reducer.apply(r, transformer.apply(p.val));
5693 result = r;
5694 CountedCompleter<?> c;
5695 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5696 @SuppressWarnings("unchecked") MapReduceValuesToLongTask<K,V>
5697 t = (MapReduceValuesToLongTask<K,V>)c,
5698 s = t.rights;
5699 while (s != null) {
5700 t.result = reducer.apply(t.result, s.result);
5701 s = t.rights = s.nextRight;
5702 }
5703 }
5704 }
5705 }
5706 }
5707
5708 @SuppressWarnings("serial")
5709 static final class MapReduceEntriesToLongTask<K,V>
5710 extends BulkTask<K,V,Long> {
5711 final ObjectToLong<Map.Entry<K,V>> transformer;
5712 final LongByLongToLong reducer;
5713 final long basis;
5714 long result;
5715 MapReduceEntriesToLongTask<K,V> rights, nextRight;
5716 MapReduceEntriesToLongTask
5717 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5718 MapReduceEntriesToLongTask<K,V> nextRight,
5719 ObjectToLong<Map.Entry<K,V>> transformer,
5720 long basis,
5721 LongByLongToLong reducer) {
5722 super(p, b, i, f, t); this.nextRight = nextRight;
5723 this.transformer = transformer;
5724 this.basis = basis; this.reducer = reducer;
5725 }
5726 public final Long getRawResult() { return result; }
5727 public final void compute() {
5728 final ObjectToLong<Map.Entry<K,V>> transformer;
5729 final LongByLongToLong reducer;
5730 if ((transformer = this.transformer) != null &&
5731 (reducer = this.reducer) != null) {
5732 long r = this.basis;
5733 for (int i = baseIndex, f, h; batch > 0 &&
5734 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5735 addToPendingCount(1);
5736 (rights = new MapReduceEntriesToLongTask<K,V>
5737 (this, batch >>>= 1, baseLimit = h, f, tab,
5738 rights, transformer, r, reducer)).fork();
5739 }
5740 for (Node<K,V> p; (p = advance()) != null; )
5741 r = reducer.apply(r, transformer.apply(p));
5742 result = r;
5743 CountedCompleter<?> c;
5744 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5745 @SuppressWarnings("unchecked") MapReduceEntriesToLongTask<K,V>
5746 t = (MapReduceEntriesToLongTask<K,V>)c,
5747 s = t.rights;
5748 while (s != null) {
5749 t.result = reducer.apply(t.result, s.result);
5750 s = t.rights = s.nextRight;
5751 }
5752 }
5753 }
5754 }
5755 }
5756
5757 @SuppressWarnings("serial")
5758 static final class MapReduceMappingsToLongTask<K,V>
5759 extends BulkTask<K,V,Long> {
5760 final ObjectByObjectToLong<? super K, ? super V> transformer;
5761 final LongByLongToLong reducer;
5762 final long basis;
5763 long result;
5764 MapReduceMappingsToLongTask<K,V> rights, nextRight;
5765 MapReduceMappingsToLongTask
5766 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5767 MapReduceMappingsToLongTask<K,V> nextRight,
5768 ObjectByObjectToLong<? super K, ? super V> transformer,
5769 long basis,
5770 LongByLongToLong reducer) {
5771 super(p, b, i, f, t); this.nextRight = nextRight;
5772 this.transformer = transformer;
5773 this.basis = basis; this.reducer = reducer;
5774 }
5775 public final Long getRawResult() { return result; }
5776 public final void compute() {
5777 final ObjectByObjectToLong<? super K, ? super V> transformer;
5778 final LongByLongToLong reducer;
5779 if ((transformer = this.transformer) != null &&
5780 (reducer = this.reducer) != null) {
5781 long r = this.basis;
5782 for (int i = baseIndex, f, h; batch > 0 &&
5783 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5784 addToPendingCount(1);
5785 (rights = new MapReduceMappingsToLongTask<K,V>
5786 (this, batch >>>= 1, baseLimit = h, f, tab,
5787 rights, transformer, r, reducer)).fork();
5788 }
5789 for (Node<K,V> p; (p = advance()) != null; )
5790 r = reducer.apply(r, transformer.apply(p.key, p.val));
5791 result = r;
5792 CountedCompleter<?> c;
5793 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5794 @SuppressWarnings("unchecked") MapReduceMappingsToLongTask<K,V>
5795 t = (MapReduceMappingsToLongTask<K,V>)c,
5796 s = t.rights;
5797 while (s != null) {
5798 t.result = reducer.apply(t.result, s.result);
5799 s = t.rights = s.nextRight;
5800 }
5801 }
5802 }
5803 }
5804 }
5805
5806 @SuppressWarnings("serial")
5807 static final class MapReduceKeysToIntTask<K,V>
5808 extends BulkTask<K,V,Integer> {
5809 final ObjectToInt<? super K> transformer;
5810 final IntByIntToInt reducer;
5811 final int basis;
5812 int result;
5813 MapReduceKeysToIntTask<K,V> rights, nextRight;
5814 MapReduceKeysToIntTask
5815 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5816 MapReduceKeysToIntTask<K,V> nextRight,
5817 ObjectToInt<? super K> transformer,
5818 int basis,
5819 IntByIntToInt reducer) {
5820 super(p, b, i, f, t); this.nextRight = nextRight;
5821 this.transformer = transformer;
5822 this.basis = basis; this.reducer = reducer;
5823 }
5824 public final Integer getRawResult() { return result; }
5825 public final void compute() {
5826 final ObjectToInt<? super K> transformer;
5827 final IntByIntToInt reducer;
5828 if ((transformer = this.transformer) != null &&
5829 (reducer = this.reducer) != null) {
5830 int r = this.basis;
5831 for (int i = baseIndex, f, h; batch > 0 &&
5832 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5833 addToPendingCount(1);
5834 (rights = new MapReduceKeysToIntTask<K,V>
5835 (this, batch >>>= 1, baseLimit = h, f, tab,
5836 rights, transformer, r, reducer)).fork();
5837 }
5838 for (Node<K,V> p; (p = advance()) != null; )
5839 r = reducer.apply(r, transformer.apply(p.key));
5840 result = r;
5841 CountedCompleter<?> c;
5842 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5843 @SuppressWarnings("unchecked") MapReduceKeysToIntTask<K,V>
5844 t = (MapReduceKeysToIntTask<K,V>)c,
5845 s = t.rights;
5846 while (s != null) {
5847 t.result = reducer.apply(t.result, s.result);
5848 s = t.rights = s.nextRight;
5849 }
5850 }
5851 }
5852 }
5853 }
5854
5855 @SuppressWarnings("serial")
5856 static final class MapReduceValuesToIntTask<K,V>
5857 extends BulkTask<K,V,Integer> {
5858 final ObjectToInt<? super V> transformer;
5859 final IntByIntToInt reducer;
5860 final int basis;
5861 int result;
5862 MapReduceValuesToIntTask<K,V> rights, nextRight;
5863 MapReduceValuesToIntTask
5864 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5865 MapReduceValuesToIntTask<K,V> nextRight,
5866 ObjectToInt<? super V> transformer,
5867 int basis,
5868 IntByIntToInt reducer) {
5869 super(p, b, i, f, t); this.nextRight = nextRight;
5870 this.transformer = transformer;
5871 this.basis = basis; this.reducer = reducer;
5872 }
5873 public final Integer getRawResult() { return result; }
5874 public final void compute() {
5875 final ObjectToInt<? super V> transformer;
5876 final IntByIntToInt reducer;
5877 if ((transformer = this.transformer) != null &&
5878 (reducer = this.reducer) != null) {
5879 int r = this.basis;
5880 for (int i = baseIndex, f, h; batch > 0 &&
5881 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5882 addToPendingCount(1);
5883 (rights = new MapReduceValuesToIntTask<K,V>
5884 (this, batch >>>= 1, baseLimit = h, f, tab,
5885 rights, transformer, r, reducer)).fork();
5886 }
5887 for (Node<K,V> p; (p = advance()) != null; )
5888 r = reducer.apply(r, transformer.apply(p.val));
5889 result = r;
5890 CountedCompleter<?> c;
5891 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5892 @SuppressWarnings("unchecked") MapReduceValuesToIntTask<K,V>
5893 t = (MapReduceValuesToIntTask<K,V>)c,
5894 s = t.rights;
5895 while (s != null) {
5896 t.result = reducer.apply(t.result, s.result);
5897 s = t.rights = s.nextRight;
5898 }
5899 }
5900 }
5901 }
5902 }
5903
5904 @SuppressWarnings("serial")
5905 static final class MapReduceEntriesToIntTask<K,V>
5906 extends BulkTask<K,V,Integer> {
5907 final ObjectToInt<Map.Entry<K,V>> transformer;
5908 final IntByIntToInt reducer;
5909 final int basis;
5910 int result;
5911 MapReduceEntriesToIntTask<K,V> rights, nextRight;
5912 MapReduceEntriesToIntTask
5913 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5914 MapReduceEntriesToIntTask<K,V> nextRight,
5915 ObjectToInt<Map.Entry<K,V>> transformer,
5916 int basis,
5917 IntByIntToInt reducer) {
5918 super(p, b, i, f, t); this.nextRight = nextRight;
5919 this.transformer = transformer;
5920 this.basis = basis; this.reducer = reducer;
5921 }
5922 public final Integer getRawResult() { return result; }
5923 public final void compute() {
5924 final ObjectToInt<Map.Entry<K,V>> transformer;
5925 final IntByIntToInt reducer;
5926 if ((transformer = this.transformer) != null &&
5927 (reducer = this.reducer) != null) {
5928 int r = this.basis;
5929 for (int i = baseIndex, f, h; batch > 0 &&
5930 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5931 addToPendingCount(1);
5932 (rights = new MapReduceEntriesToIntTask<K,V>
5933 (this, batch >>>= 1, baseLimit = h, f, tab,
5934 rights, transformer, r, reducer)).fork();
5935 }
5936 for (Node<K,V> p; (p = advance()) != null; )
5937 r = reducer.apply(r, transformer.apply(p));
5938 result = r;
5939 CountedCompleter<?> c;
5940 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5941 @SuppressWarnings("unchecked") MapReduceEntriesToIntTask<K,V>
5942 t = (MapReduceEntriesToIntTask<K,V>)c,
5943 s = t.rights;
5944 while (s != null) {
5945 t.result = reducer.apply(t.result, s.result);
5946 s = t.rights = s.nextRight;
5947 }
5948 }
5949 }
5950 }
5951 }
5952
5953 @SuppressWarnings("serial")
5954 static final class MapReduceMappingsToIntTask<K,V>
5955 extends BulkTask<K,V,Integer> {
5956 final ObjectByObjectToInt<? super K, ? super V> transformer;
5957 final IntByIntToInt reducer;
5958 final int basis;
5959 int result;
5960 MapReduceMappingsToIntTask<K,V> rights, nextRight;
5961 MapReduceMappingsToIntTask
5962 (BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
5963 MapReduceMappingsToIntTask<K,V> nextRight,
5964 ObjectByObjectToInt<? super K, ? super V> transformer,
5965 int basis,
5966 IntByIntToInt reducer) {
5967 super(p, b, i, f, t); this.nextRight = nextRight;
5968 this.transformer = transformer;
5969 this.basis = basis; this.reducer = reducer;
5970 }
5971 public final Integer getRawResult() { return result; }
5972 public final void compute() {
5973 final ObjectByObjectToInt<? super K, ? super V> transformer;
5974 final IntByIntToInt reducer;
5975 if ((transformer = this.transformer) != null &&
5976 (reducer = this.reducer) != null) {
5977 int r = this.basis;
5978 for (int i = baseIndex, f, h; batch > 0 &&
5979 (h = ((f = baseLimit) + i) >>> 1) > i;) {
5980 addToPendingCount(1);
5981 (rights = new MapReduceMappingsToIntTask<K,V>
5982 (this, batch >>>= 1, baseLimit = h, f, tab,
5983 rights, transformer, r, reducer)).fork();
5984 }
5985 for (Node<K,V> p; (p = advance()) != null; )
5986 r = reducer.apply(r, transformer.apply(p.key, p.val));
5987 result = r;
5988 CountedCompleter<?> c;
5989 for (c = firstComplete(); c != null; c = c.nextComplete()) {
5990 @SuppressWarnings("unchecked") MapReduceMappingsToIntTask<K,V>
5991 t = (MapReduceMappingsToIntTask<K,V>)c,
5992 s = t.rights;
5993 while (s != null) {
5994 t.result = reducer.apply(t.result, s.result);
5995 s = t.rights = s.nextRight;
5996 }
5997 }
5998 }
5999 }
6000 }
6001
6002
6003
6004
6005
6006
6007
6008 static final class CounterCell {
6009 volatile long p0, p1, p2, p3, p4, p5, p6;
6010 volatile long value;
6011 volatile long q0, q1, q2, q3, q4, q5, q6;
6012 CounterCell(long x) { value = x; }
6013 }
6014
6015
6016
6017
6018
6019
6020 static final class CounterHashCode {
6021 int code;
6022 }
6023
6024
6025
6026
6027 static final AtomicInteger counterHashCodeGenerator = new AtomicInteger();
6028
6029
6030
6031
6032
6033 static final int SEED_INCREMENT = 0x61c88647;
6034
6035 final long sumCount() {
6036 CounterCell[] as = counterCells; CounterCell a;
6037 long sum = baseCount;
6038 if (as != null) {
6039 for (int i = 0; i < as.length; ++i) {
6040 if ((a = as[i]) != null)
6041 sum += a.value;
6042 }
6043 }
6044 return sum;
6045 }
6046
6047
6048 private final void fullAddCount(InternalThreadLocalMap threadLocals,
6049 long x, IntegerHolder hc,
6050 boolean wasUncontended) {
6051 int h;
6052 if (hc == null) {
6053 hc = new IntegerHolder();
6054 int s = counterHashCodeGenerator.addAndGet(SEED_INCREMENT);
6055 h = hc.value = (s == 0) ? 1 : s;
6056 threadLocals.setCounterHashCode(hc);
6057 }
6058 else
6059 h = hc.value;
6060 boolean collide = false;
6061 for (;;) {
6062 CounterCell[] as; CounterCell a; int n; long v;
6063 if ((as = counterCells) != null && (n = as.length) > 0) {
6064 if ((a = as[(n - 1) & h]) == null) {
6065 if (cellsBusy == 0) {
6066 CounterCell r = new CounterCell(x);
6067 if (cellsBusy == 0 &&
6068 U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
6069 boolean created = false;
6070 try {
6071 CounterCell[] rs; int m, j;
6072 if ((rs = counterCells) != null &&
6073 (m = rs.length) > 0 &&
6074 rs[j = (m - 1) & h] == null) {
6075 rs[j] = r;
6076 created = true;
6077 }
6078 } finally {
6079 cellsBusy = 0;
6080 }
6081 if (created)
6082 break;
6083 continue;
6084 }
6085 }
6086 collide = false;
6087 }
6088 else if (!wasUncontended)
6089 wasUncontended = true;
6090 else if (U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))
6091 break;
6092 else if (counterCells != as || n >= NCPU)
6093 collide = false;
6094 else if (!collide)
6095 collide = true;
6096 else if (cellsBusy == 0 &&
6097 U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
6098 try {
6099 if (counterCells == as) {
6100 CounterCell[] rs = new CounterCell[n << 1];
6101 for (int i = 0; i < n; ++i)
6102 rs[i] = as[i];
6103 counterCells = rs;
6104 }
6105 } finally {
6106 cellsBusy = 0;
6107 }
6108 collide = false;
6109 continue;
6110 }
6111 h ^= h << 13;
6112 h ^= h >>> 17;
6113 h ^= h << 5;
6114 }
6115 else if (cellsBusy == 0 && counterCells == as &&
6116 U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
6117 boolean init = false;
6118 try {
6119 if (counterCells == as) {
6120 CounterCell[] rs = new CounterCell[2];
6121 rs[h & 1] = new CounterCell(x);
6122 counterCells = rs;
6123 init = true;
6124 }
6125 } finally {
6126 cellsBusy = 0;
6127 }
6128 if (init)
6129 break;
6130 }
6131 else if (U.compareAndSwapLong(this, BASECOUNT, v = baseCount, v + x))
6132 break;
6133 }
6134 hc.value = h;
6135 }
6136
6137
6138 private static final sun.misc.Unsafe U;
6139 private static final long SIZECTL;
6140 private static final long TRANSFERINDEX;
6141 private static final long TRANSFERORIGIN;
6142 private static final long BASECOUNT;
6143 private static final long CELLSBUSY;
6144 private static final long CELLVALUE;
6145 private static final long ABASE;
6146 private static final int ASHIFT;
6147
6148 static {
6149 try {
6150 U = getUnsafe();
6151 Class<?> k = ConcurrentHashMapV8.class;
6152 SIZECTL = U.objectFieldOffset
6153 (k.getDeclaredField("sizeCtl"));
6154 TRANSFERINDEX = U.objectFieldOffset
6155 (k.getDeclaredField("transferIndex"));
6156 TRANSFERORIGIN = U.objectFieldOffset
6157 (k.getDeclaredField("transferOrigin"));
6158 BASECOUNT = U.objectFieldOffset
6159 (k.getDeclaredField("baseCount"));
6160 CELLSBUSY = U.objectFieldOffset
6161 (k.getDeclaredField("cellsBusy"));
6162 Class<?> ck = CounterCell.class;
6163 CELLVALUE = U.objectFieldOffset
6164 (ck.getDeclaredField("value"));
6165 Class<?> ak = Node[].class;
6166 ABASE = U.arrayBaseOffset(ak);
6167 int scale = U.arrayIndexScale(ak);
6168 if ((scale & (scale - 1)) != 0)
6169 throw new Error("data type scale not a power of two");
6170 ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
6171 } catch (Exception e) {
6172 throw new Error(e);
6173 }
6174 }
6175
6176
6177
6178
6179
6180
6181
6182
6183 private static sun.misc.Unsafe getUnsafe() {
6184 try {
6185 return sun.misc.Unsafe.getUnsafe();
6186 } catch (SecurityException tryReflectionInstead) {}
6187 try {
6188 return java.security.AccessController.doPrivileged
6189 (new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() {
6190 public sun.misc.Unsafe run() throws Exception {
6191 Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
6192 for (java.lang.reflect.Field f : k.getDeclaredFields()) {
6193 f.setAccessible(true);
6194 Object x = f.get(null);
6195 if (k.isInstance(x))
6196 return k.cast(x);
6197 }
6198 throw new NoSuchFieldError("the Unsafe");
6199 }});
6200 } catch (java.security.PrivilegedActionException e) {
6201 throw new RuntimeException("Could not initialize intrinsics",
6202 e.getCause());
6203 }
6204 }
6205 }