forked from TrueCloudLab/frostfs-node
[#335] treesvc: Sort nodes by Filename in GetSubTree
Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
parent
94df541426
commit
b4e72a2dfd
12 changed files with 565 additions and 329 deletions
|
@ -5,6 +5,7 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
|
@ -440,7 +441,15 @@ func (s *Service) GetSubTree(req *GetSubTreeRequest, srv TreeService_GetSubTreeS
|
|||
func getSubTree(ctx context.Context, srv TreeService_GetSubTreeServer, cid cidSDK.ID, b *GetSubTreeRequest_Body, forest pilorama.Forest) error {
|
||||
// Traverse the tree in a DFS manner. Because we need to support arbitrary depth,
|
||||
// recursive implementation is not suitable here, so we maintain explicit stack.
|
||||
stack := [][]uint64{{b.GetRootId()}}
|
||||
m, p, err := forest.TreeGetMeta(ctx, cid, b.GetTreeId(), b.GetRootId())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stack := [][]pilorama.NodeInfo{{{
|
||||
ID: b.GetRootId(),
|
||||
Meta: m,
|
||||
ParentID: p,
|
||||
}}}
|
||||
|
||||
for {
|
||||
if len(stack) == 0 {
|
||||
|
@ -450,19 +459,15 @@ func getSubTree(ctx context.Context, srv TreeService_GetSubTreeServer, cid cidSD
|
|||
continue
|
||||
}
|
||||
|
||||
nodeID := stack[len(stack)-1][0]
|
||||
node := stack[len(stack)-1][0]
|
||||
stack[len(stack)-1] = stack[len(stack)-1][1:]
|
||||
|
||||
m, p, err := forest.TreeGetMeta(ctx, cid, b.GetTreeId(), nodeID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = srv.Send(&GetSubTreeResponse{
|
||||
Body: &GetSubTreeResponse_Body{
|
||||
NodeId: nodeID,
|
||||
ParentId: p,
|
||||
Timestamp: m.Time,
|
||||
Meta: metaToProto(m.Items),
|
||||
NodeId: node.ID,
|
||||
ParentId: node.ParentID,
|
||||
Timestamp: node.Meta.Time,
|
||||
Meta: metaToProto(node.Meta.Items),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -470,7 +475,11 @@ func getSubTree(ctx context.Context, srv TreeService_GetSubTreeServer, cid cidSD
|
|||
}
|
||||
|
||||
if b.GetDepth() == 0 || uint32(len(stack)) < b.GetDepth() {
|
||||
children, err := forest.TreeGetChildren(ctx, cid, b.GetTreeId(), nodeID)
|
||||
children, err := forest.TreeGetChildren(ctx, cid, b.GetTreeId(), node.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
children, err = sortByFilename(children, b.GetOrderBy().GetDirection())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -482,6 +491,24 @@ func getSubTree(ctx context.Context, srv TreeService_GetSubTreeServer, cid cidSD
|
|||
return nil
|
||||
}
|
||||
|
||||
func sortByFilename(nodes []pilorama.NodeInfo, d GetSubTreeRequest_Body_Order_Direction) ([]pilorama.NodeInfo, error) {
|
||||
switch d {
|
||||
case GetSubTreeRequest_Body_Order_None:
|
||||
return nodes, nil
|
||||
case GetSubTreeRequest_Body_Order_Asc:
|
||||
if len(nodes) == 0 {
|
||||
return nodes, nil
|
||||
}
|
||||
less := func(i, j int) bool {
|
||||
return bytes.Compare(nodes[i].Meta.GetAttr(pilorama.AttributeFilename), nodes[j].Meta.GetAttr(pilorama.AttributeFilename)) < 0
|
||||
}
|
||||
sort.Slice(nodes, less)
|
||||
return nodes, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported order direction: %s", d.String())
|
||||
}
|
||||
}
|
||||
|
||||
// Apply locally applies operation from the remote node to the tree.
|
||||
func (s *Service) Apply(_ context.Context, req *ApplyRequest) (*ApplyResponse, error) {
|
||||
err := verifyMessage(req)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue