Skip to content
This repository was archived by the owner on Jun 19, 2023. It is now read-only.

Commit b44bb1f

Browse files
committed
fix(arc): Per-CID locking. KeyMutex
- fixes #64
1 parent fb07d7b commit b44bb1f

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-2
lines changed

arc_cache.go

+20-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package blockstore
33
import (
44
"context"
55

6+
"github.com/gammazero/kmutex"
67
lru "github.com/hashicorp/golang-lru"
78
blocks "github.com/ipfs/go-block-format"
89
cid "github.com/ipfs/go-cid"
@@ -17,7 +18,9 @@ type cacheSize int
1718
// size. This provides block access-time improvements, allowing
1819
// to short-cut many searches without querying the underlying datastore.
1920
type arccache struct {
20-
cache *lru.TwoQueueCache
21+
cache *lru.TwoQueueCache
22+
arcKMutex *kmutex.Kmutex
23+
2124
blockstore Blockstore
2225
viewer Viewer
2326

@@ -33,7 +36,7 @@ func newARCCachedBS(ctx context.Context, bs Blockstore, lruSize int) (*arccache,
3336
if err != nil {
3437
return nil, err
3538
}
36-
c := &arccache{cache: cache, blockstore: bs}
39+
c := &arccache{cache: cache, arcKMutex: kmutex.New(), blockstore: bs}
3740
c.hits = metrics.NewCtx(ctx, "arc.hits_total", "Number of ARC cache hits").Counter()
3841
c.total = metrics.NewCtx(ctx, "arc_total", "Total number of ARC cache requests").Counter()
3942
if v, ok := bs.(Viewer); ok {
@@ -47,6 +50,9 @@ func (b *arccache) DeleteBlock(k cid.Cid) error {
4750
return nil
4851
}
4952

53+
b.arcKMutex.Lock(k)
54+
defer b.arcKMutex.Unlock(k)
55+
5056
b.cache.Remove(k) // Invalidate cache before deleting.
5157
err := b.blockstore.DeleteBlock(k)
5258
if err == nil {
@@ -79,6 +85,10 @@ func (b *arccache) GetSize(k cid.Cid) (int, error) {
7985
}
8086
// we have it but don't know the size, ask the datastore.
8187
}
88+
89+
b.arcKMutex.Lock(k)
90+
defer b.arcKMutex.Unlock(k)
91+
8292
blockSize, err := b.blockstore.GetSize(k)
8393
if err == ErrNotFound {
8494
b.cacheHave(k, false)
@@ -123,6 +133,9 @@ func (b *arccache) Get(k cid.Cid) (blocks.Block, error) {
123133
return nil, ErrNotFound
124134
}
125135

136+
b.arcKMutex.Lock(k)
137+
defer b.arcKMutex.Unlock(k)
138+
126139
bl, err := b.blockstore.Get(k)
127140
if bl == nil && err == ErrNotFound {
128141
b.cacheHave(k, false)
@@ -137,6 +150,9 @@ func (b *arccache) Put(bl blocks.Block) error {
137150
return nil
138151
}
139152

153+
b.arcKMutex.Lock(bl.Cid())
154+
defer b.arcKMutex.Unlock(bl.Cid())
155+
140156
err := b.blockstore.Put(bl)
141157
if err == nil {
142158
b.cacheSize(bl.Cid(), len(bl.RawData()))
@@ -151,6 +167,7 @@ func (b *arccache) PutMany(bs []blocks.Block) error {
151167
// the block isn't in storage
152168
if has, _, ok := b.queryCache(block.Cid()); !ok || (ok && !has) {
153169
good = append(good, block)
170+
b.arcKMutex.Lock(block.Cid())
154171
}
155172
}
156173
err := b.blockstore.PutMany(good)
@@ -159,6 +176,7 @@ func (b *arccache) PutMany(bs []blocks.Block) error {
159176
}
160177
for _, block := range good {
161178
b.cacheSize(block.Cid(), len(block.RawData()))
179+
b.arcKMutex.Unlock(block.Cid())
162180
}
163181
return nil
164182
}

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module github.com/ipfs/go-ipfs-blockstore
22

33
require (
4+
github.com/gammazero/kmutex v1.0.1
45
github.com/hashicorp/golang-lru v0.5.4
56
github.com/ipfs/bbloom v0.0.4
67
github.com/ipfs/go-block-format v0.0.3

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
22
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
33
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
44
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5+
github.com/gammazero/kmutex v1.0.1 h1:69XUr2F8TRTnGrg5absRHwfspEJcW7ETro6inQJ21Yo=
6+
github.com/gammazero/kmutex v1.0.1/go.mod h1:Qxgwjh7K2RZFEcVRyjXBOUuHgR1hLskRnns+nzftpVQ=
57
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
68
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
79
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=

0 commit comments

Comments
 (0)