Add build full tree for history tree
This commit is contained in:
parent
527236b17b
commit
a6d66c15a0
@ -14,34 +14,47 @@ type historyTree struct {
|
|||||||
*objectTree
|
*objectTree
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *historyTree) rebuildFromStorage(beforeId string, include bool) (err error) {
|
func (h *historyTree) rebuildFromStorage(params HistoryTreeParams) (err error) {
|
||||||
ot := h.objectTree
|
err = h.rebuild(params)
|
||||||
ot.treeBuilder.Reset()
|
if err != nil {
|
||||||
if beforeId == ot.Id() && !include {
|
return
|
||||||
|
}
|
||||||
|
h.aclList.RLock()
|
||||||
|
defer h.aclList.RUnlock()
|
||||||
|
state := h.aclList.AclState()
|
||||||
|
|
||||||
|
return h.readKeysFromAclState(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *historyTree) rebuild(params HistoryTreeParams) (err error) {
|
||||||
|
var (
|
||||||
|
beforeId = params.BeforeId
|
||||||
|
include = params.IncludeBeforeId
|
||||||
|
full = params.BuildFullTree
|
||||||
|
)
|
||||||
|
h.treeBuilder.Reset()
|
||||||
|
if full {
|
||||||
|
h.tree, err = h.treeBuilder.BuildFull()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if beforeId == h.Id() && !include {
|
||||||
return ErrLoadBeforeRoot
|
return ErrLoadBeforeRoot
|
||||||
}
|
}
|
||||||
|
|
||||||
heads := []string{beforeId}
|
heads := []string{beforeId}
|
||||||
if beforeId == "" {
|
if beforeId == "" {
|
||||||
heads, err = ot.treeStorage.Heads()
|
heads, err = h.treeStorage.Heads()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if !include {
|
} else if !include {
|
||||||
beforeChange, err := ot.treeBuilder.loadChange(beforeId)
|
beforeChange, err := h.treeBuilder.loadChange(beforeId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
heads = beforeChange.PreviousIds
|
heads = beforeChange.PreviousIds
|
||||||
}
|
}
|
||||||
|
|
||||||
ot.tree, err = ot.treeBuilder.build(heads, nil, nil)
|
h.tree, err = h.treeBuilder.build(heads, nil, nil)
|
||||||
if err != nil {
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
ot.aclList.RLock()
|
|
||||||
defer ot.aclList.RUnlock()
|
|
||||||
state := ot.aclList.AclState()
|
|
||||||
|
|
||||||
return ot.readKeysFromAclState(state)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -674,6 +674,37 @@ func TestObjectTree(t *testing.T) {
|
|||||||
assert.Equal(t, "0", hTree.Root().Id)
|
assert.Equal(t, "0", hTree.Root().Id)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("test history tree build full", func(t *testing.T) {
|
||||||
|
changeCreator, deps := prepareHistoryTreeDeps(aclList)
|
||||||
|
|
||||||
|
// sequence of snapshots: 5->1->0
|
||||||
|
rawChanges := []*treechangeproto.RawTreeChangeWithId{
|
||||||
|
changeCreator.CreateRaw("1", aclList.Head().Id, "0", true, "0"),
|
||||||
|
changeCreator.CreateRaw("2", aclList.Head().Id, "1", false, "1"),
|
||||||
|
changeCreator.CreateRaw("3", aclList.Head().Id, "1", true, "2"),
|
||||||
|
changeCreator.CreateRaw("4", aclList.Head().Id, "1", false, "2"),
|
||||||
|
changeCreator.CreateRaw("5", aclList.Head().Id, "1", true, "3", "4"),
|
||||||
|
changeCreator.CreateRaw("6", aclList.Head().Id, "5", false, "5"),
|
||||||
|
}
|
||||||
|
deps.treeStorage.TransactionAdd(rawChanges, []string{"6"})
|
||||||
|
hTree, err := buildHistoryTree(deps, HistoryTreeParams{
|
||||||
|
BuildFullTree: true,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
// check tree heads
|
||||||
|
assert.Equal(t, []string{"6"}, hTree.Heads())
|
||||||
|
|
||||||
|
// check tree iterate
|
||||||
|
var iterChangesId []string
|
||||||
|
err = hTree.IterateFrom(hTree.Root().Id, nil, func(change *Change) bool {
|
||||||
|
iterChangesId = append(iterChangesId, change.Id)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
require.NoError(t, err, "iterate should be without error")
|
||||||
|
assert.Equal(t, []string{"0", "1", "2", "3", "4", "5", "6"}, iterChangesId)
|
||||||
|
assert.Equal(t, "0", hTree.Root().Id)
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("test history tree include", func(t *testing.T) {
|
t.Run("test history tree include", func(t *testing.T) {
|
||||||
changeCreator, deps := prepareHistoryTreeDeps(aclList)
|
changeCreator, deps := prepareHistoryTreeDeps(aclList)
|
||||||
|
|
||||||
|
|||||||
@ -22,6 +22,7 @@ type HistoryTreeParams struct {
|
|||||||
AclList list.AclList
|
AclList list.AclList
|
||||||
BeforeId string
|
BeforeId string
|
||||||
IncludeBeforeId bool
|
IncludeBeforeId bool
|
||||||
|
BuildFullTree bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type objectTreeDeps struct {
|
type objectTreeDeps struct {
|
||||||
@ -230,7 +231,7 @@ func buildHistoryTree(deps objectTreeDeps, params HistoryTreeParams) (ht History
|
|||||||
}
|
}
|
||||||
|
|
||||||
hTree := &historyTree{objectTree: objTree}
|
hTree := &historyTree{objectTree: objTree}
|
||||||
err = hTree.rebuildFromStorage(params.BeforeId, params.IncludeBeforeId)
|
err = hTree.rebuildFromStorage(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,6 +51,22 @@ func (tb *treeBuilder) Build(theirHeads []string, newChanges []*Change) (*Tree,
|
|||||||
return tb.build(heads, theirHeads, newChanges)
|
return tb.build(heads, theirHeads, newChanges)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tb *treeBuilder) BuildFull() (*Tree, error) {
|
||||||
|
defer func() {
|
||||||
|
tb.cache = make(map[string]*Change)
|
||||||
|
}()
|
||||||
|
tb.cache = make(map[string]*Change)
|
||||||
|
heads, err := tb.treeStorage.Heads()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = tb.buildTree(heads, tb.treeStorage.Id())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return tb.tree, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (tb *treeBuilder) build(heads []string, theirHeads []string, newChanges []*Change) (*Tree, error) {
|
func (tb *treeBuilder) build(heads []string, theirHeads []string, newChanges []*Change) (*Tree, error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
tb.cache = make(map[string]*Change)
|
tb.cache = make(map[string]*Change)
|
||||||
|
|||||||
@ -323,8 +323,9 @@ type BuildTreeOpts struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type HistoryTreeOpts struct {
|
type HistoryTreeOpts struct {
|
||||||
BeforeId string
|
BeforeId string
|
||||||
Include bool
|
Include bool
|
||||||
|
BuildFullTree bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *space) BuildTree(ctx context.Context, id string, opts BuildTreeOpts) (t objecttree.ObjectTree, err error) {
|
func (s *space) BuildTree(ctx context.Context, id string, opts BuildTreeOpts) (t objecttree.ObjectTree, err error) {
|
||||||
@ -364,6 +365,7 @@ func (s *space) BuildHistoryTree(ctx context.Context, id string, opts HistoryTre
|
|||||||
AclList: s.aclList,
|
AclList: s.aclList,
|
||||||
BeforeId: opts.BeforeId,
|
BeforeId: opts.BeforeId,
|
||||||
IncludeBeforeId: opts.Include,
|
IncludeBeforeId: opts.Include,
|
||||||
|
BuildFullTree: opts.BuildFullTree,
|
||||||
}
|
}
|
||||||
params.TreeStorage, err = s.storage.TreeStorage(id)
|
params.TreeStorage, err = s.storage.TreeStorage(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user