Skip to content

Commit 7ff546a

Browse files
committed
Improve calling TrieMap calling convention
Rather than passing as the last argument, always pass it as the first, making for more navigable code. Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
1 parent 7c7926d commit 7ff546a

File tree

5 files changed

+36
-34
lines changed

5 files changed

+36
-34
lines changed

triemap/src/main/java/tech/pantheon/triemap/CNode.java

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -144,19 +144,19 @@ boolean insert(final MutableTrieMap<K, V> ct, final INode<K, V> in, final int po
144144
final K key, final V val, final int hc, final int lev) {
145145
final CNode<K, V> next;
146146
if (!sn.matches(hc, key)) {
147-
final var rn = gen == in.gen ? this : renewed(gen, ct);
147+
final var rn = gen == in.gen ? this : renewed(ct, gen);
148148
next = rn.updatedAt(pos, new INode<>(in, sn, key, val, hc, lev), gen);
149149
} else {
150150
next = updatedAt(pos, key, val, hc, gen);
151151
}
152-
return in.gcasWrite(next, ct);
152+
return in.gcasWrite(ct, next);
153153
}
154154

155155
boolean insert(final MutableTrieMap<K, V> ct, final INode<K, V> in, final int pos, final int flag, final K key,
156156
final V val, final int hc) {
157157
final var ngen = in.gen;
158-
final var rn = gen == ngen ? this : renewed(ngen, ct);
159-
return in.gcasWrite(rn.toInsertedAt(this, ngen, pos, flag, key, val, hc), ct);
158+
final var rn = gen == ngen ? this : renewed(ct, ngen);
159+
return in.gcasWrite(ct, rn.toInsertedAt(this, ngen, pos, flag, key, val, hc));
160160
}
161161

162162
@Nullable Result<V> insertIf(final MutableTrieMap<K, V> ct, final Gen startGen, final int hc, final K key,
@@ -194,16 +194,16 @@ boolean insert(final MutableTrieMap<K, V> ct, final INode<K, V> in, final int po
194194
if (!sn.matches(hc, key)) {
195195
if (cond == null || cond == ABSENT) {
196196
final var ngen = in.gen;
197-
final var rn = gen == ngen ? this : renewed(ngen, ct);
198-
return in.gcasWrite(rn.toUpdatedAt(this, pos, new INode<>(in, sn, key, val, hc, lev), ngen), ct)
197+
final var rn = gen == ngen ? this : renewed(ct, ngen);
198+
return in.gcasWrite(ct, rn.toUpdatedAt(this, pos, new INode<>(in, sn, key, val, hc, lev), ngen))
199199
? Result.empty() : null;
200200
}
201201
return Result.empty();
202202
}
203203
if (cond == ABSENT) {
204204
return sn.toResult();
205205
} else if (cond == null || cond == PRESENT || cond.equals(sn.value())) {
206-
return in.gcasWrite(updatedAt(pos, key, val, hc, gen), ct) ? sn.toResult() : null;
206+
return in.gcasWrite(ct, updatedAt(pos, key, val, hc, gen)) ? sn.toResult() : null;
207207
}
208208
return Result.empty();
209209
}
@@ -226,7 +226,7 @@ boolean insert(final MutableTrieMap<K, V> ct, final INode<K, V> in, final int po
226226
if (!sn.matches(hc, key) || cond != null && !cond.equals(sn.value())) {
227227
return Result.empty();
228228
}
229-
return parent.gcasWrite(toRemoved(ct, flag, pos, lev), ct) ? sn.toResult() : null;
229+
return parent.gcasWrite(ct, toRemoved(ct, flag, pos, lev)) ? sn.toResult() : null;
230230
} else {
231231
throw invalidElement(sub);
232232
}
@@ -252,7 +252,7 @@ MainNode<K, V> toCompressed(final TrieMap<K, V> ct, final Gen ngen, final int le
252252
final var narr = newArray(len);
253253
for (int i = 0; i < len; i++) {
254254
final var tmp = arr[i];
255-
narr[i] = tmp instanceof INode<K, V> in ? resurrect(in, ct) : tmp;
255+
narr[i] = tmp instanceof INode<K, V> in ? in.resurrect(ct) : tmp;
256256
}
257257

258258
return toUpdated(ngen, lev, narr, bitmap);
@@ -275,7 +275,7 @@ private MainNode<K, V> toUpdated(final Gen ngen, final int lev, final Branch<K,
275275

276276
// tries to gcasWrite() a copy of this CNode renewed to ngen
277277
private boolean renew(final TrieMap<K, V> ct, final INode<K, V> in, final Gen ngen) {
278-
return in.gcasWrite(renewed(ngen, ct), ct);
278+
return in.gcasWrite(ct, renewed(ct, ngen));
279279
}
280280

281281
@Override
@@ -298,22 +298,22 @@ private int computeSize(final ImmutableTrieMap<?, ?> ct) {
298298
final int len = array.length;
299299
return switch (len) {
300300
case 0 -> 0;
301-
case 1 -> elementSize(array[0], ct);
301+
case 1 -> elementSize(ct, array[0]);
302302
default -> {
303303
final int offset = ThreadLocalRandom.current().nextInt(len);
304304
int sz = 0;
305305
for (int i = offset; i < len; ++i) {
306-
sz += elementSize(array[i], ct);
306+
sz += elementSize(ct, array[i]);
307307
}
308308
for (int i = 0; i < offset; ++i) {
309-
sz += elementSize(array[i], ct);
309+
sz += elementSize(ct, array[i]);
310310
}
311311
yield sz;
312312
}
313313
};
314314
}
315315

316-
private static int elementSize(final Branch<?, ?> elem, final ImmutableTrieMap<?, ?> ct) {
316+
private static int elementSize(final ImmutableTrieMap<?, ?> ct, final Branch<?, ?> elem) {
317317
if (elem instanceof SNode) {
318318
return 1;
319319
} else if (elem instanceof INode<?, ?> inode) {
@@ -353,13 +353,13 @@ private CNode<K, V> toUpdatedAt(final CNode<K, V> prev, final int pos, final Bra
353353
* Returns a copy of this cnode such that all the i-nodes below it are copied to the specified generation
354354
* {@code ngen}.
355355
*/
356-
private CNode<K, V> renewed(final Gen ngen, final TrieMap<K, V> ct) {
356+
private CNode<K, V> renewed(final TrieMap<K, V> ct, final Gen ngen) {
357357
final var arr = array;
358358
final int len = arr.length;
359359
final var narr = newArray(len);
360360
for (int i = 0; i < len; i++) {
361361
final var tmp = arr[i];
362-
narr[i] = tmp instanceof INode<K, V> in ? in.copyToGen(ngen, ct) : tmp;
362+
narr[i] = tmp instanceof INode<K, V> in ? in.copyToGen(ct, ngen) : tmp;
363363
}
364364
return new CNode<>(this, ngen, bitmap, narr);
365365
}
@@ -374,10 +374,6 @@ private Branch<K, V>[] newArray(final int size) {
374374
return new Branch[size];
375375
}
376376

377-
private static <K, V> Branch<K, V> resurrect(final INode<K, V> in, final TrieMap<K, V> ct) {
378-
return in.gcasReadNonNull(ct) instanceof TNode<K, V> tn ? new SNode<>(tn) : in;
379-
}
380-
381377
// Visible for testing
382378
static VerifyException invalidElement(final Branch<?, ?> elem) {
383379
throw new VerifyException("A CNode can contain only INodes and SNodes, not " + elem);

triemap/src/main/java/tech/pantheon/triemap/INode.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -128,20 +128,20 @@ private TryGcas(final Gcas<K, V> prev) {
128128
}
129129

130130
MainNode<K, V> gcasRead(final TrieMap<?, ?> ct) {
131-
return gcasComplete((MainNode<K, V>) MAIN_VH.getVolatile(this), ct);
131+
return gcasComplete(ct, (MainNode<K, V>) MAIN_VH.getVolatile(this));
132132
}
133133

134-
boolean gcasWrite(final MainNode<K, V> next, final TrieMap<?, ?> ct) {
134+
boolean gcasWrite(final TrieMap<?, ?> ct, final MainNode<K, V> next) {
135135
// note: plain read of 'next', i.e. take a look at what we are about to CAS-out
136136
if (MAIN_VH.compareAndSet(this, VerifyException.throwIfNull(PREV_VH.get(next)), next)) {
137137
// established as write, now try to complete it and report if we have succeeded
138-
gcasComplete(next, ct);
138+
gcasComplete(ct, next);
139139
return PREV_VH.getVolatile(next) == null;
140140
}
141141
return false;
142142
}
143143

144-
private MainNode<K, V> gcasComplete(final MainNode<K, V> firstMain, final TrieMap<?, ?> ct) {
144+
private MainNode<K, V> gcasComplete(final TrieMap<?, ?> ct, final MainNode<K, V> firstMain) {
145145
// complete the GCAS starting at firstMain
146146
var currentMain = firstMain;
147147

@@ -211,7 +211,7 @@ private MainNode<K, V> gcasComplete(final MainNode<K, V> firstMain, final TrieMa
211211
}
212212
}
213213

214-
INode<K, V> copyToGen(final Gen ngen, final TrieMap<K, V> ct) {
214+
INode<K, V> copyToGen(final TrieMap<K, V> ct, final Gen ngen) {
215215
return new INode<>(ngen, gcasRead(ct));
216216
}
217217

@@ -329,10 +329,16 @@ boolean insert(final MutableTrieMap<K, V> ct, final Gen startGen, final int hc,
329329

330330
private void clean(final TrieMap<K, V> ct, final INode<K, V> parent, final int lev) {
331331
if (parent.gcasRead(ct) instanceof CNode<K, V> cn) {
332-
parent.gcasWrite(cn.toCompressed(ct, gen, lev - LEVEL_BITS), ct);
332+
parent.gcasWrite(ct, cn.toCompressed(ct, gen, lev - LEVEL_BITS));
333333
}
334334
}
335335

336+
// gcasRead() and if it is a TNode convert it to an SNode instead. Called indirectly via cn.toCompressed() from
337+
// clean() just above
338+
Branch<K, V> resurrect(final TrieMap<K, V> ct) {
339+
return gcasReadNonNull(ct) instanceof TNode<K, V> tn ? new SNode<>(tn) : this;
340+
}
341+
336342
private void cleanParent(final MutableTrieMap<K, V> ct, final Gen startGen, final int hc, final TNode<K, V> tn,
337343
final INode<K, V> parent, final int lev) {
338344
while (true) {
@@ -357,7 +363,7 @@ private void cleanParent(final MutableTrieMap<K, V> ct, final Gen startGen, fina
357363
}
358364

359365
// retry while we make progress and the tree is does not move to next generation
360-
if (parent.gcasWrite(cn.toContracted(gen, pos, tn, lev - LEVEL_BITS), ct)
366+
if (parent.gcasWrite(ct, cn.toContracted(gen, pos, tn, lev - LEVEL_BITS))
361367
|| ct.readRoot().gen != startGen) {
362368
return;
363369
}

triemap/src/main/java/tech/pantheon/triemap/ImmutableTrieMap.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public int size() {
109109

110110
@Override
111111
public MutableTrieMap<K, V> mutableSnapshot() {
112-
return new MutableTrieMap<>(root.copyToGen(new Gen(), this));
112+
return new MutableTrieMap<>(root.copyToGen(this, new Gen()));
113113
}
114114

115115
@Override

triemap/src/main/java/tech/pantheon/triemap/LNodeEntries.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,19 +86,19 @@ static <K,V> LNodeEntries<K, V> of(final K k1, final V v1, final K k2, final V v
8686
final boolean insert(final MutableTrieMap<K, V> ct, final INode<K, V> in, final LNode<K, V> ln, final K key,
8787
final V val) {
8888
final var entry = findEntry(key);
89-
return in.gcasWrite(entry == null ? toInserted(ln, key, val) : toReplaced(ln, entry, val), ct);
89+
return in.gcasWrite(ct, entry == null ? toInserted(ln, key, val) : toReplaced(ln, entry, val));
9090
}
9191

9292
@Nullable Result<V> insertIf(final MutableTrieMap<K, V> ct, final INode<K, V> in, final LNode<K, V> ln, final K key,
9393
final V val, final Object cond) {
9494
final var entry = findEntry(key);
9595
if (entry == null) {
96-
return cond != null && cond != ABSENT || in.gcasWrite(toInserted(ln, key, val), ct) ? Result.empty() : null;
96+
return cond != null && cond != ABSENT || in.gcasWrite(ct, toInserted(ln, key, val)) ? Result.empty() : null;
9797
}
9898
if (cond == ABSENT) {
9999
return entry.toResult();
100100
} else if (cond == null || cond == PRESENT || cond.equals(entry.value())) {
101-
return in.gcasWrite(toReplaced(ln, entry, val), ct) ? entry.toResult() : null;
101+
return in.gcasWrite(ct, toReplaced(ln, entry, val)) ? entry.toResult() : null;
102102
}
103103
return Result.empty();
104104
}
@@ -124,7 +124,7 @@ final boolean insert(final MutableTrieMap<K, V> ct, final INode<K, V> in, final
124124
final var size = ln.size;
125125
final var next = size == 2 ? new TNode<>(ln, map.key(), map.value(), hc) : new LNode<>(ln, map, size - 1);
126126

127-
return in.gcasWrite(next, ct) ? entry.toResult() : null;
127+
return in.gcasWrite(ct, next) ? entry.toResult() : null;
128128
}
129129

130130
private LNode<K, V> toInserted(final LNode<K, V> ln, final K key, final V val) {

triemap/src/main/java/tech/pantheon/triemap/MutableTrieMap.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ private INode<K, V> snapshot() {
141141
INode<K, V> localRoot;
142142
do {
143143
localRoot = readRoot();
144-
} while (!rdcssRoot(localRoot, localRoot.gcasRead(this), localRoot.copyToGen(new Gen(), this)));
144+
} while (!rdcssRoot(localRoot, localRoot.gcasRead(this), localRoot.copyToGen(this, new Gen())));
145145

146146
return localRoot;
147147
}
@@ -153,7 +153,7 @@ public ImmutableTrieMap<K, V> immutableSnapshot() {
153153

154154
@Override
155155
public MutableTrieMap<K, V> mutableSnapshot() {
156-
return new MutableTrieMap<>(snapshot().copyToGen(new Gen(), this));
156+
return new MutableTrieMap<>(snapshot().copyToGen(this, new Gen()));
157157
}
158158

159159
@Override

0 commit comments

Comments
 (0)