feat: add drop key functionality (#6)
Currently, the `Table.Drop()` function is deprecated because it is not implemented yet. Let's add that functionality. - Adds true drop functionality to the table, through `Table.Drop()`. - Adds tests for functionality. - Rewrites fuzz test using `go_fuzz_utils`, to test arbitrary usage patterns. - Rewrite `bucket` to allow a capacity of zero. - Rename `Table.Capacity()` to `Table.TotalCapacity()`, to reflect to different between the capacity of the buckets vs. the whole table. - Enforce 100% mutation test coverage. Reviewed-on: #6 Co-authored-by: M.V. Hutz <git@maximhutz.me> Co-committed-by: M.V. Hutz <git@maximhutz.me>
This commit was merged in pull request #6.
This commit is contained in:
117
cuckoo_test.go
117
cuckoo_test.go
@@ -1,6 +1,7 @@
|
||||
package cuckoo_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"maps"
|
||||
"math/rand/v2"
|
||||
"testing"
|
||||
@@ -64,7 +65,7 @@ func TestStartingCapacity(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
table := cuckoo.NewTable[int, bool](cuckoo.Capacity(64))
|
||||
|
||||
assert.Equal(uint64(128), table.Capacity())
|
||||
assert.Equal(uint64(128), table.TotalCapacity())
|
||||
}
|
||||
|
||||
func TestResizeCapacity(t *testing.T) {
|
||||
@@ -74,12 +75,12 @@ func TestResizeCapacity(t *testing.T) {
|
||||
cuckoo.GrowthFactor(2),
|
||||
)
|
||||
|
||||
for table.Capacity() == 16 {
|
||||
for table.TotalCapacity() == 16 {
|
||||
err := table.Put(rand.Int(), true)
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
assert.Equal(uint64(32), table.Capacity())
|
||||
assert.Equal(uint64(32), table.TotalCapacity())
|
||||
}
|
||||
|
||||
func TestPutMany(t *testing.T) {
|
||||
@@ -128,3 +129,113 @@ func TestRemove(t *testing.T) {
|
||||
|
||||
assert.True(table.Has(0))
|
||||
}
|
||||
|
||||
func TestDropExistingItem(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
key, value := 0, true
|
||||
table := cuckoo.NewTable[int, bool]()
|
||||
(table.Put(key, value))
|
||||
|
||||
err := table.Drop(key)
|
||||
|
||||
assert.NoError(err)
|
||||
assert.Equal(0, table.Size())
|
||||
assert.False(table.Has(key))
|
||||
}
|
||||
|
||||
func TestDropNoItem(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
key := 0
|
||||
table := cuckoo.NewTable[int, bool]()
|
||||
|
||||
err := table.Drop(key)
|
||||
|
||||
assert.NoError(err)
|
||||
assert.Equal(0, table.Size())
|
||||
assert.False(table.Has(key))
|
||||
}
|
||||
|
||||
func TestDropItemCapacity(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
key := 0
|
||||
table := cuckoo.NewTable[int, bool](
|
||||
cuckoo.Capacity(64),
|
||||
cuckoo.GrowthFactor(2),
|
||||
)
|
||||
|
||||
startingCapacity := table.TotalCapacity()
|
||||
err := table.Drop(key)
|
||||
endingCapacity := table.TotalCapacity()
|
||||
|
||||
assert.NoError(err)
|
||||
assert.Equal(0, table.Size())
|
||||
assert.Equal(uint64(128), startingCapacity)
|
||||
assert.Equal(uint64(64), endingCapacity)
|
||||
}
|
||||
|
||||
func TestPutNoCapacity(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
key, value := 0, true
|
||||
table := cuckoo.NewTable[int, bool](
|
||||
cuckoo.Capacity(0),
|
||||
)
|
||||
|
||||
err := table.Put(key, value)
|
||||
|
||||
assert.NoError(err)
|
||||
assert.Equal(1, table.Size())
|
||||
assert.True(table.Has(key))
|
||||
}
|
||||
|
||||
func TestBadHashCapacity(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
table := cuckoo.NewCustomTable[int, bool](
|
||||
func(int) uint64 { return 0 },
|
||||
func(int) uint64 { return 0 },
|
||||
func(a, b int) bool { return a == b },
|
||||
cuckoo.Capacity(20),
|
||||
)
|
||||
|
||||
err1 := table.Put(0, true)
|
||||
err2 := table.Put(1, true)
|
||||
err3 := table.Put(2, true)
|
||||
|
||||
assert.NoError(err1)
|
||||
assert.NoError(err2)
|
||||
assert.Error(err3)
|
||||
|
||||
assert.Equal(uint64(80), table.TotalCapacity())
|
||||
}
|
||||
|
||||
func TestDropResizeCapacity(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
table := cuckoo.NewTable[int, bool](
|
||||
cuckoo.Capacity(10),
|
||||
)
|
||||
|
||||
err1 := table.Put(0, true)
|
||||
err2 := table.Put(1, true)
|
||||
err3 := table.Drop(1)
|
||||
|
||||
assert.NoError(errors.Join(err1, err2, err3))
|
||||
assert.Equal(uint64(20), table.TotalCapacity())
|
||||
}
|
||||
|
||||
func TestNewTableBy(t *testing.T) {
|
||||
type User struct {
|
||||
_ func()
|
||||
id string
|
||||
name string
|
||||
}
|
||||
|
||||
assert := assert.New(t)
|
||||
table := cuckoo.NewTableBy[User, bool](
|
||||
func(u User) string { return u.id },
|
||||
)
|
||||
|
||||
err := table.Put(User{nil, "1", "Robert"}, true)
|
||||
|
||||
assert.NoError(err)
|
||||
assert.Equal(1, table.Size())
|
||||
assert.True(table.Has(User{nil, "1", "Robbie"}))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user