Skip to content

Commit

Permalink
Add example blockstore examples
Browse files Browse the repository at this point in the history
Implement examples that show how to open a read-only blockstore, and a
read-write blockstore along with resumption from the same file.

Fixes:
- #124
  • Loading branch information
masih committed Jul 16, 2021
1 parent aa62719 commit 1798caf
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 0 deletions.
146 changes: 146 additions & 0 deletions v2/blockstore/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package blockstore_test

import (
"context"
"fmt"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-merkledag"
carv2 "github.com/ipld/go-car/v2"
"github.com/ipld/go-car/v2/blockstore"
)

// ExampleOpenReadOnly opens a read-only blockstore from a CARv1 file, and prints its root CIDs
// along with CID mapping to raw data size of blocks for first five sections in the CAR file.
func ExampleOpenReadOnly() {
// Open a new ReadOnly blockstore from a CARv1 file.
// Note, `OpenReadOnly` accepts bot CARv1 and CARv2 formats and transparently generate index
// in the background if necessary.
// This instance sets ZeroLengthSectionAsEOF option to treat zero sized sections in file as EOF.
robs, err := blockstore.OpenReadOnly("../testdata/sample-v1.car", carv2.ZeroLengthSectionAsEOF)
if err != nil {
panic(err)
}
defer func() {
if err := robs.Close(); err != nil {
panic(err)
}
}()

// Print root CIDs.
roots, err := robs.Roots()
if err != nil {
panic(err)
}
fmt.Printf("Contains %v root CID(s):\n", len(roots))
for _, r := range roots {
fmt.Printf("\t%v\n", r)
}

// Print the raw data size for the first 5 CIDs in the CAR file.
keysChan, err := robs.AllKeysChan(context.Background())
if err != nil {
panic(err)
}
fmt.Println("List of first 5 CIDs and their raw data size:")
var i int
for k := range keysChan {
if i > 4 {
break
}
size, err := robs.GetSize(k)
if err != nil {
panic(err)
}
fmt.Printf("\t%v -> %v bytes\n", k, size)
i++
}

// Output:
// Contains 1 root CID(s):
// bafy2bzaced4ueelaegfs5fqu4tzsh6ywbbpfk3cxppupmxfdhbpbhzawfw5oy
// List of first 5 CIDs and their raw data size:
// bafy2bzaced4ueelaegfs5fqu4tzsh6ywbbpfk3cxppupmxfdhbpbhzawfw5oy -> 821 bytes
// bafy2bzaceaycv7jhaegckatnncu5yugzkrnzeqsppzegufr35lroxxnsnpspu -> 1053 bytes
// bafy2bzaceb62wdepofqu34afqhbcn4a7jziwblt2ih5hhqqm6zitd3qpzhdp4 -> 1094 bytes
// bafy2bzaceb3utcspm5jqcdqpih3ztbaztv7yunzkiyfq7up7xmokpxemwgu5u -> 1051 bytes
// bafy2bzacedjwekyjresrwjqj4n2r5bnuuu3klncgjo2r3slsp6wgqb37sz4ck -> 821 bytes
}

// ExampleOpenReadWrite creates a read-write blockstore and puts
func ExampleOpenReadWrite() {

thisBlock := merkledag.NewRawNode([]byte("fish")).Block
thatBlock := merkledag.NewRawNode([]byte("lobster")).Block
andTheOtherBlock := merkledag.NewRawNode([]byte("barreleye")).Block

dest := "../testdata/sample-rw-bs-v2.car"
roots := []cid.Cid{thisBlock.Cid(), thatBlock.Cid(), andTheOtherBlock.Cid()}

rwbs, err := blockstore.OpenReadWrite(dest, roots, carv2.UseDataPadding(1413), carv2.UseIndexPadding(42))
if err != nil {
panic(err)
}
defer rwbs.Close()

// Put all blocks onto the blockstore.
blocks := []blocks.Block{thisBlock, thatBlock}
if err := rwbs.PutMany(blocks); err != nil {
panic(err)
}
fmt.Printf("Successfully wrote %v blocks into the blockstore.\n", len(blocks))

// Any blocks put can be read back using the same blockstore instance.
block, err := rwbs.Get(thatBlock.Cid())
if err != nil {
panic(err)
}
fmt.Printf("Read back block just put with raw value of `%v`.\n", string(block.RawData()))

// Finalize the blockstore to flush out the index and make a complete CARv2.
if err = rwbs.Finalize(); err != nil {
panic(err)
}

// Resume from the same file to add more blocks.
// Note the UseDataPadding and roots must match the values passed to the blockstore instance
// that created the original file. Otherwise, we cannot resume from the same file.
resumedRwbos, err := blockstore.OpenReadWrite(dest, roots, carv2.UseDataPadding(1413))
if err != nil {
panic(err)
}
defer resumedRwbos.Close()

// Put another block, appending it to the set of blocks that are written previously.
if err = resumedRwbos.Put(andTheOtherBlock); err != nil {
panic(err)
}

// Read back the the block put before resumption.
// Blocks previously put are present.
block, err = resumedRwbos.Get(thatBlock.Cid())
if err != nil {
panic(err)
}
fmt.Printf("Resumed blockstore contains blocks put previously with raw value of `%v`.\n", string(block.RawData()))

// Put an additional block to the CAR.
// Blocks put after resumption are also present.
block, err = resumedRwbos.Get(andTheOtherBlock.Cid())
if err != nil {
panic(err)
}
fmt.Printf("It also contains the block put after resumption with raw value of `%v`.\n", string(block.RawData()))

// Finalize the blockstore to flush out the index and make a complete CARv2.
// Note, Finalize must be called on an open ReadWrite blockstore to flush out a complete CARv2.
if err = resumedRwbos.Finalize(); err != nil {
panic(err)
}

// Output:
// Successfully wrote 2 blocks into the blockstore.
// Read back block just put with raw value of `lobster`.
// Resumed blockstore contains blocks put previously with raw value of `lobster`.
// It also contains the block put after resumption with raw value of `barreleye`.
}
Binary file added v2/testdata/sample-rw-bs-v2.car
Binary file not shown.

0 comments on commit 1798caf

Please sign in to comment.