[bugfix] visibility after implicit approval not getting invalidated (#3370)

* replicate issue

* update go-structr to v0.8.10 with internal linked-list fix, small tweaks to caching of interaction requests

* remove debug function

---------

Co-authored-by: tobi <tobi.smethurst@protonmail.com>
This commit is contained in:
kim
2024-09-28 20:47:46 +00:00
committed by GitHub
parent 18b7e00fef
commit 095663f5cc
19 changed files with 239 additions and 136 deletions

View File

@@ -575,8 +575,9 @@ func (c *Cache[T]) store_value(index *Index, key string, value T) {
item.data = value
if index != nil {
// Append item to index.
index.append(key, item)
// Append item to index a key
// was already generated for.
index.append(&c.lru, key, item)
}
// Get ptr to value data.
@@ -607,8 +608,8 @@ func (c *Cache[T]) store_value(index *Index, key string, value T) {
continue
}
// Append item to index.
idx.append(key, item)
// Append item to this index.
idx.append(&c.lru, key, item)
}
// Add item to main lru list.
@@ -645,8 +646,9 @@ func (c *Cache[T]) store_error(index *Index, key string, err error) {
// Set error val.
item.data = err
// Append item to index.
index.append(key, item)
// Append item to index a key
// was already generated for.
index.append(&c.lru, key, item)
// Add item to main lru list.
c.lru.push_front(&item.elem)

View File

@@ -174,7 +174,7 @@ func (i *Index) init(t reflect.Type, cfg IndexConfig, cap int) {
// get_one will fetch one indexed item under key.
func (i *Index) get_one(key Key) *indexed_item {
// Get list at hash.
l, _ := i.data.Get(key.key)
l := i.data.Get(key.key)
if l == nil {
return nil
}
@@ -192,7 +192,7 @@ func (i *Index) get(key string, hook func(*indexed_item)) {
}
// Get list at hash.
l, _ := i.data.Get(key)
l := i.data.Get(key)
if l == nil {
return
}
@@ -237,11 +237,12 @@ func (i *Index) key(buf *byteutil.Buffer, parts []unsafe.Pointer) string {
}
// append will append the given index entry to appropriate
// doubly-linked-list in index hashmap. this handles case
// of key collisions and overwriting 'unique' entries.
func (i *Index) append(key string, item *indexed_item) {
// doubly-linked-list in index hashmap. this handles case of
// overwriting "unique" index entries, and removes from given
// outer linked-list in the case that it is no longer indexed.
func (i *Index) append(ll *list, key string, item *indexed_item) {
// Look for existing.
l, _ := i.data.Get(key)
l := i.data.Get(key)
if l == nil {
@@ -255,12 +256,21 @@ func (i *Index) append(key string, item *indexed_item) {
elem := l.head
l.remove(elem)
// Drop index from inner item.
// Drop index from inner item,
// catching the evicted item.
e := (*index_entry)(elem.data)
e.item.drop_index(e)
evicted := e.item
evicted.drop_index(e)
// Free unused entry.
free_index_entry(e)
if len(evicted.indexed) == 0 {
// Evicted item is not indexed,
// remove from outer linked list.
ll.remove(&evicted.elem)
free_indexed_item(evicted)
}
}
// Prepare new index entry.
@@ -283,7 +293,7 @@ func (i *Index) delete(key string, hook func(*indexed_item)) {
}
// Get list at hash.
l, _ := i.data.Get(key)
l := i.data.Get(key)
if l == nil {
return
}
@@ -292,10 +302,9 @@ func (i *Index) delete(key string, hook func(*indexed_item)) {
i.data.Delete(key)
// Iterate entries in list.
for x := 0; x < l.len; x++ {
l.rangefn(func(elem *list_elem) {
// Pop list head.
elem := l.head
// Remove elem.
l.remove(elem)
// Extract element entry + item.
@@ -310,7 +319,7 @@ func (i *Index) delete(key string, hook func(*indexed_item)) {
// Pass to hook.
hook(item)
}
})
// Release list.
free_list(l)
@@ -319,7 +328,7 @@ func (i *Index) delete(key string, hook func(*indexed_item)) {
// delete_entry deletes the given index entry.
func (i *Index) delete_entry(entry *index_entry) {
// Get list at hash sum.
l, _ := i.data.Get(entry.key)
l := i.data.Get(entry.key)
if l == nil {
return
}

View File

@@ -50,12 +50,9 @@ func (i *indexed_item) drop_index(entry *index_entry) {
continue
}
// Unset tptr value to
// ensure GC can take it.
i.indexed[x] = nil
// Move all index entries down + reslice.
_ = copy(i.indexed[x:], i.indexed[x+1:])
i.indexed[len(i.indexed)-1] = nil
i.indexed = i.indexed[:len(i.indexed)-1]
break
}

View File

@@ -48,27 +48,17 @@ func free_list(list *list) {
// push_front will push the given elem to front (head) of list.
func (l *list) push_front(elem *list_elem) {
if l.len == 0 {
// Set new tail + head
l.head = elem
l.tail = elem
// Link elem to itself
elem.next = elem
elem.prev = elem
} else {
oldHead := l.head
// Set new head.
oldHead := l.head
l.head = elem
if oldHead != nil {
// Link to old head
elem.next = oldHead
oldHead.prev = elem
// Link up to tail
elem.prev = l.tail
l.tail.next = elem
// Set new head
l.head = elem
} else {
// First in list.
l.tail = elem
}
// Incr count
@@ -77,27 +67,17 @@ func (l *list) push_front(elem *list_elem) {
// push_back will push the given elem to back (tail) of list.
func (l *list) push_back(elem *list_elem) {
if l.len == 0 {
// Set new tail + head
l.head = elem
l.tail = elem
// Link elem to itself
elem.next = elem
elem.prev = elem
} else {
oldTail := l.tail
// Set new tail.
oldTail := l.tail
l.tail = elem
if oldTail != nil {
// Link to old tail
elem.prev = oldTail
oldTail.next = elem
// Link up to head
elem.next = l.head
l.head.prev = elem
// Set new tail
l.tail = elem
} else {
// First in list.
l.head = elem
}
// Incr count
@@ -105,53 +85,57 @@ func (l *list) push_back(elem *list_elem) {
}
// move_front will move given elem to front (head) of list.
// if it is already at front this call is a no-op.
func (l *list) move_front(elem *list_elem) {
if elem == l.head {
return
}
l.remove(elem)
l.push_front(elem)
}
// move_back will move given elem to back (tail) of list.
// move_back will move given elem to back (tail) of list,
// if it is already at back this call is a no-op.
func (l *list) move_back(elem *list_elem) {
if elem == l.tail {
return
}
l.remove(elem)
l.push_back(elem)
}
// remove will remove given elem from list.
func (l *list) remove(elem *list_elem) {
if l.len <= 1 {
// Drop elem's links
elem.next = nil
elem.prev = nil
// Only elem in list
l.head = nil
l.tail = nil
l.len = 0
return
}
// Get surrounding elems
// Get linked elems.
next := elem.next
prev := elem.prev
// Relink chain
next.prev = prev
prev.next = next
switch elem {
// Set new head
case l.head:
l.head = next
// Set new tail
case l.tail:
l.tail = prev
}
// Drop elem's links
// Unset elem.
elem.next = nil
elem.prev = nil
switch {
// elem is ONLY one in list.
case next == nil && prev == nil:
l.head = nil
l.tail = nil
// elem is front in list.
case next != nil && prev == nil:
l.head = next
next.prev = nil
// elem is last in list.
case prev != nil && next == nil:
l.tail = prev
prev.next = nil
// elem in middle of list.
default:
next.prev = prev
prev.next = next
}
// Decr count
l.len--
}
@@ -161,9 +145,11 @@ func (l *list) rangefn(fn func(*list_elem)) {
if fn == nil {
panic("nil fn")
}
elem := l.head
for i := 0; i < l.len; i++ {
fn(elem)
elem = elem.next
for e := l.head; //
e != nil; //
{
n := e.next
fn(e)
e = n
}
}

View File

@@ -10,9 +10,8 @@ func (m *hashmap) init(cap int) {
m.n = cap
}
func (m *hashmap) Get(key string) (*list, bool) {
list, ok := m.m[key]
return list, ok
func (m *hashmap) Get(key string) *list {
return m.m[key]
}
func (m *hashmap) Put(key string, list *list) {

View File

@@ -308,8 +308,8 @@ func (q *Queue[T]) index(value T) *indexed_item {
continue
}
// Append item to index.
idx.append(key, item)
// Append item to this index.
idx.append(&q.queue, key, item)
}
// Done with buf.