mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-11-01 02:22:24 -05:00
[performance] overhaul struct (+ result) caching library for simplicity, performance and multiple-result lookups (#2535)
* rewrite cache library as codeberg.org/gruf/go-structr, implement in gotosocial
* use actual go-structr release version (not just commit hash)
* revert go toolchain changes (damn you go for auto changing this)
* fix go mod woes
* ensure %w is used in calls to errs.Appendf()
* fix error checking
* fix possible panic
* remove unnecessary start/stop functions, move to main Cache{} struct, add note regarding which caches require start/stop
* fix copy-paste artifact... 😇
* fix all comment copy-paste artifacts
* remove dropID() function, now we can just use slices.DeleteFunc()
* use util.Deduplicate() instead of collate(), move collate to util
* move orderByIDs() to util package and "generify"
* add a util.DeleteIf() function, use this to delete entries on failed population
* use slices.DeleteFunc() instead of util.DeleteIf() (i had the logic mixed up in my head somehow lol)
* add note about how collate differs from deduplicate
This commit is contained in:
parent
67e11a1a61
commit
7ec1e1332e
66 changed files with 4038 additions and 2711 deletions
76
vendor/codeberg.org/gruf/go-structr/result.go
generated
vendored
Normal file
76
vendor/codeberg.org/gruf/go-structr/result.go
generated
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
package structr
|
||||
|
||||
type result[T any] struct {
|
||||
// linked list entry this result is
|
||||
// stored under in Cache.lruList.
|
||||
entry elem[*result[T]]
|
||||
|
||||
// keys tracks the indices
|
||||
// result is stored under.
|
||||
keys []*indexkey[T]
|
||||
|
||||
// cached value.
|
||||
value T
|
||||
|
||||
// cached error.
|
||||
err error
|
||||
}
|
||||
|
||||
func result_acquire[T any](c *Cache[T]) *result[T] {
|
||||
var res *result[T]
|
||||
|
||||
if len(c.resPool) == 0 {
|
||||
// Allocate new result.
|
||||
res = new(result[T])
|
||||
} else {
|
||||
// Pop result from pool slice.
|
||||
res = c.resPool[len(c.resPool)-1]
|
||||
c.resPool = c.resPool[:len(c.resPool)-1]
|
||||
}
|
||||
|
||||
// Push to front of LRU list.
|
||||
c.lruList.pushFront(&res.entry)
|
||||
res.entry.Value = res
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func result_release[T any](c *Cache[T], res *result[T]) {
|
||||
// Remove from the LRU list.
|
||||
c.lruList.remove(&res.entry)
|
||||
res.entry.Value = nil
|
||||
|
||||
var zero T
|
||||
|
||||
// Reset all result fields.
|
||||
res.keys = res.keys[:0]
|
||||
res.value = zero
|
||||
res.err = nil
|
||||
|
||||
// Release result to memory pool.
|
||||
c.resPool = append(c.resPool, res)
|
||||
}
|
||||
|
||||
func result_dropIndex[T any](c *Cache[T], res *result[T], index *Index[T]) {
|
||||
for i := 0; i < len(res.keys); i++ {
|
||||
|
||||
if res.keys[i].index != index {
|
||||
// Prof. Obiwan:
|
||||
// this is not the index
|
||||
// we are looking for.
|
||||
continue
|
||||
}
|
||||
|
||||
// Get index key ptr.
|
||||
ikey := res.keys[i]
|
||||
|
||||
// Move all index keys down + reslice.
|
||||
copy(res.keys[i:], res.keys[i+1:])
|
||||
res.keys = res.keys[:len(res.keys)-1]
|
||||
|
||||
// Release ikey to memory pool.
|
||||
indexkey_release(c, ikey)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue