1
- // package blockstore implements a thin wrapper over a datastore, giving a
1
+ // Package blockstore implements a thin wrapper over a datastore, giving a
2
2
// clean interface for Getting and Putting block objects.
3
3
package blockstore
4
4
@@ -23,22 +23,36 @@ var log = logging.Logger("blockstore")
23
23
// BlockPrefix namespaces blockstore datastores
24
24
var BlockPrefix = ds .NewKey ("blocks" )
25
25
26
- var ValueTypeMismatch = errors .New ("the retrieved value is not a Block" )
26
+ // ErrValueTypeMismatch is an error returned when the item retrieved from
27
+ // the datatstore is not a block.
28
+ var ErrValueTypeMismatch = errors .New ("the retrieved value is not a Block" )
29
+
30
+ // ErrHashMismatch is an error returned when the hash of a block
31
+ // is different than expected.
27
32
var ErrHashMismatch = errors .New ("block in storage has different hash than requested" )
28
33
34
+ // ErrNotFound is an error returned when a block is not found.
29
35
var ErrNotFound = errors .New ("blockstore: block not found" )
30
36
31
- // Blockstore wraps a Datastore
37
+ // Blockstore wraps a Datastore block-centered methods and provides a layer
38
+ // of abstraction which allows to add different caching strategies.
32
39
type Blockstore interface {
33
40
DeleteBlock (* cid.Cid ) error
34
41
Has (* cid.Cid ) (bool , error )
35
42
Get (* cid.Cid ) (blocks.Block , error )
36
43
Put (blocks.Block ) error
37
44
PutMany ([]blocks.Block ) error
38
-
45
+ // AllKeysChan returns a channel from which
46
+ // the CIDs in the Blockstore can be read. It should respect
47
+ // the given context, closing the channel if it becomes Done.
39
48
AllKeysChan (ctx context.Context ) (<- chan * cid.Cid , error )
49
+ // HashOnRead specifies if every read block should be
50
+ // rehashed to make sure it matches its CID.
51
+ HashOnRead (enabled bool )
40
52
}
41
53
54
+ // GCLocker abstract functionality to lock a blockstore when performing
55
+ // garbage-collection operations.
42
56
type GCLocker interface {
43
57
// GCLock locks the blockstore for garbage collection. No operations
44
58
// that expect to finish with a pin should ocurr simultaneously.
@@ -56,11 +70,15 @@ type GCLocker interface {
56
70
GCRequested () bool
57
71
}
58
72
73
+ // GCBlockstore is a blockstore that can safely run garbage-collection
74
+ // operations.
59
75
type GCBlockstore interface {
60
76
Blockstore
61
77
GCLocker
62
78
}
63
79
80
+ // NewGCBlockstore returns a default implementation of GCBlockstore
81
+ // using the given Blockstore and GCLocker.
64
82
func NewGCBlockstore (bs Blockstore , gcl GCLocker ) GCBlockstore {
65
83
return gcBlockstore {bs , gcl }
66
84
}
@@ -70,7 +88,9 @@ type gcBlockstore struct {
70
88
GCLocker
71
89
}
72
90
73
- func NewBlockstore (d ds.Batching ) * blockstore {
91
+ // NewBlockstore returns a default Blockstore implementation
92
+ // using the provided datastore.Batching backend.
93
+ func NewBlockstore (d ds.Batching ) Blockstore {
74
94
var dsb ds.Batching
75
95
dd := dsns .Wrap (d , BlockPrefix )
76
96
dsb = dd
@@ -108,7 +128,7 @@ func (bs *blockstore) Get(k *cid.Cid) (blocks.Block, error) {
108
128
}
109
129
bdata , ok := maybeData .([]byte )
110
130
if ! ok {
111
- return nil , ValueTypeMismatch
131
+ return nil , ErrValueTypeMismatch
112
132
}
113
133
114
134
if bs .rehash {
@@ -122,9 +142,8 @@ func (bs *blockstore) Get(k *cid.Cid) (blocks.Block, error) {
122
142
}
123
143
124
144
return blocks .NewBlockWithCid (bdata , rbcid )
125
- } else {
126
- return blocks .NewBlockWithCid (bdata , k )
127
145
}
146
+ return blocks .NewBlockWithCid (bdata , k )
128
147
}
129
148
130
149
func (bs * blockstore ) Put (block blocks.Block ) error {
@@ -162,8 +181,8 @@ func (bs *blockstore) Has(k *cid.Cid) (bool, error) {
162
181
return bs .datastore .Has (dshelp .CidToDsKey (k ))
163
182
}
164
183
165
- func (s * blockstore ) DeleteBlock (k * cid.Cid ) error {
166
- err := s .datastore .Delete (dshelp .CidToDsKey (k ))
184
+ func (bs * blockstore ) DeleteBlock (k * cid.Cid ) error {
185
+ err := bs .datastore .Delete (dshelp .CidToDsKey (k ))
167
186
if err == ds .ErrNotFound {
168
187
return ErrNotFound
169
188
}
@@ -173,7 +192,7 @@ func (s *blockstore) DeleteBlock(k *cid.Cid) error {
173
192
// AllKeysChan runs a query for keys from the blockstore.
174
193
// this is very simplistic, in the future, take dsq.Query as a param?
175
194
//
176
- // AllKeysChan respects context
195
+ // AllKeysChan respects context.
177
196
func (bs * blockstore ) AllKeysChan (ctx context.Context ) (<- chan * cid.Cid , error ) {
178
197
179
198
// KeysOnly, because that would be _a lot_ of data.
@@ -220,7 +239,9 @@ func (bs *blockstore) AllKeysChan(ctx context.Context) (<-chan *cid.Cid, error)
220
239
return output , nil
221
240
}
222
241
223
- func NewGCLocker () * gclocker {
242
+ // NewGCLocker returns a default implementation of
243
+ // GCLocker using standard [RW] mutexes.
244
+ func NewGCLocker () GCLocker {
224
245
return & gclocker {}
225
246
}
226
247
@@ -230,6 +251,8 @@ type gclocker struct {
230
251
gcreqlk sync.Mutex
231
252
}
232
253
254
+ // Unlocker represents an object which can Unlock
255
+ // something.
233
256
type Unlocker interface {
234
257
Unlock ()
235
258
}
0 commit comments