static Node safeNext(Node b) { while (true) { Node n = b.next; if (n == null) return null; n.incRefCnt(); if (n == b.next) return n; else release(n); } }
public void found(Node n) { n.incRefCnt(); }
// only used by putAtomic and PutAtomicIfAbsent. Inside synchronized(b) and synchronized(this). private void putAtomicReally( Node b, int pos, double key, Object value, ConcurrentDoubleOrderedListMap orderedMap) { int len = len(); if (len + 1 <= keys.length) { if (pos == len) { // in-place append in the current node keys[pos] = key; vals[pos] = value; length = len + 1; if (pos == 0) { orderedMap.skipListMap.put(keys[0], this); } } else { // copied to a new node, replacing the current node mark(); Node n = Node.alloc(); n.next = this.next; if (next != null) next.incRefCnt(); double[] nkeys = n.keys; Object[] nvals = n.vals; n.length = len + 1; nodeCopy(keys, vals, 0, nkeys, nvals, 0, pos); nkeys[pos] = key; nvals[pos] = value; nodeCopy(keys, vals, pos, nkeys, nvals, pos + 1, len - pos); orderedMap.skipListMap.put(nkeys[0], n); b.casNext(this, n); // should always succeed. if (pos == 0) { orderedMap.skipListMap.remove(keys[0], this); } release(this); free(this); } } else { // requires 2 new nodes, to replace the current node mark(); Node n1 = Node.alloc(); double[] n1keys = n1.keys; Object[] n1vals = n1.vals; Node n2 = Node.alloc(); double[] n2keys = n2.keys; Object[] n2vals = n2.vals; int l1 = len / 2, l2 = len - l1; if (pos < l1) { // key, value stored in n1 n1.length = l1 + 1; n2.length = l2; nodeCopy(keys, vals, 0, n1keys, n1vals, 0, pos); n1keys[pos] = key; n1vals[pos] = value; nodeCopy(keys, vals, pos, n1keys, n1vals, pos + 1, l1 - pos); nodeCopy(keys, vals, l1, n2keys, n2vals, 0, l2); n1.next = n2; n2.next = this.next; if (next != null) next.incRefCnt(); orderedMap.skipListMap.put(n1keys[0], n1); orderedMap.skipListMap.put(n2keys[0], n2); b.casNext(this, n1); // should always succeed. if (pos == 0) { orderedMap.skipListMap.remove(keys[0], this); } release(this); free(this); } else { // key,value is stored in n2 n1.length = l1; n2.length = l2 + 1; int newpos = pos - l1; nodeCopy(keys, vals, 0, n1keys, n1vals, 0, l1); nodeCopy(keys, vals, l1, n2keys, n2vals, 0, newpos); n2keys[newpos] = key; n2vals[newpos] = value; nodeCopy(keys, vals, pos, n2keys, n2vals, newpos + 1, l2 - newpos); n1.next = n2; n2.next = this.next; if (next != null) next.incRefCnt(); orderedMap.skipListMap.put(n1keys[0], n1); orderedMap.skipListMap.put(n2keys[0], n2); b.casNext(this, n1); // should always succeed. release(this); free(this); } } }