package getsvc import ( "context" objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" ) func (a *assembler) assembleObjectByChildrenListRange(ctx context.Context, childrenIDs []oid.ID, writer ObjectWriter) error { if err := a.assemblePayloadInReverseRange(ctx, writer, childrenIDs[len(childrenIDs)-1]); err != nil { return err } return writer.WriteChunk(ctx, a.parentObject.Payload()) } func (a *assembler) assemleObjectByPreviousIDInReverseRange(ctx context.Context, prevID oid.ID, writer ObjectWriter) error { if err := a.assemblePayloadInReverseRange(ctx, writer, prevID); err != nil { return err } if err := writer.WriteChunk(ctx, a.parentObject.Payload()); err != nil { // last part return err } return nil } func (a *assembler) assemblePayloadByObjectIDsRange(ctx context.Context, writer ObjectWriter, partIDs []oid.ID, partRanges []objectSDK.Range) error { for i := range partIDs { _, err := a.getChildObject(ctx, partIDs[i], &partRanges[i], false, writer) if err != nil { return err } } return nil } func (a *assembler) assemblePayloadInReverseRange(ctx context.Context, writer ObjectWriter, prevID oid.ID) error { chain, rngs, err := a.buildChainRange(ctx, prevID) if err != nil { return err } for left, right := 0, len(chain)-1; left < right; left, right = left+1, right-1 { chain[left], chain[right] = chain[right], chain[left] rngs[left], rngs[right] = rngs[right], rngs[left] } return a.assemblePayloadByObjectIDsRange(ctx, writer, chain, rngs) } func (a *assembler) buildChainRange(ctx context.Context, prevID oid.ID) ([]oid.ID, []objectSDK.Range, error) { var ( chain []oid.ID rngs []objectSDK.Range from = a.rng.GetOffset() to = from + a.rng.GetLength() hasPrev = true ) // fill the chain end-to-start for hasPrev { if a.currentOffset <= from { break } head, err := a.objGetter.HeadObject(ctx, prevID) if err != nil { return nil, nil, err } if !a.isChild(head) { return nil, nil, errParentAddressDiffers } sz := head.PayloadSize() a.currentOffset -= sz if a.currentOffset < to { off := uint64(0) if from > a.currentOffset { off = from - a.currentOffset sz -= from - a.currentOffset } if to < a.currentOffset+off+sz { sz = to - off - a.currentOffset } index := len(rngs) rngs = append(rngs, objectSDK.Range{}) rngs[index].SetOffset(off) rngs[index].SetLength(sz) id, _ := head.ID() chain = append(chain, id) } prevID, hasPrev = head.PreviousID() } return chain, rngs, nil }