forked from TrueCloudLab/frostfs-node
[#1234] pilorama: Fix GetByPath() on duplicate directories
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
parent
6ace2f597e
commit
b027a7f91e
2 changed files with 46 additions and 15 deletions
|
@ -906,7 +906,7 @@ func (t *boltForest) TreeGetByPath(ctx context.Context, cid cidSDK.ID, treeID st
|
||||||
|
|
||||||
b := treeRoot.Bucket(dataBucket)
|
b := treeRoot.Bucket(dataBucket)
|
||||||
|
|
||||||
i, curNode, err := t.getPathPrefix(b, attr, path[:len(path)-1])
|
i, curNodes, err := t.getPathPrefixMultiTraversal(b, attr, path[:len(path)-1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -918,7 +918,8 @@ func (t *boltForest) TreeGetByPath(ctx context.Context, cid cidSDK.ID, treeID st
|
||||||
|
|
||||||
c := b.Cursor()
|
c := b.Cursor()
|
||||||
|
|
||||||
attrKey := internalKey(nil, attr, path[len(path)-1], curNode, 0)
|
for i := range curNodes {
|
||||||
|
attrKey := internalKey(nil, attr, path[len(path)-1], curNodes[i], 0)
|
||||||
attrKey = attrKey[:len(attrKey)-8]
|
attrKey = attrKey[:len(attrKey)-8]
|
||||||
childKey, _ := c.Seek(attrKey)
|
childKey, _ := c.Seek(attrKey)
|
||||||
for len(childKey) == len(attrKey)+8 && bytes.Equal(attrKey, childKey[:len(childKey)-8]) {
|
for len(childKey) == len(attrKey)+8 && bytes.Equal(attrKey, childKey[:len(childKey)-8]) {
|
||||||
|
@ -934,6 +935,7 @@ func (t *boltForest) TreeGetByPath(ctx context.Context, cid cidSDK.ID, treeID st
|
||||||
}
|
}
|
||||||
childKey, _ = c.Next()
|
childKey, _ = c.Next()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}))
|
}))
|
||||||
success = err == nil
|
success = err == nil
|
||||||
|
@ -1412,6 +1414,36 @@ func (t *boltForest) TreeListTrees(ctx context.Context, prm TreeListTreesPrm) (*
|
||||||
return &res, nil
|
return &res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *boltForest) getPathPrefixMultiTraversal(bTree *bbolt.Bucket, attr string, path []string) (int, []Node, error) {
|
||||||
|
c := bTree.Cursor()
|
||||||
|
|
||||||
|
var curNodes []Node
|
||||||
|
nextNodes := []Node{RootID}
|
||||||
|
var attrKey []byte
|
||||||
|
|
||||||
|
for i := range path {
|
||||||
|
curNodes, nextNodes = nextNodes, curNodes[:0]
|
||||||
|
for j := range curNodes {
|
||||||
|
attrKey = internalKey(attrKey, attr, path[i], curNodes[j], 0)
|
||||||
|
attrKey = attrKey[:len(attrKey)-8]
|
||||||
|
|
||||||
|
childKey, value := c.Seek(attrKey)
|
||||||
|
for len(childKey) == len(attrKey)+8 && bytes.Equal(attrKey, childKey[:len(childKey)-8]) {
|
||||||
|
if len(value) == 1 && value[0] == 1 {
|
||||||
|
nextNodes = append(nextNodes, binary.LittleEndian.Uint64(childKey[len(childKey)-8:]))
|
||||||
|
}
|
||||||
|
childKey, value = c.Next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(nextNodes) == 0 {
|
||||||
|
return i, curNodes, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return len(path), nextNodes, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (t *boltForest) getPathPrefix(bTree *bbolt.Bucket, attr string, path []string) (int, Node, error) {
|
func (t *boltForest) getPathPrefix(bTree *bbolt.Bucket, attr string, path []string) (int, Node, error) {
|
||||||
c := bTree.Cursor()
|
c := bTree.Cursor()
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDuplicateDirectory(t *testing.T) {
|
func TestDuplicateDirectory(t *testing.T) {
|
||||||
t.Skip()
|
|
||||||
for i := range providers {
|
for i := range providers {
|
||||||
if providers[i].name == "inmemory" {
|
if providers[i].name == "inmemory" {
|
||||||
continue
|
continue
|
||||||
|
|
Loading…
Reference in a new issue