Skip to content

Commit

Permalink
Rename ReadOnlyOf to NewReadOnly and accept both v1 and v2 payload
Browse files Browse the repository at this point in the history
Rename the `blockstore.ReadOnlyOf` to `blockstore.NewReadOnly` for
better readability and consistent naming.

Allow the function to accept both v1 and v2 payloads and "do the right
thing" depending on the input.

Optionally, allow the caller to supply an index that, if present, will
overrider any existing index. Otherwise an in-memory index is generated.

Note, `blockstore.OpenReadOnly` only accepts v2 payload. Future PRs will
change this function to also accept both versions for consistency, and
drop modification of given path, delegating any writing to the
write-specific APIs like `index.Attach` and `index.Generate`.

Fixes #128


This commit was moved from ipld/go-car@4e863b2
  • Loading branch information
masih authored and mvdan committed Jul 16, 2021
1 parent 8ce2fa7 commit 10bd2b5
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 9 deletions.
7 changes: 3 additions & 4 deletions ipld/car/v2/blockstore/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
//
// The ReadOnly blockstore provides a read-only random access from a given data payload either in
// unindexed v1 format or indexed/unindexed v2 format:
// - ReadOnly.ReadOnlyOf can be used to instantiate a new read-only blockstore for a given CAR v1
// data payload and an existing index. See index.Generate for index generation from CAR v1
// payload.
// - ReadOnly.OpenReadOnly can be used to instantiate a new read-only blockstore for a given CAR v2
// * ReadOnly.NewReadOnly can be used to instantiate a new read-only blockstore for a given CAR v1
// or CAR v2 data payload with an optional index override.
// * ReadOnly.OpenReadOnly can be used to instantiate a new read-only blockstore for a given CAR v2
// file with automatic index generation if the index is not present in the given file. This
// function can optionally attach the index to the given CAR v2 file.
//
Expand Down
45 changes: 41 additions & 4 deletions ipld/car/v2/blockstore/readonly.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,47 @@ type ReadOnly struct {
carv2Closer io.Closer
}

// ReadOnlyOf opens ReadOnly blockstore from an existing backing containing a CAR v1 payload and an existing index.
// The index for a CAR v1 payload can be separately generated using index.Generate.
func ReadOnlyOf(backing io.ReaderAt, index index.Index) *ReadOnly {
return &ReadOnly{backing: backing, idx: index}
// NewReadOnly creates a new ReadOnly blockstore from the backing with a optional index as idx.
// This function accepts both CAR v1 and v2 backing.
// The blockstore is instantiated with the given index if it is not nil.
//
// Otherwise:
// * For a CAR v1 backing an index is generated.
// * For a CAR v2 backing an index is only generated if Header.HasIndex returns false.
//
// There is no need to call ReadOnly.Close on instances returned by this function.
func NewReadOnly(backing io.ReaderAt, idx index.Index) (*ReadOnly, error) {
version, err := carv2.ReadVersion(internalio.NewOffsetReader(backing, 0))
if err != nil {
return nil, err
}
switch version {
case 1:
if idx == nil {
if idx, err = index.Generate(backing); err != nil {
return nil, err
}
}
return &ReadOnly{backing: backing, idx: idx}, nil
case 2:
v2r, err := carv2.NewReader(backing)
if err != nil {
return nil, err
}
if idx == nil {
if v2r.Header.HasIndex() {
idx, err = index.ReadFrom(v2r.IndexReader())
if err != nil {
return nil, err
}
} else if idx, err = index.Generate(backing); err != nil {
return nil, err
}
}
return &ReadOnly{backing: v2r.CarV1Reader(), idx: idx}, nil
default:
return nil, fmt.Errorf("unsupported car version: %v", version)
}
}

// OpenReadOnly opens a read-only blockstore from a CAR v2 file, generating an index if it does not exist.
Expand Down
2 changes: 1 addition & 1 deletion ipld/car/v2/blockstore/readwrite.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func NewReadWrite(path string, roots []cid.Cid, opts ...Option) (*ReadWrite, err
}
b.carV1Writer = internalio.NewOffsetWriter(f, int64(b.header.CarV1Offset))
carV1Reader := internalio.NewOffsetReader(f, int64(b.header.CarV1Offset))
b.ReadOnly = *ReadOnlyOf(carV1Reader, idx)
b.ReadOnly = ReadOnly{backing: carV1Reader, idx: idx}
if _, err := f.WriteAt(carv2.Pragma, 0); err != nil {
return nil, err
}
Expand Down

0 comments on commit 10bd2b5

Please sign in to comment.