frostfs-node/pkg/services/object/get/assembler_range.go
Evgenii Stratonikov 57dc0a8e9e [#1616] getsvc: Move break condition from body to the loop condition
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2025-01-30 06:50:37 +00:00

87 lines
2.4 KiB
Go

package getsvc
import (
"context"
"slices"
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
}
slices.Reverse(chain)
slices.Reverse(rngs)
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 && from < a.currentOffset {
head, err := a.objGetter.HeadObject(ctx, prevID)
if err != nil {
return nil, nil, err
}
if !a.isChild(head) {
return nil, nil, errParentAddressDiffers
}
nextOffset := a.currentOffset - head.PayloadSize()
clampedFrom := max(from, nextOffset)
clampedTo := min(to, a.currentOffset)
if clampedFrom < clampedTo {
index := len(rngs)
rngs = append(rngs, objectSDK.Range{})
rngs[index].SetOffset(clampedFrom - nextOffset)
rngs[index].SetLength(clampedTo - clampedFrom)
id, _ := head.ID()
chain = append(chain, id)
}
a.currentOffset = nextOffset
prevID, hasPrev = head.PreviousID()
}
return chain, rngs, nil
}