feat: sentinel error ErrBadHash (#19)
All checks were successful
CI / Check PR Title (push) Has been skipped
CI / Makefile Lint (push) Successful in 1m4s
CI / Markdown Lint (push) Successful in 32s
CI / Go Lint (push) Successful in 1m15s
CI / Unit Tests (push) Successful in 38s
CI / Fuzz Tests (push) Successful in 1m34s
CI / Mutation Tests (push) Successful in 1m31s
All checks were successful
CI / Check PR Title (push) Has been skipped
CI / Makefile Lint (push) Successful in 1m4s
CI / Markdown Lint (push) Successful in 32s
CI / Go Lint (push) Successful in 1m15s
CI / Unit Tests (push) Successful in 38s
CI / Fuzz Tests (push) Successful in 1m34s
CI / Mutation Tests (push) Successful in 1m31s
## Description Currently, the errors are not sentinel, and so are hard to test for. This PR makes sure hash collision errors are accounted for. ## Changes - Add `ErrBadHash`. Happens when there are too many collisions for an item to be added. ### Design Decisions - Chose to name `ErrBadHash` over `ErrCycle` because the feedbach that the user should be given is to evaluate their hash functions. Cycle collision is a bit esoteric. ## Checklist - [x] Tests pass - [x] Docs updated Reviewed-on: #19 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 #19.
This commit is contained in:
11
table.go
11
table.go
@@ -1,12 +1,21 @@
|
||||
package cuckoo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"iter"
|
||||
"math/bits"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ErrBadHash occurs when the hashes given to a [Table] cause too many key
|
||||
// collisions. Try rebuilding the table using:
|
||||
//
|
||||
// 1. Different hash seeds. Equal seeds produce equal hash functions, which
|
||||
// always cycle.
|
||||
// 2. A different [Hash] algorithm.
|
||||
var ErrBadHash = errors.New("bad hash")
|
||||
|
||||
// A Table is hash table that uses cuckoo hashing to resolve collision. Create
|
||||
// one with [NewTable]. Or if you want more granularity, use [NewTableBy] or
|
||||
// [NewCustomTable].
|
||||
@@ -128,7 +137,7 @@ func (t *Table[K, V]) Put(key K, value V) (err error) {
|
||||
}
|
||||
|
||||
if t.load() < t.minLoadFactor {
|
||||
return fmt.Errorf("bad hash: resize on load %d/%d = %f", t.Size(), t.TotalCapacity(), t.load())
|
||||
return fmt.Errorf("hash functions produced a cycle at load %d/%d: %w", t.Size(), t.TotalCapacity(), ErrBadHash)
|
||||
}
|
||||
|
||||
if err := t.grow(); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user