refactor: HashTable -> Table, table -> subtable
All checks were successful
CI / Check PR Title (pull_request) Successful in 29s
CI / Go Lint (pull_request) Successful in 39s
CI / Makefile Lint (pull_request) Successful in 48s
CI / Markdown Lint (pull_request) Successful in 31s
CI / Unit Tests (pull_request) Successful in 37s
CI / Fuzz Tests (pull_request) Successful in 1m38s
CI / Mutation Tests (pull_request) Successful in 1m19s
All checks were successful
CI / Check PR Title (pull_request) Successful in 29s
CI / Go Lint (pull_request) Successful in 39s
CI / Makefile Lint (pull_request) Successful in 48s
CI / Markdown Lint (pull_request) Successful in 31s
CI / Unit Tests (pull_request) Successful in 37s
CI / Fuzz Tests (pull_request) Successful in 1m38s
CI / Mutation Tests (pull_request) Successful in 1m19s
This commit is contained in:
103
subtable.go
Normal file
103
subtable.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package cuckoo
|
||||
|
||||
type entry[K, V any] struct {
|
||||
key K
|
||||
value V
|
||||
}
|
||||
|
||||
type slot[K, V any] struct {
|
||||
entry[K, V]
|
||||
occupied bool
|
||||
}
|
||||
|
||||
type subtable[K, V any] struct {
|
||||
hash Hash[K]
|
||||
slots []slot[K, V]
|
||||
capacity, size uint64
|
||||
compare EqualFunc[K]
|
||||
}
|
||||
|
||||
// location determines where in the subtable a certain key would be placed. If
|
||||
// the capacity is 0, this will panic.
|
||||
func (t subtable[K, V]) location(key K) uint64 {
|
||||
return t.hash(key) % t.capacity
|
||||
}
|
||||
|
||||
func (t subtable[K, V]) get(key K) (value V, found bool) {
|
||||
if t.capacity == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
slot := t.slots[t.location(key)]
|
||||
return slot.value, slot.occupied && t.compare(slot.key, key)
|
||||
}
|
||||
|
||||
func (t *subtable[K, V]) drop(key K) (occupied bool) {
|
||||
if t.capacity == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
slot := &t.slots[t.location(key)]
|
||||
|
||||
if slot.occupied && t.compare(slot.key, key) {
|
||||
slot.occupied = false
|
||||
t.size--
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *subtable[K, V]) resize(capacity uint64) {
|
||||
t.slots = make([]slot[K, V], capacity)
|
||||
t.capacity = capacity
|
||||
t.size = 0
|
||||
}
|
||||
|
||||
func (t subtable[K, V]) update(key K, value V) (updated bool) {
|
||||
if t.capacity == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
slot := &t.slots[t.location(key)]
|
||||
|
||||
if slot.occupied && t.compare(slot.key, key) {
|
||||
slot.value = value
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *subtable[K, V]) evict(insertion entry[K, V]) (evicted entry[K, V], eviction bool) {
|
||||
if t.capacity == 0 {
|
||||
return insertion, true
|
||||
}
|
||||
|
||||
slot := &t.slots[t.location(insertion.key)]
|
||||
|
||||
if !slot.occupied {
|
||||
slot.entry = insertion
|
||||
slot.occupied = true
|
||||
t.size++
|
||||
return
|
||||
}
|
||||
|
||||
if t.compare(slot.key, insertion.key) {
|
||||
slot.value = insertion.value
|
||||
return
|
||||
}
|
||||
|
||||
insertion, slot.entry = slot.entry, insertion
|
||||
return insertion, true
|
||||
}
|
||||
|
||||
func newSubtable[K, V any](capacity uint64, hash Hash[K], compare EqualFunc[K]) subtable[K, V] {
|
||||
return subtable[K, V]{
|
||||
hash: hash,
|
||||
capacity: capacity,
|
||||
compare: compare,
|
||||
size: 0,
|
||||
slots: make([]slot[K, V], capacity),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user