package dataobj import ( "context" "fmt" "io" "math" "github.com/thanos-io/objstore" ) // rangeReader is an interface that can read a range of bytes from an object. type rangeReader interface { // Size returns the full size of the object. Size(ctx context.Context) (int64, error) // ReadRange returns a reader over a range of bytes. Callers may create // multiple current instance of ReadRange. ReadRange(ctx context.Context, offset int64, length int64) (io.ReadCloser, error) } type bucketRangeReader struct { bucket objstore.BucketReader path string } func (rr *bucketRangeReader) Size(ctx context.Context) (int64, error) { attrs, err := rr.bucket.Attributes(ctx, rr.path) if err != nil { return 0, fmt.Errorf("reading attributes: %w", err) } return attrs.Size, nil } func (rr *bucketRangeReader) ReadRange(ctx context.Context, offset int64, length int64) (io.ReadCloser, error) { return rr.bucket.GetRange(ctx, rr.path, offset, length) } type readerAtRangeReader struct { size int64 r io.ReaderAt } func (rr *readerAtRangeReader) Size(_ context.Context) (int64, error) { return rr.size, nil } func (rr *readerAtRangeReader) ReadRange(_ context.Context, offset int64, length int64) (io.ReadCloser, error) { if length > math.MaxInt { return nil, fmt.Errorf("length too large: %d", length) } return io.NopCloser(io.NewSectionReader(rr.r, offset, length)), nil }