Summary
Once the lock-free join and periodic backpointer repair land, we need a deterministic regression test that reproduces the concurrent-join partition and proves repair heals it. The partition is a transient break of the backpointer invariant (if y is x's right neighbor at a level, x must be y's left neighbor, and symmetrically): for four nodes A < B < C < D with A and D already linked at a level, B and C joining concurrently between them can fragment the level list into A<->B and C<->D — each side keeping only half of the splice, reachable with no node failures — which the paper's periodic repair (Aspnes & Shah, arXiv:cs/0306043) heals in a bounded number of rounds.
This issue adds a scheduler-driven test that inserts N nodes concurrently, drives repair rounds deterministically, then asserts the correctness and consistency (backpointer) invariants. It also de-flakes the existing concurrentInsertions test (currently marked flakey) and fixes MvpTest, which is pinned to 5 nodes because it fails when the node count grows.
Scope
src/test/java/skipnode/SkipNodeTest.java
- Add a new deterministic test (e.g.
concurrentJoinRepairRegression) that builds N nodes via LocalSkipGraph, inserts all of them concurrently, steps message delivery and repair rounds through the deterministic test scheduler until quiescent, then runs tableCorrectnessCheck and tableConsistencyCheck (lines 27-42 and 46-62) across every node.
- De-flake
concurrentInsertions (method spans lines 149-192): delete the // TODO: this test is flakey; fix it! marker at line 148 (immediately above the @Test) and make correctness depend on scheduler-driven delivery and repair rather than a timed await.
src/test/java/integration/MvpTest.java
- Remove the hardcoded
NODES = 5 cap and the // TODO: this test fails if number of nodes increased marker (lines 30-31); raise/parameterize NODES and drive insertion plus repair deterministically so full-connectivity searches pass at larger sizes.
Acceptance Criteria
Dependencies
Requires these capabilities to land first:
- An accept-or-forward table write primitive: verify the current slot, then set-or-forward atomically under the table's own lock, with a relink variant that additionally reports already-consistent (no-op) and evicted-neighbor.
- The join/repair message types: an order-verification link request that a neighbor either accepts or forwards to the correct neighbor, and the relink request used by repair.
- The lock-free insert/join rewrite (Algorithm 2) that splices a joining node into each level's doubly-linked list via order-verification forwarding.
- Removal of the pessimistic multi-level neighbor locking and random-backoff retry, so concurrent joins no longer serialize.
- A deterministic test scheduler that can step message delivery and trigger repair rounds on demand (no wall-clock timing).
- The periodic backpointer repair / self-stabilization (Algorithm 8, Section 5.2.1) that re-links neighbors to restore the invariant.
Related: #12.
Part of #33. Depends on: #35, #41, #44
Summary
Once the lock-free join and periodic backpointer repair land, we need a deterministic regression test that reproduces the concurrent-join partition and proves repair heals it. The partition is a transient break of the backpointer invariant (if
yisx's right neighbor at a level,xmust bey's left neighbor, and symmetrically): for four nodes A < B < C < D with A and D already linked at a level, B and C joining concurrently between them can fragment the level list into A<->B and C<->D — each side keeping only half of the splice, reachable with no node failures — which the paper's periodic repair (Aspnes & Shah, arXiv:cs/0306043) heals in a bounded number of rounds.This issue adds a scheduler-driven test that inserts N nodes concurrently, drives repair rounds deterministically, then asserts the correctness and consistency (backpointer) invariants. It also de-flakes the existing
concurrentInsertionstest (currently marked flakey) and fixesMvpTest, which is pinned to 5 nodes because it fails when the node count grows.Scope
src/test/java/skipnode/SkipNodeTest.javaconcurrentJoinRepairRegression) that builds N nodes viaLocalSkipGraph, inserts all of them concurrently, steps message delivery and repair rounds through the deterministic test scheduler until quiescent, then runstableCorrectnessCheckandtableConsistencyCheck(lines 27-42 and 46-62) across every node.concurrentInsertions(method spans lines 149-192): delete the// TODO: this test is flakey; fix it!marker at line 148 (immediately above the@Test) and make correctness depend on scheduler-driven delivery and repair rather than a timedawait.src/test/java/integration/MvpTest.javaNODES = 5cap and the// TODO: this test fails if number of nodes increasedmarker (lines 30-31); raise/parameterizeNODESand drive insertion plus repair deterministically so full-connectivity searches pass at larger sizes.Acceptance Criteria
SkipNodeTestinserts N nodes concurrently (N large enough to exercise concurrent splices, e.g. the existingNODES = 20), drives repair rounds via the test scheduler, and passestableCorrectnessCheckandtableConsistencyCheckfor every node with no wall-clock sleeps.tableConsistencyCheckholds for all nodes.awaitfor correctness.concurrentInsertionsno longer carries the flakey TODO and passes deterministically.MvpTestno longer hardcodesNODES = 5or carries the scaling TODO;MVP_TESTpasses full-connectivity searches at a larger node count (e.g. >= 20).Dependencies
Requires these capabilities to land first:
Related: #12.
Part of #33. Depends on: #35, #41, #44