1
0
Fork 0
mirror of https://github.com/anyproto/any-sync.git synced 2025-06-10 18:10:54 +09:00

Fix tree reduce and update tests

This commit is contained in:
mcrakhman 2024-11-24 20:15:19 +01:00
parent 0a340d61b2
commit 20ddfa1961
No known key found for this signature in database
GPG key ID: DED12CFEF5B8396B
3 changed files with 20 additions and 94 deletions

View file

@ -329,17 +329,6 @@ func (t *Tree) attach(c *Change, newEl bool) {
}
}
func (t *Tree) after(id1, id2 string) (found bool) {
t.iterate(t.attached[id2], func(c *Change) (isContinue bool) {
if c.Id == id1 {
found = true
return false
}
return true
})
return
}
func (t *Tree) dfsPrev(stack []*Change, breakpoints []string, visit func(ch *Change) (isContinue bool), afterVisit func([]*Change)) {
t.visitedBuf = t.visitedBuf[:0]

View file

@ -170,8 +170,8 @@ func TestTree_AddFuzzy(t *testing.T) {
}
}
func TestTree_CheckRootReduce(t *testing.T) {
t.Run("check root once", func(t *testing.T) {
func TestTree_Reduce(t *testing.T) {
t.Run("reduce once", func(t *testing.T) {
tr := new(Tree)
tr.Add(
newSnapshot("0", ""),
@ -186,10 +186,6 @@ func TestTree_CheckRootReduce(t *testing.T) {
newSnapshot("10", "0", "1.2+3.1", "1.1"),
newChange("last", "10", "10"),
)
t.Run("check root", func(t *testing.T) {
total := tr.checkRoot(tr.attached["10"])
assert.Equal(t, 1, total)
})
t.Run("reduce", func(t *testing.T) {
tr.reduceTree()
assert.Equal(t, "10", tr.RootId())
@ -211,10 +207,6 @@ func TestTree_CheckRootReduce(t *testing.T) {
newSnapshot("2", "1", "1"),
newSnapshot("3", "2", "2"),
)
t.Run("check root", func(t *testing.T) {
total := tr.checkRoot(tr.attached["3"])
assert.Equal(t, 0, total)
})
t.Run("reduce", func(t *testing.T) {
tr.reduceTree()
assert.Equal(t, "3", tr.RootId())
@ -226,64 +218,31 @@ func TestTree_CheckRootReduce(t *testing.T) {
assert.Equal(t, []string{"3"}, res)
})
})
t.Run("check root many", func(t *testing.T) {
t.Run("many snapshots", func(t *testing.T) {
tr := new(Tree)
tr.Add(
newSnapshot("0", ""),
newSnapshot("1", "0", "0"),
newChange("1.2", "0", "1"),
newChange("1.3", "0", "1"),
newChange("1.3.1", "0", "1.3"),
newChange("1.2", "1", "1"),
newChange("1.3", "1", "1"),
newChange("1.3.1", "1", "1.3"),
newSnapshot("1.2+3", "1", "1.2", "1.3.1"),
newChange("1.2+3.1", "1", "1.2+3"),
newChange("1.2+3.2", "1", "1.2+3"),
newChange("1.2+3.1", "1.2+3", "1.2+3"),
newChange("1.2+3.2", "1.2+3", "1.2+3"),
newSnapshot("10", "1.2+3", "1.2+3.1", "1.2+3.2"),
newChange("last", "10", "10"),
newChange("last1", "10", "10"),
newChange("last2", "1.2+3", "1.2+3"),
)
t.Run("check root", func(t *testing.T) {
total := tr.checkRoot(tr.attached["10"])
assert.Equal(t, 1, total)
total = tr.checkRoot(tr.attached["1.2+3"])
assert.Equal(t, 4, total)
total = tr.checkRoot(tr.attached["1"])
assert.Equal(t, 8, total)
})
t.Run("reduce", func(t *testing.T) {
tr.reduceTree()
assert.Equal(t, "10", tr.RootId())
assert.Equal(t, "1.2+3", tr.RootId())
var res []string
tr.IterateSkip(tr.RootId(), func(c *Change) (isContinue bool) {
res = append(res, c.Id)
return true
})
assert.Equal(t, []string{"10", "last"}, res)
})
})
t.Run("check root incorrect", func(t *testing.T) {
tr := new(Tree)
tr.Add(
newSnapshot("0", ""),
newChange("1", "0", "0"),
newChange("1.1", "0", "1"),
newChange("1.2", "0", "1"),
newChange("1.4", "0", "1.2"),
newChange("1.3", "0", "1"),
newSnapshot("1.3.1", "0", "1.3"),
newChange("1.2+3", "0", "1.4", "1.3.1"),
newChange("1.2+3.1", "0", "1.2+3"),
newChange("10", "0", "1.2+3.1", "1.1"),
newChange("last", "10", "10"),
)
t.Run("check root", func(t *testing.T) {
total := tr.checkRoot(tr.attached["1.3.1"])
assert.Equal(t, -1, total)
})
t.Run("reduce", func(t *testing.T) {
tr.reduceTree()
assert.Equal(t, "0", tr.RootId())
assert.Equal(t, 0, len(tr.possibleRoots))
assert.Equal(t, []string{"1.2+3", "1.2+3.1", "1.2+3.2", "10", "last", "last1", "last2"}, res)
})
})
}

View file

@ -10,34 +10,6 @@ func (t *Tree) clearPossibleRoots() {
t.possibleRoots = t.possibleRoots[:0]
}
// checkRoot checks if a change can be a new root for the tree
// it returns total changes which were discovered during dfsPrev from heads
func (t *Tree) checkRoot(change *Change) (total int) {
t.stackBuf = t.stackBuf[:0]
stack := t.stackBuf
// starting with heads
for _, h := range t.headIds {
stack = append(stack, t.attached[h])
}
t.dfsPrev(
stack,
[]string{change.Id},
func(ch *Change) bool {
total += 1
return true
},
func(changes []*Change) {
if t.root.visited {
total = -1
}
},
)
return
}
// makeRootAndRemove removes all changes before start and makes start the root
func (t *Tree) makeRootAndRemove(start *Change) {
t.stackBuf = t.stackBuf[:0]
@ -69,7 +41,13 @@ func (t *Tree) reduceTree() (res bool) {
if len(t.possibleRoots) == 0 {
return
}
cur, ok := t.attached[t.attached[t.headIds[0]].SnapshotId]
firstHead := t.attached[t.headIds[0]]
if firstHead.IsSnapshot && len(t.headIds) == 1 {
t.clearPossibleRoots()
t.makeRootAndRemove(firstHead)
return true
}
cur, ok := t.attached[firstHead.SnapshotId]
if !ok {
log.Error("snapshot not found in tree", zap.String("snapshotId", t.attached[t.headIds[0]].SnapshotId))
return false
@ -82,13 +60,13 @@ func (t *Tree) reduceTree() (res bool) {
// gathering snapshots from first head to root
var path []*Change
for cur.Id != t.root.Id {
cur.visited = true
path = append(path, cur)
cur, ok = t.attached[cur.SnapshotId]
if !ok {
log.Error("snapshot not found in tree", zap.String("snapshotId", cur.SnapshotId))
return false
}
cur.visited = true
}
path = append(path, t.root)
t.root.visited = true