Skip to content

Commit a467b3c

Browse files
improve(syncmap): clean up
1 parent 13a167e commit a467b3c

File tree

3 files changed

+46
-41
lines changed

3 files changed

+46
-41
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.gradle
2+
.kotlin
23
build/
34
!gradle/wrapper/gradle-wrapper.jar
45
!**/src/main/**/build/

collections/src/jmh/java/space/vectrix/collections/SyncMapBenchmark.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
@Fork(1)
5252
@Warmup(iterations = 5)
5353
@Measurement(iterations = 5)
54-
@Threads(16)
5554
public class SyncMapBenchmark {
5655
private static final int SIZE = 100_000;
5756

collections/src/main/java/space/vectrix/collections/SyncMap.java

Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -394,8 +394,6 @@ public boolean containsKey(final @NotNull Object key) {
394394
} else if(this.amended) {
395395
reference = this.getMutableValue(hash, key);
396396

397-
// Record a miss even if the node does not exist, but only if the table
398-
// is amended.
399397
this.miss();
400398
return reference;
401399
}
@@ -490,8 +488,6 @@ public boolean containsKey(final @NotNull Object key) {
490488
next = mappingFunction.apply(key);
491489
if(next == null) return null;
492490

493-
// Try insert a new node if it hasn't previously existed, then
494-
// increment the count.
495491
if(SyncMap.replaceNode(mutableTable, index, new Node<>(hash, key, new ObjectReference(next)))) {
496492
break;
497493
}
@@ -529,8 +525,6 @@ public boolean containsKey(final @NotNull Object key) {
529525
next = mappingFunction.apply(key);
530526
if(next == null) return null;
531527

532-
// If the node does not exist in this bucket, create a new
533-
// node and increment the count.
534528
previousNode.next = new Node<>(hash, key, new ObjectReference(next));
535529
break retry;
536530
}
@@ -688,8 +682,6 @@ public boolean containsKey(final @NotNull Object key) {
688682
next = remappingFunction.apply(key, null);
689683
if(next == null) return null;
690684

691-
// Try insert a new node if it hasn't previously existed, then
692-
// increment the count.
693685
if(SyncMap.replaceNode(mutableTable, index, new Node<>(hash, key, new ObjectReference(next)))) {
694686
count = 1L;
695687
break;
@@ -739,8 +731,6 @@ public boolean containsKey(final @NotNull Object key) {
739731
next = remappingFunction.apply(key, null);
740732
if(next == null) return null;
741733

742-
// If the node does not exist in this bucket, create a new
743-
// node and increment the count.
744734
previousNode.next = new Node<>(hash, key, new ObjectReference(next));
745735

746736
count = 1L;
@@ -797,8 +787,6 @@ public boolean containsKey(final @NotNull Object key) {
797787
if(!this.amended || (mutableTable == null && (mutableTable = this.mutableTable) == null) || (length = mutableTable.length) == 0) {
798788
this.amend();
799789
} else if((node = SyncMap.getNode(mutableTable, index = (length - 1) & hash)) == null) {
800-
// Try insert a new node if it hasn't previously existed, then
801-
// increment the count.
802790
if(SyncMap.replaceNode(mutableTable, index, new Node<>(hash, key, new ObjectReference(value)))) {
803791
break;
804792
}
@@ -830,8 +818,6 @@ public boolean containsKey(final @NotNull Object key) {
830818

831819
final Node<K, V> previousNode = node;
832820
if((node = node.next) == null) {
833-
// If the node does not exist in this bucket, create a new
834-
// node and increment the count.
835821
previousNode.next = new Node<>(hash, key, new ObjectReference(value));
836822
break retry;
837823
}
@@ -886,8 +872,6 @@ public boolean containsKey(final @NotNull Object key) {
886872
if(!this.amended || (mutableTable == null && (mutableTable = this.mutableTable) == null) || (length = mutableTable.length) == 0) {
887873
this.amend();
888874
} else if((node = SyncMap.getNode(mutableTable, index = (length - 1) & hash)) == null) {
889-
// Try insert a new node if it hasn't previously existed, then
890-
// increment the count.
891875
if(SyncMap.replaceNode(mutableTable, index, new Node<>(hash, key, new ObjectReference(value)))) {
892876
break;
893877
}
@@ -921,8 +905,6 @@ public boolean containsKey(final @NotNull Object key) {
921905

922906
final Node<K, V> previousNode = node;
923907
if((node = node.next) == null) {
924-
// If the node does not exist in this bucket, create a new
925-
// node and increment the count.
926908
previousNode.next = new Node<>(hash, key, new ObjectReference(value));
927909
break retry;
928910
}
@@ -942,10 +924,8 @@ public boolean containsKey(final @NotNull Object key) {
942924
for(Node<K, V> node; ; ) {
943925
final int length, index;
944926
if(!this.amended || (table == null && (table = this.mutableTable) == null) || (length = table.length) == 0) {
945-
// If the mutable table has been removed, we can't proceed.
946927
return;
947928
} else if((node = SyncMap.getNode(table, index = (length - 1) & hash)) == null) {
948-
// Try insert a new node if it hasn't previously existed.
949929
if(SyncMap.replaceNode(table, index, new Node<>(hash, key, reference))) {
950930
return;
951931
}
@@ -965,8 +945,6 @@ public boolean containsKey(final @NotNull Object key) {
965945

966946
final Node<K, V> previousNode = node;
967947
if((node = node.next) == null) {
968-
// If the node does not exist in this bucket, create a new
969-
// node.
970948
previousNode.next = new Node<>(hash, key, reference);
971949
return;
972950
}
@@ -1368,7 +1346,6 @@ public void clear() {
13681346

13691347
long stamp = this.stampLock.getAcquire();
13701348
while(stamp == StampLock.DEFAULT_STAMP && this.amended && (source = this.mutableTable) != null) {
1371-
// If the stamp lock has not been acquired, try to acquire it now.
13721349
final long next = StampLock.pack(StampLock.MODE_PROMOTE);
13731350
final long witness = this.stampLock.compareAndExchange(stamp, next);
13741351
if(witness != StampLock.DEFAULT_STAMP) {
@@ -1438,7 +1415,6 @@ public void clear() {
14381415
|| (this.size.sum() * this.loadFactor) < length) return;
14391416

14401417
if(stamp == StampLock.DEFAULT_STAMP) {
1441-
// If the stamp lock has not been acquired, try to acquire it now.
14421418
final long next = StampLock.pack(StampLock.MODE_RESIZE);
14431419
final long witness = this.stampLock.compareAndExchange(stamp, next);
14441420
if(witness != StampLock.DEFAULT_STAMP) {
@@ -1456,8 +1432,6 @@ public void clear() {
14561432
this.transferTable = destination = new Node[length << 1];
14571433
break;
14581434
} else if(StampLock.modeOf(stamp) == StampLock.MODE_RESIZE && StampLock.stageOf(stamp) == StampLock.STAGE_RUNNING) {
1459-
// If the stamp lock has been acquired, ensure the mode is resize and
1460-
// the stage is running.
14611435
final long count = StampLock.countOf(stamp);
14621436
if(count >= SyncMap.MAXIMUM_TRANSFER_THREADS) {
14631437
return;
@@ -1488,7 +1462,6 @@ public void clear() {
14881462
if(achieved) {
14891463
stamp = this.stampLock.getAcquire();
14901464
for(; ; ) {
1491-
// If the stamp lock is no longer at the running stage break.
14921465
if(StampLock.stageOf(stamp) != StampLock.STAGE_RUNNING) break;
14931466

14941467
final long next = StampLock.withStage(stamp, StampLock.STAGE_ACHIEVED);
@@ -1558,7 +1531,6 @@ public void clear() {
15581531
length = source.length;
15591532

15601533
if(stamp == StampLock.DEFAULT_STAMP) {
1561-
// If the stamp lock has not been acquired, try to acquire it now.
15621534
final long next = StampLock.pack(StampLock.MODE_AMEND);
15631535
final long witness = this.stampLock.compareAndExchange(stamp, next);
15641536
if(witness != StampLock.DEFAULT_STAMP) {
@@ -1576,8 +1548,6 @@ public void clear() {
15761548
this.transferTable = destination = new Node[length];
15771549
break;
15781550
} else if(StampLock.modeOf(stamp) == StampLock.MODE_AMEND && StampLock.stageOf(stamp) == StampLock.STAGE_RUNNING) {
1579-
// If the stamp lock has been acquired, ensure the mode is amend and
1580-
// the stage is running.
15811551
final long count = StampLock.countOf(stamp);
15821552
if(count >= SyncMap.MAXIMUM_TRANSFER_THREADS) {
15831553
return;
@@ -1608,7 +1578,6 @@ public void clear() {
16081578
if(achieved) {
16091579
stamp = this.stampLock.getAcquire();
16101580
for(; ; ) {
1611-
// If the stamp lock is no longer at the running stage break.
16121581
if(StampLock.stageOf(stamp) != StampLock.STAGE_RUNNING) break;
16131582

16141583
final long next = StampLock.withStage(stamp, StampLock.STAGE_ACHIEVED);
@@ -1689,7 +1658,6 @@ public void clear() {
16891658
Node<K, V> node;
16901659
int index, bound = 0;
16911660

1692-
// Claim the range of indexes we are going to transfer.
16931661
for(; ; ) {
16941662
if((index = (int) SyncMap.TRANSFER_INDEX.getAcquire(this)) <= 0 || finished) {
16951663
index = -1;
@@ -1702,8 +1670,6 @@ public void clear() {
17021670
Thread.onSpinWait();
17031671
}
17041672

1705-
// Start iterating the nodes in the range that was claimed and move them
1706-
// to the destination table.
17071673
boolean advance = false;
17081674
for(int i = index - 1; ; ) {
17091675
if(i < 0 || i >= capacity || (resize && (i + capacity >= nextCapacity))) {
@@ -1787,7 +1753,6 @@ public void clear() {
17871753
if(advance) i--;
17881754
}
17891755

1790-
// Now that the range has been transferred, increase the progress.
17911756
if(delta > 0) {
17921757
progress = (int) SyncMap.TRANSFER_PROGRESS.getAcquire(this);
17931758
for(; ; ) {
@@ -1811,6 +1776,10 @@ public void clear() {
18111776

18121777
/* --------------------------- < Stamp Lock > --------------------------- */
18131778

1779+
/**
1780+
* Represents a stamped lock for doing bulk map operations such as promoting,
1781+
* resizing, and amending.
1782+
*/
18141783
/* package */ static final class StampLock {
18151784
/* package */ static final long DEFAULT_STAMP = 0L;
18161785

@@ -1843,25 +1812,57 @@ public void clear() {
18431812

18441813
/* package */ static final long ONE_COUNT = 1L << StampLock.SHIFT_COUNT;
18451814

1846-
private static long pack(final int mode) {
1815+
/**
1816+
* Returns a packed {@code long} stamp with the given mode, running stage,
1817+
* and thread count of {@code 1}.
1818+
*
1819+
* @param mode the mode
1820+
* @return the packed stamp
1821+
*/
1822+
/* package */ static long pack(final int mode) {
18471823
return ((long) mode & 7L) << StampLock.SHIFT_MODE
18481824
| ((long) StampLock.STAGE_RUNNING & 7L) << StampLock.SHIFT_STAGE
18491825
| 1L << StampLock.SHIFT_COUNT;
18501826
}
18511827

1852-
private static int modeOf(final long stamp) {
1828+
/**
1829+
* Returns the mode from the packed stamp.
1830+
*
1831+
* @param stamp the packed stamp
1832+
* @return the mode
1833+
*/
1834+
/* package */ static int modeOf(final long stamp) {
18531835
return (int) ((stamp >>> StampLock.SHIFT_MODE) & StampLock.MASK_MODE);
18541836
}
18551837

1856-
private static int stageOf(final long stamp) {
1838+
/**
1839+
* Returns the stage from the packed stamp.
1840+
*
1841+
* @param stamp the packed stamp
1842+
* @return the stage
1843+
*/
1844+
/* package */ static int stageOf(final long stamp) {
18571845
return (int) ((stamp >>> StampLock.SHIFT_STAGE) & StampLock.MASK_STAGE);
18581846
}
18591847

1860-
private static long countOf(final long stamp) {
1848+
/**
1849+
* Returns the count from the packet stamp.
1850+
*
1851+
* @param stamp the packed stamp
1852+
* @return the count
1853+
*/
1854+
/* package */ static long countOf(final long stamp) {
18611855
return stamp >>> StampLock.SHIFT_COUNT;
18621856
}
18631857

1864-
private static long withStage(final long stamp, final int newStage) {
1858+
/**
1859+
* Returns the packed stamp with the given stage applied.
1860+
*
1861+
* @param stamp the packed stamp
1862+
* @param newStage the new stage
1863+
* @return the packed stamp, with the new stage
1864+
*/
1865+
/* package */ static long withStage(final long stamp, final int newStage) {
18651866
final long stageMask = StampLock.MASK_STAGE << StampLock.SHIFT_STAGE;
18661867
return (stamp & ~stageMask) | (((long) newStage & 7L) << StampLock.SHIFT_STAGE);
18671868
}
@@ -1900,6 +1901,10 @@ private static long withStage(final long stamp, final int newStage) {
19001901

19011902
/* ------------------------ < Object Reference > ------------------------ */
19021903

1904+
/**
1905+
* Represents a value holder for sharing across nodes in the immutable and
1906+
* mutable tables, providing atomic updates for the underlying value.
1907+
*/
19031908
@SuppressWarnings({"FieldMayBeFinal", "FieldCanBeLocal"})
19041909
/* package */ static final class ObjectReference {
19051910
private static final VarHandle VALUE;

0 commit comments

Comments
 (0)