[#1642] tree: Fix sorted getSubtree for multiversion filenames
Signed-off-by: Airat Arifullin <a.arifullin@yadro.com>
This commit is contained in:
parent
a11b2d27e4
commit
760b6a44ea
4 changed files with 29 additions and 6 deletions
|
@ -1128,6 +1128,7 @@ func (t *boltForest) TreeSortedByFilename(ctx context.Context, cid cidSDK.ID, tr
|
||||||
}
|
}
|
||||||
|
|
||||||
t.fillSortedChildren(b, nodeIDs, h)
|
t.fillSortedChildren(b, nodeIDs, h)
|
||||||
|
|
||||||
for info, ok := h.pop(); ok; info, ok = h.pop() {
|
for info, ok := h.pop(); ok; info, ok = h.pop() {
|
||||||
for _, id := range info.id {
|
for _, id := range info.id {
|
||||||
childInfo, err := t.getChildInfo(b, key, id)
|
childInfo, err := t.getChildInfo(b, key, id)
|
||||||
|
@ -1154,7 +1155,7 @@ func (t *boltForest) TreeSortedByFilename(ctx context.Context, cid cidSDK.ID, tr
|
||||||
}
|
}
|
||||||
if len(res) != 0 {
|
if len(res) != 0 {
|
||||||
s := string(findAttr(res[len(res)-1].Meta, AttributeFilename))
|
s := string(findAttr(res[len(res)-1].Meta, AttributeFilename))
|
||||||
last = NewCursor(s)
|
last = NewCursor(s, res[len(res)-1].Children[len(res[len(res)-1].Children)-1])
|
||||||
}
|
}
|
||||||
return res, last, metaerr.Wrap(err)
|
return res, last, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,11 +207,11 @@ func (f *memoryForest) TreeSortedByFilename(_ context.Context, cid cid.ID, treeI
|
||||||
if start == nil || string(findAttr(r[i].Meta, AttributeFilename)) > start.GetFilename() {
|
if start == nil || string(findAttr(r[i].Meta, AttributeFilename)) > start.GetFilename() {
|
||||||
finish := min(len(res), i+count)
|
finish := min(len(res), i+count)
|
||||||
last := string(findAttr(r[finish-1].Meta, AttributeFilename))
|
last := string(findAttr(r[finish-1].Meta, AttributeFilename))
|
||||||
return r[i:finish], NewCursor(last), nil
|
return r[i:finish], NewCursor(last, 0), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
last := string(res[len(res)-1].Meta.GetAttr(AttributeFilename))
|
last := string(res[len(res)-1].Meta.GetAttr(AttributeFilename))
|
||||||
return nil, NewCursor(last), nil
|
return nil, NewCursor(last, 0), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TreeGetChildren implements the Forest interface.
|
// TreeGetChildren implements the Forest interface.
|
||||||
|
|
|
@ -50,8 +50,19 @@ func newHeap(start *Cursor, count int) *fixedHeap {
|
||||||
const amortizationMultiplier = 5
|
const amortizationMultiplier = 5
|
||||||
|
|
||||||
func (h *fixedHeap) push(id MultiNode, filename string) bool {
|
func (h *fixedHeap) push(id MultiNode, filename string) bool {
|
||||||
if h.start != nil && filename <= (*h.start).GetFilename() {
|
if h.start != nil {
|
||||||
return false
|
if filename < h.start.GetFilename() {
|
||||||
|
return false
|
||||||
|
} else if filename == h.start.GetFilename() {
|
||||||
|
// A tree may have a lot of nodes with the same filename but different versions so that
|
||||||
|
// len(nodes) > batch_size. The cut nodes should be pushed into the result on repeated call
|
||||||
|
// with the same filename.
|
||||||
|
pos := slices.Index(id, h.start.GetNode())
|
||||||
|
if pos == -1 || pos+1 >= len(id) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
id = id[pos+1:]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*h.h = append(*h.h, heapInfo{id: id, filename: filename})
|
*h.h = append(*h.h, heapInfo{id: id, filename: filename})
|
||||||
|
|
|
@ -85,11 +85,15 @@ const (
|
||||||
type Cursor struct {
|
type Cursor struct {
|
||||||
// Last traversed filename.
|
// Last traversed filename.
|
||||||
filename string
|
filename string
|
||||||
|
|
||||||
|
// Last traversed node.
|
||||||
|
node Node
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCursor(filename string) *Cursor {
|
func NewCursor(filename string, node Node) *Cursor {
|
||||||
return &Cursor{
|
return &Cursor{
|
||||||
filename: filename,
|
filename: filename,
|
||||||
|
node: node,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,6 +104,13 @@ func (c *Cursor) GetFilename() string {
|
||||||
return c.filename
|
return c.filename
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Cursor) GetNode() Node {
|
||||||
|
if c == nil {
|
||||||
|
return Node(0)
|
||||||
|
}
|
||||||
|
return c.node
|
||||||
|
}
|
||||||
|
|
||||||
// CIDDescriptor contains container ID and information about the node position
|
// CIDDescriptor contains container ID and information about the node position
|
||||||
// in the list of container nodes.
|
// in the list of container nodes.
|
||||||
type CIDDescriptor struct {
|
type CIDDescriptor struct {
|
||||||
|
|
Loading…
Add table
Reference in a new issue