feat!: Drop returns bool, Put doesn't stack-overflow
#21
30
subtable.go
30
subtable.go
@@ -1,13 +1,13 @@
|
||||
package cuckoo
|
||||
|
||||
// An Entry is a key-value pair.
|
||||
type Entry[K, V any] struct {
|
||||
Key K
|
||||
Value V
|
||||
// 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]
|
||||
entry[K, V]
|
||||
occupied bool
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ func (t *subtable[K, V]) get(key K) (value V, found bool) {
|
||||
}
|
||||
|
||||
slot := t.slots[t.location(key)]
|
||||
return slot.Value, slot.occupied && t.compare(slot.Key, key)
|
||||
return slot.value, slot.occupied && t.compare(slot.key, key)
|
||||
}
|
||||
|
||||
func (t *subtable[K, V]) drop(key K) (occupied bool) {
|
||||
@@ -40,7 +40,7 @@ func (t *subtable[K, V]) drop(key K) (occupied bool) {
|
||||
|
||||
slot := &t.slots[t.location(key)]
|
||||
|
||||
if slot.occupied && t.compare(slot.Key, key) {
|
||||
if slot.occupied && t.compare(slot.key, key) {
|
||||
slot.occupied = false
|
||||
t.size--
|
||||
return true
|
||||
@@ -65,34 +65,34 @@ func (t *subtable[K, V]) update(key K, value V) (updated bool) {
|
||||
|
||||
slot := &t.slots[t.location(key)]
|
||||
|
||||
if slot.occupied && t.compare(slot.Key, key) {
|
||||
slot.Value = value
|
||||
if slot.occupied && t.compare(slot.key, key) {
|
||||
slot.value = value
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *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 t.capacity == 0 {
|
||||
return insertion, true
|
||||
}
|
||||
|
||||
slot := &t.slots[t.location(insertion.Key)]
|
||||
slot := &t.slots[t.location(insertion.key)]
|
||||
|
||||
if !slot.occupied {
|
||||
slot.Entry = insertion
|
||||
slot.entry = insertion
|
||||
slot.occupied = true
|
||||
t.size++
|
||||
return
|
||||
}
|
||||
|
||||
if t.compare(slot.Key, insertion.Key) {
|
||||
slot.Value = insertion.Value
|
||||
if t.compare(slot.key, insertion.key) {
|
||||
slot.value = insertion.value
|
||||
return
|
||||
}
|
||||
|
||||
insertion, slot.Entry = slot.Entry, insertion
|
||||
insertion, slot.entry = slot.entry, insertion
|
||||
return insertion, true
|
||||
}
|
||||
|
||||
|
||||
14
table.go
14
table.go
@@ -57,12 +57,12 @@ func (t *Table[K, V]) load() float64 {
|
||||
// insert attempts to put/update an entry in the table, without modifying the
|
||||
// size of the table. Returns a displaced entry and 'homeless = true' if an
|
||||
// entry could not be placed after exhausting evictions.
|
||||
func (t *Table[K, V]) insert(entry Entry[K, V]) (displaced Entry[K, V], homeless bool) {
|
||||
if t.tableA.update(entry.Key, entry.Value) {
|
||||
func (t *Table[K, V]) insert(entry entry[K, V]) (displaced entry[K, V], homeless bool) {
|
||||
if t.tableA.update(entry.key, entry.value) {
|
||||
return
|
||||
}
|
||||
|
||||
if t.tableB.update(entry.Key, entry.Value) {
|
||||
if t.tableB.update(entry.key, entry.value) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ func (t *Table[K, V]) resize(capacity uint64) bool {
|
||||
updated := t.resized(capacity)
|
||||
|
||||
for k, v := range t.Entries() {
|
||||
if _, failed := updated.insert(Entry[K, V]{k, v}); failed {
|
||||
if _, failed := updated.insert(entry[K, V]{k, v}); failed {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -156,7 +156,7 @@ func (t *Table[K, V]) Has(key K) (exists bool) {
|
||||
// Put sets the value for a key. If it cannot be set, an error is returned.
|
||||
func (t *Table[K, V]) Put(key K, value V) (err error) {
|
||||
var (
|
||||
entry = Entry[K, V]{key, value}
|
||||
entry = entry[K, V]{key, value}
|
||||
homeless bool
|
||||
)
|
||||
|
||||
@@ -202,7 +202,7 @@ func (t *Table[K, V]) Entries() iter.Seq2[K, V] {
|
||||
return func(yield func(K, V) bool) {
|
||||
for _, slot := range t.tableA.slots {
|
||||
if slot.occupied {
|
||||
if !yield(slot.Key, slot.Value) {
|
||||
if !yield(slot.key, slot.value) {
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -210,7 +210,7 @@ func (t *Table[K, V]) Entries() iter.Seq2[K, V] {
|
||||
|
||||
for _, slot := range t.tableB.slots {
|
||||
if slot.occupied {
|
||||
if !yield(slot.Key, slot.Value) {
|
||||
if !yield(slot.key, slot.value) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user