// no concurrent read/write is assumed public V put(double key, V value) { if (value == null) throw new NullPointerException(); // not incrementing b's refcnt, so need not release it. Node b = skipListMap.findGrandPredecessor(key); if (b == null) b = head; Node n = b.next; if (n == null) { n = Node.alloc(); n.put(key, value, this); n.next = null; b.next = n; return null; } Node f = n.next; if (f == null) { // put (key,value) into node n Object val = n.put(key, value, this); return (V) val; } else { assert f.len() > 0 && f.first() >= key; if (f.first() == key) { Object val = f.put(key, value, this); return (V) val; } else { Object val = n.put(key, value, this); return (V) val; } } }
// concurrent read/write access is allowed boolean appendNewAtomic(double key, Object value, ConcurrentDoubleOrderedListMap orderedMap) { synchronized (this) { if (isMarked()) return false; if (next != null) return false; Node n = Node.alloc(); n.put(key, value, orderedMap); // assert n.len()==1; n.next = null; boolean success = casNext(null, n); assert success; return true; } }
// no concurrent read/write access is assumed private void putReally( int pos, double key, Object value, ConcurrentDoubleOrderedListMap orderedMap) { int len = len(); if (len + 1 <= keys.length) { // inserted in the current node nodeCopy(keys, vals, pos, keys, vals, pos + 1, len - pos); keys[pos] = key; vals[pos] = value; length = len + 1; if (pos == 0) { orderedMap.skipListMap.put(keys[0], this); if (len != 0) orderedMap.skipListMap.remove(keys[1], this); } } else if (emptySlotInNextTwo()) { if (pos == len) { next.put(key, value, orderedMap); return; } next.put(keys[len - 1], vals[len - 1], orderedMap); nodeCopy(keys, vals, pos, keys, vals, pos + 1, len - pos - 1); keys[pos] = key; vals[pos] = value; if (pos == 0) { orderedMap.skipListMap.remove(keys[1], this); orderedMap.skipListMap.put(keys[0], this); } } else { // current node is full, so requires a new node Node n = Node.alloc(); double[] nkeys = n.keys; Object[] nvals = n.vals; int l1 = len / 2, l2 = len - l1; if (next == null && pos == len) { // this is the last node, simply add to the new node. nkeys[0] = key; nvals[0] = value; n.length = 1; orderedMap.skipListMap.put(nkeys[0], n); } else if (pos < l1) { // key,value is stored in the current node length = l1 + 1; n.length = l2; nodeCopy(keys, vals, l1, nkeys, nvals, 0, l2); nodeCopy(keys, vals, pos, keys, vals, pos + 1, l1 - pos); keys[pos] = key; vals[pos] = value; if (pos == 0) { orderedMap.skipListMap.remove(keys[1]); orderedMap.skipListMap.put(keys[0], this); } orderedMap.skipListMap.put(nkeys[0], n); } else { // key,value is stored in the new node length = l1; n.length = l2 + 1; int newpos = pos - l1; nodeCopy(keys, vals, l1, nkeys, nvals, 0, newpos); nkeys[newpos] = key; nvals[newpos] = value; nodeCopy(keys, vals, pos, nkeys, nvals, newpos + 1, l2 - newpos); orderedMap.skipListMap.put(nkeys[0], n); } n.next = this.next; this.next = n; } }