Files
go-cuckoo/bucket.go
M.V. Hutz ca66ccd040
All checks were successful
CI / Check PR Title (pull_request) Successful in 19s
CI / Go Lint (pull_request) Successful in 42s
CI / Markdown Lint (pull_request) Successful in 23s
CI / Makefile Lint (pull_request) Successful in 41s
CI / Unit Tests (pull_request) Successful in 41s
CI / Fuzz Tests (pull_request) Successful in 1m12s
CI / Mutation Tests (pull_request) Successful in 58s
fix: public facing key/value fields in entry
2026-04-04 00:38:27 +02:00

108 lines
2.0 KiB
Go

package cuckoo
// An Entry is a key-value pair.
type Entry[K, V any] struct {
Key K
Value V
}
type slot[K, V any] struct {
Entry[K, V]
occupied bool
}
type bucket[K, V any] struct {
hash Hash[K]
slots []slot[K, V]
capacity, size uint64
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
}
func (b bucket[K, V]) get(key K) (value V, found bool) {
if b.capacity == 0 {
return
}
slot := b.slots[b.location(key)]
return slot.Value, slot.occupied && b.compare(slot.Key, key)
}
func (b *bucket[K, V]) drop(key K) (occupied bool) {
if b.capacity == 0 {
return
}
slot := &b.slots[b.location(key)]
if slot.occupied && b.compare(slot.Key, key) {
slot.occupied = false
b.size--
return true
}
return false
}
func (b *bucket[K, V]) resized(capacity uint64) bucket[K, V] {
return bucket[K, V]{
slots: make([]slot[K, V], capacity),
capacity: capacity,
hash: b.hash,
compare: b.compare,
}
}
func (b bucket[K, V]) update(key K, value V) (updated bool) {
if b.capacity == 0 {
return
}
slot := &b.slots[b.location(key)]
if slot.occupied && b.compare(slot.Key, key) {
slot.Value = value
return true
}
return false
}
func (b *bucket[K, V]) insert(insertion Entry[K, V]) (evicted Entry[K, V], eviction bool) {
if b.capacity == 0 {
return insertion, true
}
slot := &b.slots[b.location(insertion.Key)]
if !slot.occupied {
slot.Entry = insertion
slot.occupied = true
b.size++
return
}
if b.compare(slot.Key, insertion.Key) {
slot.Value = insertion.Value
return
}
insertion, slot.Entry = slot.Entry, insertion
return insertion, true
}
func newBucket[K, V any](capacity uint64, hash Hash[K], compare EqualFunc[K]) bucket[K, V] {
return bucket[K, V]{
hash: hash,
capacity: capacity,
compare: compare,
size: 0,
slots: make([]slot[K, V], capacity),
}
}