More tests and fixes for reading from tree

This commit is contained in:
mcrakhman 2022-09-07 22:30:29 +02:00 committed by Mikhail Iudin
parent cd0f601afa
commit 77e4f9b6f9
No known key found for this signature in database
GPG Key ID: FAAAA8BAABDFF1C0
3 changed files with 53 additions and 27 deletions

View File

@ -92,12 +92,13 @@ func prepareTreeContext(t *testing.T, aclList list.ACLList) testTreeContext {
treeStorage := changeCreator.createNewTreeStorage("treeId", aclList.ID(), aclList.Head().Id, "0") treeStorage := changeCreator.createNewTreeStorage("treeId", aclList.ID(), aclList.Head().Id, "0")
changeBuilder := &mockChangeBuilder{} changeBuilder := &mockChangeBuilder{}
deps := objectTreeDeps{ deps := objectTreeDeps{
changeBuilder: changeBuilder, changeBuilder: changeBuilder,
treeBuilder: newTreeBuilder(treeStorage, changeBuilder), treeBuilder: newTreeBuilder(treeStorage, changeBuilder),
treeStorage: treeStorage, treeStorage: treeStorage,
updateListener: nil, updateListener: nil,
validator: &mockChangeValidator{}, rawChangeLoader: newRawChangeLoader(treeStorage, changeBuilder),
aclList: aclList, validator: &mockChangeValidator{},
aclList: aclList,
} }
// check build // check build
@ -271,7 +272,7 @@ func TestObjectTree(t *testing.T) {
assert.Equal(t, true, objTree.(*objectTree).snapshotPathIsActual()) assert.Equal(t, true, objTree.(*objectTree).snapshotPathIsActual())
}) })
t.Run("changes after common snapshot complex", func(t *testing.T) { t.Run("changes from tree after common snapshot complex", func(t *testing.T) {
ctx := prepareTreeContext(t, aclList) ctx := prepareTreeContext(t, aclList)
changeCreator := ctx.changeCreator changeCreator := ctx.changeCreator
objTree := ctx.objTree objTree := ctx.objTree
@ -289,7 +290,7 @@ func TestObjectTree(t *testing.T) {
require.NoError(t, err, "adding changes should be without error") require.NoError(t, err, "adding changes should be without error")
require.Equal(t, "0", objTree.Root().Id) require.Equal(t, "0", objTree.Root().Id)
t.Run("changes from tree", func(t *testing.T) { t.Run("all changes from tree", func(t *testing.T) {
changes, err := objTree.ChangesAfterCommonSnapshot([]string{"3", "0"}, []string{}) changes, err := objTree.ChangesAfterCommonSnapshot([]string{"3", "0"}, []string{})
require.NoError(t, err, "changes after common snapshot should be without error") require.NoError(t, err, "changes after common snapshot should be without error")
@ -302,9 +303,11 @@ func TestObjectTree(t *testing.T) {
_, ok := changeIds[raw.Id] _, ok := changeIds[raw.Id]
assert.Equal(t, true, ok) assert.Equal(t, true, ok)
} }
_, ok := changeIds["0"]
assert.Equal(t, true, ok)
}) })
t.Run("changes from tree after first", func(t *testing.T) { t.Run("changes from tree after 1", func(t *testing.T) {
changes, err := objTree.ChangesAfterCommonSnapshot([]string{"3", "0"}, []string{"1"}) changes, err := objTree.ChangesAfterCommonSnapshot([]string{"3", "0"}, []string{"1"})
require.NoError(t, err, "changes after common snapshot should be without error") require.NoError(t, err, "changes after common snapshot should be without error")
@ -313,15 +316,33 @@ func TestObjectTree(t *testing.T) {
changeIds[ch.Id] = struct{}{} changeIds[ch.Id] = struct{}{}
} }
for _, raw := range rawChanges { for _, id := range []string{"2", "3", "4", "5", "6"} {
if raw.Id == "1" { _, ok := changeIds[id]
_, ok := changeIds[raw.Id]
assert.Equal(t, false, ok)
continue
}
_, ok := changeIds[raw.Id]
assert.Equal(t, true, ok) assert.Equal(t, true, ok)
} }
for _, id := range []string{"0", "1"} {
_, ok := changeIds[id]
assert.Equal(t, false, ok)
}
})
t.Run("changes from tree after 5", func(t *testing.T) {
changes, err := objTree.ChangesAfterCommonSnapshot([]string{"3", "0"}, []string{"5"})
require.NoError(t, err, "changes after common snapshot should be without error")
changeIds := make(map[string]struct{})
for _, ch := range changes {
changeIds[ch.Id] = struct{}{}
}
for _, id := range []string{"2", "3", "4", "6"} {
_, ok := changeIds[id]
assert.Equal(t, true, ok)
}
for _, id := range []string{"0", "1", "5"} {
_, ok := changeIds[id]
assert.Equal(t, false, ok)
}
}) })
}) })

View File

@ -90,7 +90,7 @@ func (r *rawChangeLoader) LoadFromTree(t *Tree, breakpoints []string) ([]*aclpb.
return true return true
}, },
func(visited []*Change) { func(visited []*Change) {
discardFromSlice(results, func(change *Change) bool { results = discardFromSlice(results, func(change *Change) bool {
return change.visited return change.visited
}) })
}, },
@ -200,7 +200,7 @@ func (r *rawChangeLoader) LoadFromStorage(commonSnapshot string, heads, breakpoi
}) })
// discarding visited // discarding visited
discardFromSlice(buffer, func(change *aclpb.RawChange) bool { buffer = discardFromSlice(buffer, func(change *aclpb.RawChange) bool {
return change == nil return change == nil
}) })
@ -233,17 +233,20 @@ func (r *rawChangeLoader) loadEntry(id string) (entry rawCacheEntry, err error)
return return
} }
func discardFromSlice[T any](elements []T, isDiscarded func(T) bool) { func discardFromSlice[T any](elements []T, isDiscarded func(T) bool) []T {
var ( var (
finishedIdx = 0 finishedIdx = 0
currentIdx = 0 currentIdx = 0
) )
for currentIdx < len(elements) { for currentIdx < len(elements) {
if !isDiscarded(elements[currentIdx]) && finishedIdx != currentIdx { if !isDiscarded(elements[currentIdx]) {
elements[finishedIdx] = elements[currentIdx] if finishedIdx != currentIdx {
elements[finishedIdx] = elements[currentIdx]
}
finishedIdx++ finishedIdx++
} }
currentIdx++ currentIdx++
} }
elements = elements[:finishedIdx] elements = elements[:finishedIdx]
return elements
} }

View File

@ -73,22 +73,24 @@ func (tb *treeBuilder) buildTree(heads []string, breakpoint string) (err error)
return return
} }
tb.tree.AddFast(ch) tb.tree.AddFast(ch)
changes, err := tb.dfs(heads, breakpoint, tb.loadChange) changes, err := tb.dfs(heads, breakpoint)
tb.tree.AddFast(changes...) tb.tree.AddFast(changes...)
return return
} }
func (tb *treeBuilder) dfs( func (tb *treeBuilder) dfs(heads []string, breakpoint string) (buf []*Change, err error) {
heads []string, // initializing buffers
breakpoint string,
load func(string) (*Change, error)) (buf []*Change, err error) {
tb.idStack = tb.idStack[:0] tb.idStack = tb.idStack[:0]
tb.loadBuffer = tb.loadBuffer[:0] tb.loadBuffer = tb.loadBuffer[:0]
// updating map
uniqMap := map[string]struct{}{breakpoint: {}} uniqMap := map[string]struct{}{breakpoint: {}}
// preparing dfs
tb.idStack = append(tb.idStack, heads...) tb.idStack = append(tb.idStack, heads...)
// dfs
for len(tb.idStack) > 0 { for len(tb.idStack) > 0 {
id := tb.idStack[len(tb.idStack)-1] id := tb.idStack[len(tb.idStack)-1]
tb.idStack = tb.idStack[:len(tb.idStack)-1] tb.idStack = tb.idStack[:len(tb.idStack)-1]
@ -96,7 +98,7 @@ func (tb *treeBuilder) dfs(
continue continue
} }
ch, err := load(id) ch, err := tb.loadChange(id)
if err != nil { if err != nil {
continue continue
} }