2024-01-19 15:57:29 +03:00
|
|
|
package structr
|
|
|
|
|
2024-01-29 18:13:53 +03:00
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
"unsafe"
|
|
|
|
)
|
2024-01-19 15:57:29 +03:00
|
|
|
|
2024-01-29 18:13:53 +03:00
|
|
|
var result_pool sync.Pool
|
2024-01-19 15:57:29 +03:00
|
|
|
|
2024-01-29 18:13:53 +03:00
|
|
|
type result struct {
|
|
|
|
// linked list elem this result is
|
|
|
|
// stored under in Cache.lruList.
|
|
|
|
elem list_elem
|
2024-01-19 15:57:29 +03:00
|
|
|
|
2024-01-29 18:13:53 +03:00
|
|
|
// indexed stores the indices
|
|
|
|
// this result is stored under.
|
|
|
|
indexed []*index_entry
|
2024-01-19 15:57:29 +03:00
|
|
|
|
2024-01-29 18:13:53 +03:00
|
|
|
// cached data (we maintain
|
|
|
|
// the type data here using
|
|
|
|
// an interface as any one
|
|
|
|
// instance can be T / error).
|
|
|
|
data interface{}
|
|
|
|
}
|
2024-01-19 15:57:29 +03:00
|
|
|
|
2024-01-29 18:13:53 +03:00
|
|
|
func result_acquire[T any](c *Cache[T]) *result {
|
|
|
|
// Acquire from pool.
|
|
|
|
v := result_pool.Get()
|
|
|
|
if v == nil {
|
|
|
|
v = new(result)
|
2024-01-19 15:57:29 +03:00
|
|
|
}
|
|
|
|
|
2024-01-29 18:13:53 +03:00
|
|
|
// Cast result value.
|
|
|
|
res := v.(*result)
|
|
|
|
|
|
|
|
// Push result elem to front of LRU list.
|
|
|
|
list_push_front(&c.lruList, &res.elem)
|
|
|
|
res.elem.data = unsafe.Pointer(res)
|
2024-01-19 15:57:29 +03:00
|
|
|
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
2024-01-29 18:13:53 +03:00
|
|
|
func result_release[T any](c *Cache[T], res *result) {
|
|
|
|
// Remove result elem from LRU list.
|
|
|
|
list_remove(&c.lruList, &res.elem)
|
|
|
|
res.elem.data = nil
|
2024-01-19 15:57:29 +03:00
|
|
|
|
|
|
|
// Reset all result fields.
|
2024-01-29 18:13:53 +03:00
|
|
|
res.indexed = res.indexed[:0]
|
|
|
|
res.data = nil
|
2024-01-19 15:57:29 +03:00
|
|
|
|
2024-01-29 18:13:53 +03:00
|
|
|
// Release to pool.
|
|
|
|
result_pool.Put(res)
|
2024-01-19 15:57:29 +03:00
|
|
|
}
|
|
|
|
|
2024-01-29 18:13:53 +03:00
|
|
|
func result_drop_index[T any](res *result, index *Index[T]) {
|
|
|
|
for i := 0; i < len(res.indexed); i++ {
|
2024-01-19 15:57:29 +03:00
|
|
|
|
2024-01-29 18:13:53 +03:00
|
|
|
if res.indexed[i].index != unsafe.Pointer(index) {
|
2024-01-19 15:57:29 +03:00
|
|
|
// Prof. Obiwan:
|
|
|
|
// this is not the index
|
|
|
|
// we are looking for.
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2024-01-29 18:13:53 +03:00
|
|
|
// Get index entry ptr.
|
|
|
|
entry := res.indexed[i]
|
2024-01-19 15:57:29 +03:00
|
|
|
|
2024-01-29 18:13:53 +03:00
|
|
|
// Move all index entries down + reslice.
|
|
|
|
copy(res.indexed[i:], res.indexed[i+1:])
|
|
|
|
res.indexed = res.indexed[:len(res.indexed)-1]
|
2024-01-19 15:57:29 +03:00
|
|
|
|
2024-01-29 18:13:53 +03:00
|
|
|
// Release to memory pool.
|
|
|
|
index_entry_release(entry)
|
2024-01-19 15:57:29 +03:00
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|