feat!: Drop returns bool, Put doesn't stack-overflow #21

Merged
mvhutz merged 12 commits from feat/safe-put into main 2026-04-17 01:31:02 +00:00
Showing only changes of commit 78f7d01d5f - Show all commits

View File

@@ -20,52 +20,52 @@ type subtable[K, V any] struct {
// location determines where in the bucket a certain key would be placed. If the // location determines where in the bucket a certain key would be placed. If the
// capacity is 0, this will panic. // capacity is 0, this will panic.
func (b *subtable[K, V]) location(key K) uint64 { func (t *subtable[K, V]) location(key K) uint64 {
return b.hash(key) % b.capacity return t.hash(key) % t.capacity
} }
func (b *subtable[K, V]) get(key K) (value V, found bool) { func (t *subtable[K, V]) get(key K) (value V, found bool) {
if b.capacity == 0 { if t.capacity == 0 {
return return
} }
slot := b.slots[b.location(key)] slot := t.slots[t.location(key)]
return slot.Value, slot.occupied && b.compare(slot.Key, key) return slot.Value, slot.occupied && t.compare(slot.Key, key)
} }
func (b *subtable[K, V]) drop(key K) (occupied bool) { func (t *subtable[K, V]) drop(key K) (occupied bool) {
if b.capacity == 0 { if t.capacity == 0 {
return return
} }
slot := &b.slots[b.location(key)] slot := &t.slots[t.location(key)]
if slot.occupied && b.compare(slot.Key, key) { if slot.occupied && t.compare(slot.Key, key) {
slot.occupied = false slot.occupied = false
b.size-- t.size--
return true return true
} }
return false return false
} }
func (b *subtable[K, V]) resized(capacity uint64) *subtable[K, V] { func (t *subtable[K, V]) resized(capacity uint64) *subtable[K, V] {
return &subtable[K, V]{ return &subtable[K, V]{
slots: make([]slot[K, V], capacity), slots: make([]slot[K, V], capacity),
capacity: capacity, capacity: capacity,
hash: b.hash, hash: t.hash,
compare: b.compare, compare: t.compare,
} }
} }
func (b *subtable[K, V]) update(key K, value V) (updated bool) { func (t *subtable[K, V]) update(key K, value V) (updated bool) {
if b.capacity == 0 { if t.capacity == 0 {
return return
} }
slot := &b.slots[b.location(key)] slot := &t.slots[t.location(key)]
if slot.occupied && b.compare(slot.Key, key) { if slot.occupied && t.compare(slot.Key, key) {
slot.Value = value slot.Value = value
return true return true
} }
@@ -73,21 +73,21 @@ func (b *subtable[K, V]) update(key K, value V) (updated bool) {
return false return false
} }
func (b *subtable[K, V]) insert(insertion Entry[K, V]) (evicted Entry[K, V], eviction bool) { func (t *subtable[K, V]) insert(insertion Entry[K, V]) (evicted Entry[K, V], eviction bool) {
if b.capacity == 0 { if t.capacity == 0 {
return insertion, true return insertion, true
} }
slot := &b.slots[b.location(insertion.Key)] slot := &t.slots[t.location(insertion.Key)]
if !slot.occupied { if !slot.occupied {
slot.Entry = insertion slot.Entry = insertion
slot.occupied = true slot.occupied = true
b.size++ t.size++
return return
} }
if b.compare(slot.Key, insertion.Key) { if t.compare(slot.Key, insertion.Key) {
slot.Value = insertion.Value slot.Value = insertion.Value
return return
} }