@@ -38,10 +38,12 @@ import (
38
38
)
39
39
40
40
const (
41
+ // HashMurmur3 is the multiformats identifier for Murmur3
41
42
HashMurmur3 uint64 = 0x22
42
43
)
43
44
44
- type HamtShard struct {
45
+ // A Shard represents the HAMT. It should be initialized with NewShard().
46
+ type Shard struct {
45
47
nd * dag.ProtoNode
46
48
47
49
bitfield * big.Int
@@ -66,9 +68,9 @@ type child interface {
66
68
Label () string
67
69
}
68
70
69
- // NewHamtShard creates a new, empty HAMT shard with the given size.
70
- func NewHamtShard (dserv ipld.DAGService , size int ) (* HamtShard , error ) {
71
- ds , err := makeHamtShard (dserv , size )
71
+ // NewShard creates a new, empty HAMT shard with the given size.
72
+ func NewShard (dserv ipld.DAGService , size int ) (* Shard , error ) {
73
+ ds , err := makeShard (dserv , size )
72
74
if err != nil {
73
75
return nil , err
74
76
}
@@ -79,13 +81,13 @@ func NewHamtShard(dserv ipld.DAGService, size int) (*HamtShard, error) {
79
81
return ds , nil
80
82
}
81
83
82
- func makeHamtShard (ds ipld.DAGService , size int ) (* HamtShard , error ) {
84
+ func makeShard (ds ipld.DAGService , size int ) (* Shard , error ) {
83
85
lg2s := int (math .Log2 (float64 (size )))
84
86
if 1 << uint (lg2s ) != size {
85
87
return nil , fmt .Errorf ("hamt size should be a power of two" )
86
88
}
87
89
maxpadding := fmt .Sprintf ("%X" , size - 1 )
88
- return & HamtShard {
90
+ return & Shard {
89
91
tableSizeLg2 : lg2s ,
90
92
prefixPadStr : fmt .Sprintf ("%%0%dX" , len (maxpadding )),
91
93
maxpadlen : len (maxpadding ),
@@ -95,7 +97,7 @@ func makeHamtShard(ds ipld.DAGService, size int) (*HamtShard, error) {
95
97
}
96
98
97
99
// NewHamtFromDag creates new a HAMT shard from the given DAG.
98
- func NewHamtFromDag (dserv ipld.DAGService , nd ipld.Node ) (* HamtShard , error ) {
100
+ func NewHamtFromDag (dserv ipld.DAGService , nd ipld.Node ) (* Shard , error ) {
99
101
pbnd , ok := nd .(* dag.ProtoNode )
100
102
if ! ok {
101
103
return nil , dag .ErrLinkNotFound
@@ -114,7 +116,7 @@ func NewHamtFromDag(dserv ipld.DAGService, nd ipld.Node) (*HamtShard, error) {
114
116
return nil , fmt .Errorf ("only murmur3 supported as hash function" )
115
117
}
116
118
117
- ds , err := makeHamtShard (dserv , int (pbd .GetFanout ()))
119
+ ds , err := makeShard (dserv , int (pbd .GetFanout ()))
118
120
if err != nil {
119
121
return nil , err
120
122
}
@@ -129,17 +131,17 @@ func NewHamtFromDag(dserv ipld.DAGService, nd ipld.Node) (*HamtShard, error) {
129
131
}
130
132
131
133
// SetPrefix sets the CID Prefix
132
- func (ds * HamtShard ) SetPrefix (prefix * cid.Prefix ) {
134
+ func (ds * Shard ) SetPrefix (prefix * cid.Prefix ) {
133
135
ds .prefix = prefix
134
136
}
135
137
136
138
// Prefix gets the CID Prefix, may be nil if unset
137
- func (ds * HamtShard ) Prefix () * cid.Prefix {
139
+ func (ds * Shard ) Prefix () * cid.Prefix {
138
140
return ds .prefix
139
141
}
140
142
141
143
// Node serializes the HAMT structure into a merkledag node with unixfs formatting
142
- func (ds * HamtShard ) Node () (ipld.Node , error ) {
144
+ func (ds * Shard ) Node () (ipld.Node , error ) {
143
145
out := new (dag.ProtoNode )
144
146
out .SetPrefix (ds .prefix )
145
147
@@ -214,14 +216,14 @@ func hash(val []byte) []byte {
214
216
return h .Sum (nil )
215
217
}
216
218
217
- // Label for HamtShards is the empty string, this is used to differentiate them from
219
+ // Label for Shards is the empty string, this is used to differentiate them from
218
220
// value entries
219
- func (ds * HamtShard ) Label () string {
221
+ func (ds * Shard ) Label () string {
220
222
return ""
221
223
}
222
224
223
225
// Set sets 'name' = nd in the HAMT
224
- func (ds * HamtShard ) Set (ctx context.Context , name string , nd ipld.Node ) error {
226
+ func (ds * Shard ) Set (ctx context.Context , name string , nd ipld.Node ) error {
225
227
hv := & hashBits {b : hash ([]byte (name ))}
226
228
err := ds .dserv .Add (ctx , nd )
227
229
if err != nil {
@@ -238,13 +240,13 @@ func (ds *HamtShard) Set(ctx context.Context, name string, nd ipld.Node) error {
238
240
}
239
241
240
242
// Remove deletes the named entry if it exists, this operation is idempotent.
241
- func (ds * HamtShard ) Remove (ctx context.Context , name string ) error {
243
+ func (ds * Shard ) Remove (ctx context.Context , name string ) error {
242
244
hv := & hashBits {b : hash ([]byte (name ))}
243
245
return ds .modifyValue (ctx , hv , name , nil )
244
246
}
245
247
246
248
// Find searches for a child node by 'name' within this hamt
247
- func (ds * HamtShard ) Find (ctx context.Context , name string ) (* ipld.Link , error ) {
249
+ func (ds * Shard ) Find (ctx context.Context , name string ) (* ipld.Link , error ) {
248
250
hv := & hashBits {b : hash ([]byte (name ))}
249
251
250
252
var out * ipld.Link
@@ -262,7 +264,7 @@ func (ds *HamtShard) Find(ctx context.Context, name string) (*ipld.Link, error)
262
264
// getChild returns the i'th child of this shard. If it is cached in the
263
265
// children array, it will return it from there. Otherwise, it loads the child
264
266
// node from disk.
265
- func (ds * HamtShard ) getChild (ctx context.Context , i int ) (child , error ) {
267
+ func (ds * Shard ) getChild (ctx context.Context , i int ) (child , error ) {
266
268
if i >= len (ds .children ) || i < 0 {
267
269
return nil , fmt .Errorf ("invalid index passed to getChild (likely corrupt bitfield)" )
268
270
}
@@ -281,7 +283,7 @@ func (ds *HamtShard) getChild(ctx context.Context, i int) (child, error) {
281
283
282
284
// loadChild reads the i'th child node of this shard from disk and returns it
283
285
// as a 'child' interface
284
- func (ds * HamtShard ) loadChild (ctx context.Context , i int ) (child , error ) {
286
+ func (ds * Shard ) loadChild (ctx context.Context , i int ) (child , error ) {
285
287
lnk := ds .nd .Links ()[i ]
286
288
if len (lnk .Name ) < ds .maxpadlen {
287
289
return nil , fmt .Errorf ("invalid link name '%s'" , lnk .Name )
@@ -326,12 +328,12 @@ func (ds *HamtShard) loadChild(ctx context.Context, i int) (child, error) {
326
328
return c , nil
327
329
}
328
330
329
- func (ds * HamtShard ) setChild (i int , c child ) {
331
+ func (ds * Shard ) setChild (i int , c child ) {
330
332
ds .children [i ] = c
331
333
}
332
334
333
335
// Link returns a merklelink to this shard node
334
- func (ds * HamtShard ) Link () (* ipld.Link , error ) {
336
+ func (ds * Shard ) Link () (* ipld.Link , error ) {
335
337
nd , err := ds .Node ()
336
338
if err != nil {
337
339
return nil , err
@@ -345,7 +347,7 @@ func (ds *HamtShard) Link() (*ipld.Link, error) {
345
347
return ipld .MakeLink (nd )
346
348
}
347
349
348
- func (ds * HamtShard ) insertChild (idx int , key string , lnk * ipld.Link ) error {
350
+ func (ds * Shard ) insertChild (idx int , key string , lnk * ipld.Link ) error {
349
351
if lnk == nil {
350
352
return os .ErrNotExist
351
353
}
@@ -364,7 +366,7 @@ func (ds *HamtShard) insertChild(idx int, key string, lnk *ipld.Link) error {
364
366
return nil
365
367
}
366
368
367
- func (ds * HamtShard ) rmChild (i int ) error {
369
+ func (ds * Shard ) rmChild (i int ) error {
368
370
if i < 0 || i >= len (ds .children ) || i >= len (ds .nd .Links ()) {
369
371
return fmt .Errorf ("hamt: attempted to remove child with out of range index" )
370
372
}
@@ -378,7 +380,7 @@ func (ds *HamtShard) rmChild(i int) error {
378
380
return nil
379
381
}
380
382
381
- func (ds * HamtShard ) getValue (ctx context.Context , hv * hashBits , key string , cb func (* shardValue ) error ) error {
383
+ func (ds * Shard ) getValue (ctx context.Context , hv * hashBits , key string , cb func (* shardValue ) error ) error {
382
384
idx := hv .Next (ds .tableSizeLg2 )
383
385
if ds .bitfield .Bit (int (idx )) == 1 {
384
386
cindex := ds .indexForBitPos (idx )
@@ -389,7 +391,7 @@ func (ds *HamtShard) getValue(ctx context.Context, hv *hashBits, key string, cb
389
391
}
390
392
391
393
switch child := child .(type ) {
392
- case * HamtShard :
394
+ case * Shard :
393
395
return child .getValue (ctx , hv , key , cb )
394
396
case * shardValue :
395
397
if child .key == key {
@@ -401,7 +403,8 @@ func (ds *HamtShard) getValue(ctx context.Context, hv *hashBits, key string, cb
401
403
return os .ErrNotExist
402
404
}
403
405
404
- func (ds * HamtShard ) EnumLinks (ctx context.Context ) ([]* ipld.Link , error ) {
406
+ // EnumLinks collects all links in the Shard.
407
+ func (ds * Shard ) EnumLinks (ctx context.Context ) ([]* ipld.Link , error ) {
405
408
var links []* ipld.Link
406
409
err := ds .ForEachLink (ctx , func (l * ipld.Link ) error {
407
410
links = append (links , l )
@@ -410,7 +413,8 @@ func (ds *HamtShard) EnumLinks(ctx context.Context) ([]*ipld.Link, error) {
410
413
return links , err
411
414
}
412
415
413
- func (ds * HamtShard ) ForEachLink (ctx context.Context , f func (* ipld.Link ) error ) error {
416
+ // ForEachLink walks the Shard and calls the given function.
417
+ func (ds * Shard ) ForEachLink (ctx context.Context , f func (* ipld.Link ) error ) error {
414
418
return ds .walkTrie (ctx , func (sv * shardValue ) error {
415
419
lnk := sv .val
416
420
lnk .Name = sv .key
@@ -419,7 +423,7 @@ func (ds *HamtShard) ForEachLink(ctx context.Context, f func(*ipld.Link) error)
419
423
})
420
424
}
421
425
422
- func (ds * HamtShard ) walkTrie (ctx context.Context , cb func (* shardValue ) error ) error {
426
+ func (ds * Shard ) walkTrie (ctx context.Context , cb func (* shardValue ) error ) error {
423
427
for i := 0 ; i < ds .tableSize ; i ++ {
424
428
if ds .bitfield .Bit (i ) == 0 {
425
429
continue
@@ -440,7 +444,7 @@ func (ds *HamtShard) walkTrie(ctx context.Context, cb func(*shardValue) error) e
440
444
return err
441
445
}
442
446
443
- case * HamtShard :
447
+ case * Shard :
444
448
err := c .walkTrie (ctx , cb )
445
449
if err != nil {
446
450
return err
@@ -452,7 +456,7 @@ func (ds *HamtShard) walkTrie(ctx context.Context, cb func(*shardValue) error) e
452
456
return nil
453
457
}
454
458
455
- func (ds * HamtShard ) modifyValue (ctx context.Context , hv * hashBits , key string , val * ipld.Link ) error {
459
+ func (ds * Shard ) modifyValue (ctx context.Context , hv * hashBits , key string , val * ipld.Link ) error {
456
460
idx := hv .Next (ds .tableSizeLg2 )
457
461
458
462
if ds .bitfield .Bit (idx ) != 1 {
@@ -467,7 +471,7 @@ func (ds *HamtShard) modifyValue(ctx context.Context, hv *hashBits, key string,
467
471
}
468
472
469
473
switch child := child .(type ) {
470
- case * HamtShard :
474
+ case * Shard :
471
475
err := child .modifyValue (ctx , hv , key , val )
472
476
if err != nil {
473
477
return err
@@ -510,7 +514,7 @@ func (ds *HamtShard) modifyValue(ctx context.Context, hv *hashBits, key string,
510
514
}
511
515
512
516
// replace value with another shard, one level deeper
513
- ns , err := NewHamtShard (ds .dserv , ds .tableSize )
517
+ ns , err := NewShard (ds .dserv , ds .tableSize )
514
518
if err != nil {
515
519
return err
516
520
}
@@ -540,7 +544,7 @@ func (ds *HamtShard) modifyValue(ctx context.Context, hv *hashBits, key string,
540
544
// indexForBitPos returns the index within the collapsed array corresponding to
541
545
// the given bit in the bitset. The collapsed array contains only one entry
542
546
// per bit set in the bitfield, and this function is used to map the indices.
543
- func (ds * HamtShard ) indexForBitPos (bp int ) int {
547
+ func (ds * Shard ) indexForBitPos (bp int ) int {
544
548
// TODO: an optimization could reuse the same 'mask' here and change the size
545
549
// as needed. This isnt yet done as the bitset package doesnt make it easy
546
550
// to do.
@@ -553,6 +557,6 @@ func (ds *HamtShard) indexForBitPos(bp int) int {
553
557
}
554
558
555
559
// linkNamePrefix takes in the bitfield index of an entry and returns its hex prefix
556
- func (ds * HamtShard ) linkNamePrefix (idx int ) string {
560
+ func (ds * Shard ) linkNamePrefix (idx int ) string {
557
561
return fmt .Sprintf (ds .prefixPadStr , idx )
558
562
}
0 commit comments