From 3b44bb05f74ebd2734f12808c813dae2995b41b1 Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Sat, 21 Feb 2026 00:11:00 +0800 Subject: objectdb: Add Reader-based methods --- objectdb/chain.go | 37 +++++++++++++++++++++++++++++++++++++ objectdb/objectdb.go | 7 +++++++ 2 files changed, 44 insertions(+) (limited to 'objectdb') diff --git a/objectdb/chain.go b/objectdb/chain.go index 8e2d8527..f69b77c1 100644 --- a/objectdb/chain.go +++ b/objectdb/chain.go @@ -3,6 +3,7 @@ package objectdb import ( "errors" "fmt" + "io" "codeberg.org/lindenii/furgit/objectid" "codeberg.org/lindenii/furgit/objecttype" @@ -56,6 +57,42 @@ func (chain *Chain) ReadBytesContent(id objectid.ObjectID) (objecttype.Type, []b return objecttype.TypeInvalid, nil, ErrObjectNotFound } +// ReadReaderFull reads a full serialized object stream from the first backend that has it. +func (chain *Chain) ReadReaderFull(id objectid.ObjectID) (io.ReadCloser, error) { + for i, backend := range chain.backends { + if backend == nil { + continue + } + reader, err := backend.ReadReaderFull(id) + if err == nil { + return reader, nil + } + if errors.Is(err, ErrObjectNotFound) { + continue + } + return nil, fmt.Errorf("objectdb: backend %d read reader full: %w", i, err) + } + return nil, ErrObjectNotFound +} + +// ReadReaderContent reads an object's type and content stream from the first backend that has it. +func (chain *Chain) ReadReaderContent(id objectid.ObjectID) (objecttype.Type, io.ReadCloser, error) { + for i, backend := range chain.backends { + if backend == nil { + continue + } + ty, reader, err := backend.ReadReaderContent(id) + if err == nil { + return ty, reader, nil + } + if errors.Is(err, ErrObjectNotFound) { + continue + } + return objecttype.TypeInvalid, nil, fmt.Errorf("objectdb: backend %d read reader content: %w", i, err) + } + return objecttype.TypeInvalid, nil, ErrObjectNotFound +} + // ReadHeader reads object header data from the first backend that has it. func (chain *Chain) ReadHeader(id objectid.ObjectID) (objecttype.Type, int64, error) { for i, backend := range chain.backends { diff --git a/objectdb/objectdb.go b/objectdb/objectdb.go index 3e45893a..6e1fbded 100644 --- a/objectdb/objectdb.go +++ b/objectdb/objectdb.go @@ -3,6 +3,7 @@ package objectdb import ( "errors" + "io" "codeberg.org/lindenii/furgit/objectid" "codeberg.org/lindenii/furgit/objecttype" @@ -19,6 +20,12 @@ type ObjectDB interface { ReadBytesFull(id objectid.ObjectID) ([]byte, error) // ReadBytesContent reads an object's type and content bytes. ReadBytesContent(id objectid.ObjectID) (objecttype.Type, []byte, error) + // ReadReaderFull reads a full serialized object stream as "type size\\x00content". + // Caller must close the returned reader. + ReadReaderFull(id objectid.ObjectID) (io.ReadCloser, error) + // ReadReaderContent reads an object's type and content stream. + // Caller must close the returned reader. + ReadReaderContent(id objectid.ObjectID) (objecttype.Type, io.ReadCloser, error) // ReadHeader reads an object's type and declared content length. ReadHeader(id objectid.ObjectID) (objecttype.Type, int64, error) // Close releases resources associated with the backend. -- cgit v1.3.1-10-gc9f91