Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 25 additions & 5 deletions blockstore/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package blockstore
import (
"context"

lru "github.com/hashicorp/golang-lru/v2"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"
Expand All @@ -15,14 +16,22 @@ type ChainIO interface {
}

type apiBlockstore struct {
api ChainIO
api ChainIO
cache *lru.Cache[cid.Cid, []byte]
}

// This blockstore is adapted in the constructor.
var _ BasicBlockstore = (*apiBlockstore)(nil)

func NewAPIBlockstore(cio ChainIO) Blockstore {
bs := &apiBlockstore{api: cio}
lc, err := lru.New[cid.Cid, []byte](1024) // we mostly come here for short-lived CLI applications so 1024 is a compromise size
if err != nil {
panic(err) // should never happen, only errors if size is <= 0
}
bs := &apiBlockstore{
api: cio,
cache: lc,
}
return Adapt(bs) // return an adapted blockstore.
}

Expand All @@ -31,31 +40,44 @@ func (a *apiBlockstore) DeleteBlock(context.Context, cid.Cid) error {
}

func (a *apiBlockstore) Has(ctx context.Context, c cid.Cid) (bool, error) {
if a.cache.Contains(c) {
return true, nil
}
return a.api.ChainHasObj(ctx, c)
}

func (a *apiBlockstore) Get(ctx context.Context, c cid.Cid) (blocks.Block, error) {
if bb, ok := a.cache.Get(c); ok {
return blocks.NewBlockWithCid(bb, c)
}
bb, err := a.api.ChainReadObj(ctx, c)
if err != nil {
return nil, err
}
a.cache.ContainsOrAdd(c, bb)
return blocks.NewBlockWithCid(bb, c)
}

func (a *apiBlockstore) GetSize(ctx context.Context, c cid.Cid) (int, error) {
if bb, ok := a.cache.Peek(c); ok {
return len(bb), nil
}
bb, err := a.api.ChainReadObj(ctx, c)
if err != nil {
return 0, err
}
a.cache.ContainsOrAdd(c, bb)
return len(bb), nil
}

func (a *apiBlockstore) Put(ctx context.Context, block blocks.Block) error {
a.cache.Add(block.Cid(), block.RawData())
Comment thread
rvagg marked this conversation as resolved.
return a.api.ChainPutObj(ctx, block)
}

func (a *apiBlockstore) PutMany(ctx context.Context, blocks []blocks.Block) error {
for _, block := range blocks {
a.cache.Add(block.Cid(), block.RawData())
Comment thread
rvagg marked this conversation as resolved.
err := a.api.ChainPutObj(ctx, block)
if err != nil {
return err
Expand All @@ -68,6 +90,4 @@ func (a *apiBlockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error)
return nil, xerrors.New("not supported")
}

func (a *apiBlockstore) HashOnRead(enabled bool) {
return
}
func (a *apiBlockstore) HashOnRead(bool) {}