@@ -3,6 +3,7 @@ package blockstore
3
3
import (
4
4
"context"
5
5
6
+ lru "github.com/hashicorp/golang-lru/v2"
6
7
blocks "github.com/ipfs/go-block-format"
7
8
"github.com/ipfs/go-cid"
8
9
"golang.org/x/xerrors"
@@ -15,14 +16,22 @@ type ChainIO interface {
15
16
}
16
17
17
18
type apiBlockstore struct {
18
- api ChainIO
19
+ api ChainIO
20
+ cache * lru.Cache [cid.Cid , []byte ]
19
21
}
20
22
21
23
// This blockstore is adapted in the constructor.
22
24
var _ BasicBlockstore = (* apiBlockstore )(nil )
23
25
24
26
func NewAPIBlockstore (cio ChainIO ) Blockstore {
25
- bs := & apiBlockstore {api : cio }
27
+ lc , err := lru.New [cid.Cid , []byte ](1024 ) // we mostly come here for short-lived CLI applications so 1024 is a compromise size
28
+ if err != nil {
29
+ panic (err ) // should never happen, only errors if size is <= 0
30
+ }
31
+ bs := & apiBlockstore {
32
+ api : cio ,
33
+ cache : lc ,
34
+ }
26
35
return Adapt (bs ) // return an adapted blockstore.
27
36
}
28
37
@@ -31,31 +40,44 @@ func (a *apiBlockstore) DeleteBlock(context.Context, cid.Cid) error {
31
40
}
32
41
33
42
func (a * apiBlockstore ) Has (ctx context.Context , c cid.Cid ) (bool , error ) {
43
+ if a .cache .Contains (c ) {
44
+ return true , nil
45
+ }
34
46
return a .api .ChainHasObj (ctx , c )
35
47
}
36
48
37
49
func (a * apiBlockstore ) Get (ctx context.Context , c cid.Cid ) (blocks.Block , error ) {
50
+ if bb , ok := a .cache .Get (c ); ok {
51
+ return blocks .NewBlockWithCid (bb , c )
52
+ }
38
53
bb , err := a .api .ChainReadObj (ctx , c )
39
54
if err != nil {
40
55
return nil , err
41
56
}
57
+ a .cache .ContainsOrAdd (c , bb )
42
58
return blocks .NewBlockWithCid (bb , c )
43
59
}
44
60
45
61
func (a * apiBlockstore ) GetSize (ctx context.Context , c cid.Cid ) (int , error ) {
62
+ if bb , ok := a .cache .Peek (c ); ok {
63
+ return len (bb ), nil
64
+ }
46
65
bb , err := a .api .ChainReadObj (ctx , c )
47
66
if err != nil {
48
67
return 0 , err
49
68
}
69
+ a .cache .ContainsOrAdd (c , bb )
50
70
return len (bb ), nil
51
71
}
52
72
53
73
func (a * apiBlockstore ) Put (ctx context.Context , block blocks.Block ) error {
74
+ a .cache .Add (block .Cid (), block .RawData ())
54
75
return a .api .ChainPutObj (ctx , block )
55
76
}
56
77
57
78
func (a * apiBlockstore ) PutMany (ctx context.Context , blocks []blocks.Block ) error {
58
79
for _ , block := range blocks {
80
+ a .cache .Add (block .Cid (), block .RawData ())
59
81
err := a .api .ChainPutObj (ctx , block )
60
82
if err != nil {
61
83
return err
@@ -68,6 +90,4 @@ func (a *apiBlockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error)
68
90
return nil , xerrors .New ("not supported" )
69
91
}
70
92
71
- func (a * apiBlockstore ) HashOnRead (enabled bool ) {
72
- return
73
- }
93
+ func (a * apiBlockstore ) HashOnRead (bool ) {}
0 commit comments