Skip to content

Commit

Permalink
fix hamt delete issue
Browse files Browse the repository at this point in the history
License: MIT
Signed-off-by: Jeromy <jeromyj@gmail.com>
  • Loading branch information
whyrusleeping committed Nov 18, 2017
1 parent cc01b7f commit f8eaae3
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 22 deletions.
17 changes: 11 additions & 6 deletions unixfs/hamt/hamt.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 14 additions & 0 deletions unixfs/hamt/hamt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
18 changes: 2 additions & 16 deletions unixfs/hamt/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
}

0 comments on commit f8eaae3

Please sign in to comment.