Fix multi-round convergence for N-way collisions (bd-108)

- Add AllocateNextID() public method to SQLiteStorage for cross-package ID allocation
- Enhance handleRename() to handle collision during rename with retry logic
- Fix stale ID map issue by removing deleted IDs from dbByID after rename
- Update edge case tests to use convergence rounds consistently
- All N-way collision tests now pass (TestFiveCloneCollision, TestEdgeCases)
This commit is contained in:
Steve Yegge
2025-10-29 11:08:28 -07:00
parent 757bdf6f7e
commit 55f803a7c9
3 changed files with 116 additions and 25 deletions

View File

@@ -402,9 +402,13 @@ func testIdenticalContent(t *testing.T, numClones int) {
syncCloneWithConflictResolution(t, cloneDirs[syncOrder[i]], syncOrder[i], i == 0)
}
// Final pull
for name, dir := range cloneDirs {
finalPullForClone(t, dir, name)
// Final convergence rounds
for round := 1; round <= 3; round++ {
for i := 0; i < numClones; i++ {
name := string(rune('A' + i))
dir := cloneDirs[name]
syncCloneWithConflictResolution(t, dir, name, false)
}
}
// Verify all clones have exactly one issue (deduplication worked)
@@ -450,9 +454,13 @@ func testOneDifferent(t *testing.T, numClones int) {
syncCloneWithConflictResolution(t, cloneDirs[syncOrder[i]], syncOrder[i], i == 0)
}
// Final pull
for name, dir := range cloneDirs {
finalPullForClone(t, dir, name)
// Final convergence rounds
for round := 1; round <= 3; round++ {
for i := 0; i < numClones; i++ {
name := string(rune('A' + i))
dir := cloneDirs[name]
syncCloneWithConflictResolution(t, dir, name, false)
}
}
// Verify all clones have exactly 2 issues
@@ -503,9 +511,15 @@ func testMixedCollisions(t *testing.T, numClones int) {
syncCloneWithConflictResolution(t, cloneDirs[syncOrder[i]], syncOrder[i], i == 0)
}
// Final pull
for name, dir := range cloneDirs {
finalPullForClone(t, dir, name)
// Final convergence rounds - same as TestFiveCloneCollision
t.Log("Final convergence rounds")
for round := 1; round <= 3; round++ {
t.Logf("Convergence round %d", round)
for i := 0; i < numClones; i++ {
name := string(rune('A' + i))
dir := cloneDirs[name]
syncCloneWithConflictResolution(t, dir, name, false)
}
}
// Verify all clones have all 2*N issues