1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 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
   | private final void transfer(Node<K,V>[] tab, Node<K,V>[] nextTab) {                                    int n = tab.length, stride;          if ((stride = (NCPU > 1) ? (n >>> 3) / NCPU : n) < MIN_TRANSFER_STRIDE)           stride = MIN_TRANSFER_STRIDE;             if (nextTab == null) {                                                                                 try {               @SuppressWarnings("unchecked")                            Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n << 1];                                               nextTab = nt;           } catch (Throwable ex) {                                  sizeCtl = Integer.MAX_VALUE;               return;                                                                                        }           nextTable = nextTab;                    transferIndex = n;                                                                             }          int nextn = nextTab.length;          ForwardingNode<K,V> fwd = new ForwardingNode<K,V>(nextTab);                 boolean advance = true;             boolean finishing = false;           for (int i = 0, bound = 0;;) {           Node<K,V> f; int fh;                    while (advance) {                                                                                      int nextIndex, nextBound;                            if (--i >= bound || finishing)                                                                         advance = false;                            else if ((nextIndex = transferIndex) <= 0) {                                                           i = -1;                   advance = false;               }                            else if (U.compareAndSwapInt                        (this, TRANSFERINDEX, nextIndex,                                                                    nextBound = (nextIndex > stride ?                                                                               nextIndex - stride : 0))) {                                    bound = nextBound;                   i = nextIndex - 1;                                                                                 advance = false;               }           }                                                                                                  if (i < 0 || i >= n || i + n >= nextn) {               int sc;               if (finishing) {                                                                                       nextTable = null;                   table = nextTab;                                    sizeCtl = (n << 1) - (n >>> 1);                                                                    return;               }                            if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, sc - 1)) {                                    if ((sc - 2) != resizeStamp(n) << RESIZE_STAMP_SHIFT)                                                  return;                   finishing = advance = true;                   i = n;                }           }           else if ((f = tabAt(tab, i)) == null)                                                              advance = casTabAt(tab, i, null, fwd);           else if ((fh = f.hash) == MOVED)                                                                   advance = true;            else {               synchronized (f) {                                                                                 if (tabAt(tab, i) == f) {                                                                          Node<K,V> ln, hn;                       if (fh >= 0) {                                                                                     int runBit = fh & n;                                                                           Node<K,V> lastRun = f;                                                                         for (Node<K,V> p = f.next; p != null; p = p.next) {                               int b = p.hash & n;                               if (b != runBit) {                                   runBit = b;                                   lastRun = p;                               }                           }                           if (runBit == 0) {                                                                                 ln = lastRun;                               hn = null;                           }                           else {                               hn = lastRun;                               ln = null;                           }                           for (Node<K,V> p = f; p != lastRun; p = p.next) {                               int ph = p.hash; K pk = p.key; V pv = p.val;                               if ((ph & n) == 0)                                                                                 ln = new Node<K,V>(ph, pk, pv, ln);                               else                                   hn = new Node<K,V>(ph, pk, pv, hn);                           }                           setTabAt(nextTab, i, ln);                                                                      setTabAt(nextTab, i + n, hn);                           setTabAt(tab, i, fwd);                                                                         advance = true;                                                                            }                       else if (f instanceof TreeBin) {                                                                   TreeBin<K,V> t = (TreeBin<K,V>)f;                           TreeNode<K,V> lo = null, loTail = null;                           TreeNode<K,V> hi = null, hiTail = null;                           int lc = 0, hc = 0;                           for (Node<K,V> e = t.first; e != null; e = e.next) {                                               int h = e.hash;                               TreeNode<K,V> p = new TreeNode<K,V>                                   (h, e.key, e.val, null, null);                               if ((h & n) == 0) {                                   if ((p.prev = loTail) == null)                                       lo = p;                                   else                                       loTail.next = p;                                   loTail = p;                                   ++lc;                               }                               else {                                   if ((p.prev = hiTail) == null)                                       hi = p;                                   else                                       hiTail.next = p;                                   hiTail = p;                                   ++hc;                               }                           }                           ln = (lc <= UNTREEIFY_THRESHOLD) ? untreeify(lo) :                                             (hc != 0) ? new TreeBin<K,V>(lo) : t;                                                  hn = (hc <= UNTREEIFY_THRESHOLD) ? untreeify(hi) :                               (lc != 0) ? new TreeBin<K,V>(hi) : t;                           setTabAt(nextTab, i, ln);                           setTabAt(nextTab, i + n, hn);                           setTabAt(tab, i, fwd);                           advance = true;                       }                   }               }           }       }   }
  |