diff --git a/pkg/services/object/util/chain.go b/pkg/services/object/util/chain.go index e6ec9363..96dafd10 100644 --- a/pkg/services/object/util/chain.go +++ b/pkg/services/object/util/chain.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" + cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" ) @@ -72,7 +73,6 @@ func TraverseSplitChain(r HeadReceiver, addr oid.Address, h SplitMemberHandler) return err } -// nolint: funlen, gocognit func traverseSplitChain(r HeadReceiver, addr oid.Address, h SplitMemberHandler) (bool, error) { v, err := r.Head(addr) if err != nil { @@ -94,80 +94,89 @@ func traverseSplitChain(r HeadReceiver, addr oid.Address, h SplitMemberHandler) default: return false, errors.New("lack of split information") case withLink: - var addr oid.Address - addr.SetContainer(cnr) - addr.SetObject(link) - - chain := make([]oid.ID, 0) - - if _, err := traverseSplitChain(r, addr, func(member *object.Object, reverseDirection bool) (stop bool) { - children := member.Children() - - if reverseDirection { - chain = append(children, chain...) - } else { - chain = append(chain, children...) - } - - return false - }); err != nil { - return false, err - } - - var reverseChain []*object.Object - - for i := range chain { - addr.SetObject(chain[i]) - - if stop, err := traverseSplitChain(r, addr, func(member *object.Object, reverseDirection bool) (stop bool) { - if !reverseDirection { - return h(member, false) - } - - reverseChain = append(reverseChain, member) - return false - }); err != nil || stop { - return stop, err - } - } - - for i := len(reverseChain) - 1; i >= 0; i-- { - if h(reverseChain[i], false) { - return true, nil - } - } + return traverseByLink(cnr, link, r, h) case withLast: - var addr oid.Address - addr.SetContainer(cnr) + return traverseByLast(cnr, last, withLast, res, r, h) + } + } +} - for last, withLast = res.LastPart(); withLast; { - addr.SetObject(last) +func traverseByLink(cnr cid.ID, link oid.ID, r HeadReceiver, h SplitMemberHandler) (bool, error) { + var addr oid.Address + addr.SetContainer(cnr) + addr.SetObject(link) - var directChain []*object.Object + chain := make([]oid.ID, 0) - if _, err := traverseSplitChain(r, addr, func(member *object.Object, reverseDirection bool) (stop bool) { - if reverseDirection { - last, withLast = member.PreviousID() - return h(member, true) - } + if _, err := traverseSplitChain(r, addr, func(member *object.Object, reverseDirection bool) (stop bool) { + children := member.Children() - directChain = append(directChain, member) + if reverseDirection { + chain = append(children, chain...) + } else { + chain = append(chain, children...) + } - return false - }); err != nil { - return false, err - } + return false + }); err != nil { + return false, err + } - for i := len(directChain) - 1; i >= 0; i-- { - if h(directChain[i], true) { - return true, nil - } - } + var reverseChain []*object.Object - if len(directChain) > 0 { - last, withLast = directChain[len(directChain)-1].PreviousID() - } + for i := range chain { + addr.SetObject(chain[i]) + + if stop, err := traverseSplitChain(r, addr, func(member *object.Object, reverseDirection bool) (stop bool) { + if !reverseDirection { + return h(member, false) } + + reverseChain = append(reverseChain, member) + return false + }); err != nil || stop { + return stop, err + } + } + + for i := len(reverseChain) - 1; i >= 0; i-- { + if h(reverseChain[i], false) { + return true, nil + } + } + return false, nil +} + +func traverseByLast(cnr cid.ID, last oid.ID, withLast bool, res *object.SplitInfo, r HeadReceiver, h SplitMemberHandler) (bool, error) { + var addr oid.Address + addr.SetContainer(cnr) + + for last, withLast = res.LastPart(); withLast; { + addr.SetObject(last) + + var directChain []*object.Object + + if _, err := traverseSplitChain(r, addr, func(member *object.Object, reverseDirection bool) (stop bool) { + if reverseDirection { + last, withLast = member.PreviousID() + return h(member, true) + } + + directChain = append(directChain, member) + + return false + }); err != nil { + return false, err + } + + for i := len(directChain) - 1; i >= 0; i-- { + if h(directChain[i], true) { + return true, nil + } + } + + if len(directChain) > 0 { + last, withLast = directChain[len(directChain)-1].PreviousID() } }