@cryptotaxi247 / kubo / commits / f8eaae329

fix hamt delete issue

License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>

Jeromy committed Nov 18, 2017 at 08:39 UTC f8eaae329f203fa3bd1a926e17ae13d8219fae82
3 files changed +27 -22
unixfs/hamt/hamt.go
+11 -6
@@ -492,16 +492,21 @@ func (ds *HamtShard) modifyValue(ctx context.Context, hv *hashBits, key string,
492
493 return nil
494 case *shardValue:
495 - switch {
496 - case val == nil: // passing a nil value signifies a 'delete'
497 - ds.bitfield.SetBit(ds.bitfield, idx, 0)
498 - return ds.rmChild(cindex)
495 + if child.key == key {
496 + // value modification
497 + if val == nil {
498 + ds.bitfield.SetBit(ds.bitfield, idx, 0)
499 + return ds.rmChild(cindex)
500 + }
501
500 - case child.key == key: // value modification
502 child.val = val
503 return nil
504 + } else {
505 + if val == nil {
506 + return os.ErrNotExist
507 + }
508
504 - default: // replace value with another shard, one level deeper
509 + // replace value with another shard, one level deeper
510 ns, err := NewHamtShard(ds.dserv, ds.tableSize)
511 if err != nil {
512 return err
unixfs/hamt/hamt_test.go
+14
@@ -222,6 +222,20 @@ func TestRemoveElems(t *testing.T) {
222 }
223 ctx := context.Background()
224
225 + for i := 0; i < 100; i++ {
226 + err := s.Remove(ctx, fmt.Sprintf("NOTEXIST%d", rand.Int()))
227 + if err != os.ErrNotExist {
228 + t.Fatal("shouldnt be able to remove things that don't exist")
229 + }
230 + }
231 +
232 + for _, d := range dirs {
233 + _, err := s.Find(ctx, d)
234 + if err != nil {
235 + t.Fatal(err)
236 + }
237 + }
238 +
239 shuffle(time.Now().UnixNano(), dirs)
240
241 for _, d := range dirs {
unixfs/hamt/util.go
+2 -16
@@ -2,6 +2,7 @@ package hamt
2
3 import (
4 "math/big"
5 + "math/bits"
6 )
7
8 // hashBits is a helper that allows the reading of the 'next n bits' as an integer.
@@ -39,25 +40,10 @@ func (hb *hashBits) Next(i int) int {
40 }
41 }
42
42 -const (
43 - m1 = 0x5555555555555555 //binary: 0101...
44 - m2 = 0x3333333333333333 //binary: 00110011..
45 - m4 = 0x0f0f0f0f0f0f0f0f //binary: 4 zeros, 4 ones ...
46 - h01 = 0x0101010101010101 //the sum of 256 to the power of 0,1,2,3...
47 -)
48 -
49 -// from https://en.wikipedia.org/wiki/Hamming_weight
50 -func popCountUint64(x uint64) int {
51 - x -= (x >> 1) & m1 //put count of each 2 bits into those 2 bits
52 - x = (x & m2) + ((x >> 2) & m2) //put count of each 4 bits into those 4 bits
53 - x = (x + (x >> 4)) & m4 //put count of each 8 bits into those 8 bits
54 - return int((x * h01) >> 56)
55 -}
56 -
43 func popCount(i *big.Int) int {
44 var n int
45 for _, v := range i.Bits() {
60 - n += popCountUint64(uint64(v))
46 + n += bits.OnesCount64(uint64(v))
47 }
48 return n
49 }