Compare commits
1 Commits
cdb5efb4a3
...
v0.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 56b1982f8a |
@@ -4,4 +4,6 @@ unleash:
|
||||
timeout-coefficient: 50
|
||||
|
||||
workers: 4
|
||||
dry-run: false
|
||||
dry-run: false
|
||||
threshold:
|
||||
efficacy: 1.0
|
||||
@@ -17,6 +17,8 @@ type bucket[K, V any] struct {
|
||||
compare EqualFunc[K]
|
||||
}
|
||||
|
||||
// location determines where in the bucket a certain key would be placed. If the
|
||||
// capacity is 0, this will panic.
|
||||
func (b bucket[K, V]) location(key K) uint64 {
|
||||
return b.hash(key) % b.capacity
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cuckoo_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"maps"
|
||||
"math/rand/v2"
|
||||
"testing"
|
||||
@@ -153,3 +154,88 @@ func TestDropNoItem(t *testing.T) {
|
||||
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"}))
|
||||
}
|
||||
|
||||
2
go.mod
2
go.mod
@@ -4,6 +4,8 @@ go 1.25.6
|
||||
|
||||
require github.com/stretchr/testify v1.11.1
|
||||
|
||||
require github.com/kr/pretty v0.3.1 // indirect
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
|
||||
11
go.sum
11
go.sum
@@ -1,12 +1,21 @@
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/trailofbits/go-fuzz-utils v0.0.0-20260318143407-0907cafe7589 h1:UmBZCTPdDYore2IEHN+U4eIqEaRq6METh9pKiPumkqc=
|
||||
github.com/trailofbits/go-fuzz-utils v0.0.0-20260318143407-0907cafe7589/go.mod h1:zh+T+w9XT/3o4E0WLEGCdmLJ8Yqx/zY3o538tQY3OjY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
7
table.go
7
table.go
@@ -45,6 +45,9 @@ func (t Table[K, V]) load() float64 {
|
||||
return float64(t.Size()) / float64(t.TotalCapacity())
|
||||
}
|
||||
|
||||
// resize clears all buckets, changes the sizes of them to a specific capacity,
|
||||
// and fills them back up again. It is a helper function for [Table.grow] and
|
||||
// [Table.shrink]; use them instead.
|
||||
func (t *Table[K, V]) resize(capacity uint64) error {
|
||||
entries := make([]entry[K, V], 0, t.Size())
|
||||
for k, v := range t.Entries() {
|
||||
@@ -63,6 +66,8 @@ func (t *Table[K, V]) resize(capacity uint64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// grow increases the table's capacity by the [Table.growthFactor]. If the
|
||||
// capacity is 0, it increases it to 1.
|
||||
func (t *Table[K, V]) grow() error {
|
||||
var newCapacity uint64
|
||||
|
||||
@@ -75,6 +80,8 @@ func (t *Table[K, V]) grow() error {
|
||||
return t.resize(newCapacity)
|
||||
}
|
||||
|
||||
// shrink reduces the table's capacity by the [Table.growthFactor]. It may
|
||||
// reduce it down to 0.
|
||||
func (t *Table[K, V]) shrink() error {
|
||||
return t.resize(t.bucketA.capacity / t.growthFactor)
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
go test fuzz v1
|
||||
[]byte("B000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000")
|
||||
Reference in New Issue
Block a user