diff --git a/unixfs/hamt/hamt.go b/unixfs/hamt/hamt.go index fecf23b46a7..bd73434cb03 100644 --- a/unixfs/hamt/hamt.go +++ b/unixfs/hamt/hamt.go @@ -492,16 +492,21 @@ func (ds *HamtShard) modifyValue(ctx context.Context, hv *hashBits, key string, return nil case *shardValue: - switch { - case val == nil: // passing a nil value signifies a 'delete' - ds.bitfield.SetBit(ds.bitfield, idx, 0) - return ds.rmChild(cindex) + if child.key == key { + // value modification + if val == nil { + ds.bitfield.SetBit(ds.bitfield, idx, 0) + return ds.rmChild(cindex) + } - case child.key == key: // value modification child.val = val return nil + } else { + if val == nil { + return os.ErrNotExist + } - default: // replace value with another shard, one level deeper + // replace value with another shard, one level deeper ns, err := NewHamtShard(ds.dserv, ds.tableSize) if err != nil { return err diff --git a/unixfs/hamt/hamt_test.go b/unixfs/hamt/hamt_test.go index 77997d2fd18..eb204dfd624 100644 --- a/unixfs/hamt/hamt_test.go +++ b/unixfs/hamt/hamt_test.go @@ -222,6 +222,20 @@ func TestRemoveElems(t *testing.T) { } ctx := context.Background() + for i := 0; i < 100; i++ { + err := s.Remove(ctx, fmt.Sprintf("NOTEXIST%d", rand.Int())) + if err != os.ErrNotExist { + t.Fatal("shouldnt be able to remove things that don't exist") + } + } + + for _, d := range dirs { + _, err := s.Find(ctx, d) + if err != nil { + t.Fatal(err) + } + } + shuffle(time.Now().UnixNano(), dirs) for _, d := range dirs { diff --git a/unixfs/hamt/util.go b/unixfs/hamt/util.go index 08c232a8ad1..4692e749390 100644 --- a/unixfs/hamt/util.go +++ b/unixfs/hamt/util.go @@ -2,6 +2,7 @@ package hamt import ( "math/big" + "math/bits" ) // 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 { } } -const ( - m1 = 0x5555555555555555 //binary: 0101... - m2 = 0x3333333333333333 //binary: 00110011.. - m4 = 0x0f0f0f0f0f0f0f0f //binary: 4 zeros, 4 ones ... - h01 = 0x0101010101010101 //the sum of 256 to the power of 0,1,2,3... -) - -// from https://en.wikipedia.org/wiki/Hamming_weight -func popCountUint64(x uint64) int { - x -= (x >> 1) & m1 //put count of each 2 bits into those 2 bits - x = (x & m2) + ((x >> 2) & m2) //put count of each 4 bits into those 4 bits - x = (x + (x >> 4)) & m4 //put count of each 8 bits into those 8 bits - return int((x * h01) >> 56) -} - func popCount(i *big.Int) int { var n int for _, v := range i.Bits() { - n += popCountUint64(uint64(v)) + n += bits.OnesCount64(uint64(v)) } return n }