2020-04-20 16:53:19 +00:00
|
|
|
package cachebs
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
|
|
|
lru "github.com/hashicorp/golang-lru"
|
|
|
|
block "github.com/ipfs/go-block-format"
|
|
|
|
"github.com/ipfs/go-cid"
|
|
|
|
logging "github.com/ipfs/go-log/v2"
|
2020-07-23 02:05:11 +00:00
|
|
|
|
|
|
|
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
2020-04-20 16:53:19 +00:00
|
|
|
)
|
|
|
|
|
2020-08-20 04:49:10 +00:00
|
|
|
//nolint:deadcode,varcheck
|
2020-04-20 16:53:19 +00:00
|
|
|
var log = logging.Logger("cachebs")
|
|
|
|
|
|
|
|
type CacheBS struct {
|
|
|
|
cache *lru.ARCCache
|
|
|
|
bs bstore.Blockstore
|
|
|
|
}
|
|
|
|
|
2020-07-23 02:05:11 +00:00
|
|
|
func NewBufferedBstore(base bstore.Blockstore, size int) bstore.Blockstore {
|
2020-04-20 16:53:19 +00:00
|
|
|
c, err := lru.NewARC(size)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2020-07-23 02:05:11 +00:00
|
|
|
// Wrap this in an ID blockstore to avoid caching blocks inlined into
|
|
|
|
// CIDs.
|
|
|
|
return bstore.WrapIDStore(&CacheBS{
|
2020-04-20 16:53:19 +00:00
|
|
|
cache: c,
|
|
|
|
bs: base,
|
2020-07-23 02:05:11 +00:00
|
|
|
})
|
2020-04-20 16:53:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var _ (bstore.Blockstore) = &CacheBS{}
|
|
|
|
|
|
|
|
func (bs *CacheBS) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
|
|
|
|
return bs.bs.AllKeysChan(ctx)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bs *CacheBS) DeleteBlock(c cid.Cid) error {
|
2020-04-22 19:04:03 +00:00
|
|
|
bs.cache.Remove(c)
|
|
|
|
|
2020-04-20 16:53:19 +00:00
|
|
|
return bs.bs.DeleteBlock(c)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bs *CacheBS) Get(c cid.Cid) (block.Block, error) {
|
|
|
|
v, ok := bs.cache.Get(c)
|
|
|
|
if ok {
|
|
|
|
return v.(block.Block), nil
|
|
|
|
}
|
|
|
|
|
2020-05-29 22:15:59 +00:00
|
|
|
out, err := bs.bs.Get(c)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
bs.cache.Add(c, out)
|
|
|
|
return out, nil
|
2020-04-20 16:53:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (bs *CacheBS) GetSize(c cid.Cid) (int, error) {
|
|
|
|
return bs.bs.GetSize(c)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bs *CacheBS) Put(blk block.Block) error {
|
|
|
|
bs.cache.Add(blk.Cid(), blk)
|
|
|
|
|
|
|
|
return bs.bs.Put(blk)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bs *CacheBS) Has(c cid.Cid) (bool, error) {
|
|
|
|
if bs.cache.Contains(c) {
|
|
|
|
return true, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return bs.bs.Has(c)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bs *CacheBS) HashOnRead(hor bool) {
|
|
|
|
bs.bs.HashOnRead(hor)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bs *CacheBS) PutMany(blks []block.Block) error {
|
|
|
|
for _, blk := range blks {
|
|
|
|
bs.cache.Add(blk.Cid(), blk)
|
|
|
|
}
|
|
|
|
return bs.bs.PutMany(blks)
|
|
|
|
}
|