static final Object KEY_PRESENT = new Object ();
static final Object KEY_ABSENT = new Object ();
+ /**
+ * Virtual result for lookup methods indicating that the lookup needs to be restarted. This is a faster version
+ * of throwing a checked exception to control the restart.
+ */
+ static final Object RESTART = new Object();
+
static <K,V> INode<K,V> newRootNode() {
Gen gen = new Gen ();
CNode<K, V> cn = new CNode<> (0, new BasicNode[] {}, gen);
- return new INode<>(cn, gen);
- }
-
- private INode(final MainNode<K, V> bn, final Gen g) {
- super(g);
- WRITE(bn);
- }
-
- INode(final Gen g) {
- this(null, g);
- }
-
- void WRITE(final MainNode<K, V> nval) {
- INodeBase.updater.set(this, nval);
+ return new INode<>(gen, cn);
}
- boolean CAS(final MainNode<K, V> old, final MainNode<K, V> n) {
- return INodeBase.updater.compareAndSet(this, old, n);
+ INode(final Gen gen, final MainNode<K, V> bn) {
+ super(gen, bn);
}
MainNode<K, V> gcasRead(final TrieMap<K, V> ct) {
}
MainNode<K, V> GCAS_READ(final TrieMap<K, V> ct) {
- MainNode<K, V> m = /* READ */mainnode;
+ MainNode<K, V> m = /* READ */ READ();
MainNode<K, V> prevval = /* READ */ m.READ_PREV();
if (prevval == null) {
return m;
} else {
// Tailrec
// return GCAS_Complete (/* READ */mainnode, ct);
- m = /* READ */mainnode;
+ m = /* READ */ READ();
continue;
}
} else if (prev instanceof MainNode) {
} else {
// try to abort
m.CAS_PREV(prev, new FailedNode<>(prev));
- return GCAS_Complete(/* READ */mainnode, ct);
+ return GCAS_Complete(/* READ */ READ(), ct);
}
}
}
}
private INode<K, V> inode(final MainNode<K, V> cn) {
- INode<K, V> nin = new INode<>(gen);
- nin.WRITE(cn);
- return nin;
+ return new INode<>(gen, cn);
}
INode<K, V> copyToGen(final Gen ngen, final TrieMap<K, V> ct) {
- INode<K, V> nin = new INode<>(ngen);
- MainNode<K, V> main = GCAS_READ(ct);
- nin.WRITE(main);
- return nin;
+ return new INode<>(ngen, GCAS_READ(ct));
}
/**
// Tailrec
continue;
} else {
- return RESTART; // used to be throw
- // RestartException
+ return RESTART; // used to be throw RestartException
}
}
} else if (sub instanceof SNode) {
abstract class INodeBase<K, V> extends BasicNode {
- public static final AtomicReferenceFieldUpdater<INodeBase, MainNode> updater = AtomicReferenceFieldUpdater.newUpdater(INodeBase.class, MainNode.class, "mainnode");
-
- public static final Object RESTART = new Object();
-
- public volatile MainNode<K, V> mainnode = null;
+ @SuppressWarnings("rawtypes")
+ private static final AtomicReferenceFieldUpdater<INodeBase, MainNode> MAINNODE_UPDATER =
+ AtomicReferenceFieldUpdater.newUpdater(INodeBase.class, MainNode.class, "mainnode");
public final Gen gen;
- public INodeBase(final Gen generation) {
- gen = generation;
+ private volatile MainNode<K, V> mainnode;
+
+ INodeBase(final Gen generation, final MainNode<K, V> mainnode) {
+ gen = generation;
+ this.mainnode = mainnode;
}
- public BasicNode prev() {
- return null;
+ final boolean CAS(final MainNode<K, V> old, final MainNode<K, V> n) {
+ return MAINNODE_UPDATER.compareAndSet(this, old, n);
}
-}
\ No newline at end of file
+ final MainNode<K, V> READ() {
+ return mainnode;
+ }
+}
}
}
- private Object lookuphc (final K k, final int hc) {
+ private Object lookuphc(final K k, final int hc) {
while (true) {
- INode<K, V> r = RDCSS_READ_ROOT ();
- Object res = r.rec_lookup (k, hc, 0, null, r.gen, this);
- if (res == INodeBase.RESTART) {
- // return lookuphc (k, hc);
- // tailrec
- continue;
- } else {
+ final INode<K, V> r = RDCSS_READ_ROOT ();
+ final Object res = r.rec_lookup(k, hc, 0, null, r.gen, this);
+ if (!INode.RESTART.equals(res)) {
return res;
}
+
+ // Tail recursion: lookuphc(k, hc)
}
}