refactor!: shorter constructors, bucket → subtable (#22)
All checks were successful
CI / Check PR Title (push) Has been skipped
CI / Makefile Lint (push) Successful in 47s
CI / Go Lint (push) Successful in 51s
CI / Markdown Lint (push) Successful in 46s
CI / Unit Tests (push) Successful in 47s
CI / Fuzz Tests (push) Successful in 1m19s
CI / Mutation Tests (push) Successful in 1m36s
All checks were successful
CI / Check PR Title (push) Has been skipped
CI / Makefile Lint (push) Successful in 47s
CI / Go Lint (push) Successful in 51s
CI / Markdown Lint (push) Successful in 46s
CI / Unit Tests (push) Successful in 47s
CI / Fuzz Tests (push) Successful in 1m19s
CI / Mutation Tests (push) Successful in 1m36s
## Description Currently, the name of `bucket` is a bit confusing, because it is considered a 'table' in literature (as well as the whole hash table). A `bucket` is better described as a 'subtable', which is used by the total hash table to perform cuckoo hashing. In addition, the constructors `NewTable`, `NewTableBy`, and `NewCustomTable` were given shorter names, because the package name `cuckoo` already implies that `New*` would create a hash table with cuckoo hashing. This package has one use-case, and so it unambiguous what constructors produce. ## Changes - `NewTable` -> `New` - `NewTableBy` -> `NewBy` - `NewCustomTable` -> `NewCustom` - `bucket` -> `subtable` ### Design Decisions - I would have renamed `Table` and `subtable` to map equivalents, but 'submap' implies that a certain subsection of the map is contained within it, which isn't quite right. - I chose not to go with `Map` and `table`, because of the split naming convention. ## Checklist - [x] Tests pass - [x] Docs updated Reviewed-on: #22 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 #22.
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