package handler import ( "context" "errors" "strings" "git.frostfs.info/TrueCloudLab/frostfs-http-gw/internal/data" "git.frostfs.info/TrueCloudLab/frostfs-http-gw/tree" ) type nodeMeta struct { key string value []byte } func (m nodeMeta) GetKey() string { return m.key } func (m nodeMeta) GetValue() []byte { return m.value } type nodeResponse struct { meta []nodeMeta nodeID uint64 parentID uint64 timestamp uint64 } func (n nodeResponse) GetNodeID() []uint64 { return []uint64{n.nodeID} } func (n nodeResponse) GetParentID() []uint64 { return []uint64{n.parentID} } func (n nodeResponse) GetTimestamp() []uint64 { return []uint64{n.timestamp} } func (n nodeResponse) GetMeta() []tree.Meta { res := make([]tree.Meta, len(n.meta)) for i, value := range n.meta { res[i] = value } return res } type containerInfo struct { trees map[string]map[string]nodeResponse } type treeServiceClientMock struct { containers map[string]containerInfo } func newTreeServiceClientMock() *treeServiceClientMock { return &treeServiceClientMock{ containers: make(map[string]containerInfo), } } func (t *treeServiceClientMock) GetNodes(_ context.Context, p *tree.GetNodesParams) ([]tree.NodeResponse, error) { cnr, ok := t.containers[p.CnrID.EncodeToString()] if !ok { return nil, tree.ErrNodeNotFound } tr, ok := cnr.trees[p.TreeID] if !ok { return nil, tree.ErrNodeNotFound } node, ok := tr[strings.Join(p.Path, "/")] if !ok { return nil, tree.ErrNodeNotFound } return []tree.NodeResponse{node}, nil } func (t *treeServiceClientMock) GetSubTree(_ context.Context, bktInfo *data.BucketInfo, treeID string, rootID []uint64, depth uint32, _ bool) ([]tree.NodeResponse, error) { cnr, ok := t.containers[bktInfo.CID.EncodeToString()] if !ok { return nil, tree.ErrNodeNotFound } tr, ok := cnr.trees[treeID] if !ok { return nil, tree.ErrNodeNotFound } if len(rootID) != 1 { return nil, errors.New("invalid rootID") } var root *nodeResponse for _, v := range tr { if v.nodeID == rootID[0] { root = &v break } } if root == nil { return nil, tree.ErrNodeNotFound } var res []nodeResponse if depth == 0 { for _, v := range tr { res = append(res, v) } } else { res = append(res, *root) depthIndex := 0 for i := uint32(0); i < depth-1; i++ { childrenCount := 0 for _, v := range tr { for j := range res[depthIndex:] { if v.parentID == res[j].nodeID { res = append(res, v) childrenCount++ break } } } depthIndex = len(res) - childrenCount } } res2 := make([]tree.NodeResponse, len(res)) for i := range res { res2[i] = res[i] } return res2, nil }