mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2024-11-24 18:25:57 +03:00
update go-structr to v0.8.11 (#3380)
This commit is contained in:
parent
e3019eada4
commit
c17abea921
11 changed files with 306 additions and 91 deletions
2
go.mod
2
go.mod
|
@ -22,7 +22,7 @@ require (
|
||||||
codeberg.org/gruf/go-runners v1.6.3
|
codeberg.org/gruf/go-runners v1.6.3
|
||||||
codeberg.org/gruf/go-sched v1.2.4
|
codeberg.org/gruf/go-sched v1.2.4
|
||||||
codeberg.org/gruf/go-storage v0.2.0
|
codeberg.org/gruf/go-storage v0.2.0
|
||||||
codeberg.org/gruf/go-structr v0.8.10
|
codeberg.org/gruf/go-structr v0.8.11
|
||||||
codeberg.org/superseriousbusiness/exif-terminator v0.9.0
|
codeberg.org/superseriousbusiness/exif-terminator v0.9.0
|
||||||
github.com/DmitriyVTitov/size v1.5.0
|
github.com/DmitriyVTitov/size v1.5.0
|
||||||
github.com/KimMachineGun/automemlimit v0.6.1
|
github.com/KimMachineGun/automemlimit v0.6.1
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -72,8 +72,8 @@ codeberg.org/gruf/go-sched v1.2.4 h1:ddBB9o0D/2oU8NbQ0ldN5aWxogpXPRBATWi58+p++Hw
|
||||||
codeberg.org/gruf/go-sched v1.2.4/go.mod h1:wad6l+OcYGWMA2TzNLMmLObsrbBDxdJfEy5WvTgBjNk=
|
codeberg.org/gruf/go-sched v1.2.4/go.mod h1:wad6l+OcYGWMA2TzNLMmLObsrbBDxdJfEy5WvTgBjNk=
|
||||||
codeberg.org/gruf/go-storage v0.2.0 h1:mKj3Lx6AavEkuXXtxqPhdq+akW9YwrnP16yQBF7K5ZI=
|
codeberg.org/gruf/go-storage v0.2.0 h1:mKj3Lx6AavEkuXXtxqPhdq+akW9YwrnP16yQBF7K5ZI=
|
||||||
codeberg.org/gruf/go-storage v0.2.0/go.mod h1:o3GzMDE5QNUaRnm/daUzFqvuAaC4utlgXDXYO79sWKU=
|
codeberg.org/gruf/go-storage v0.2.0/go.mod h1:o3GzMDE5QNUaRnm/daUzFqvuAaC4utlgXDXYO79sWKU=
|
||||||
codeberg.org/gruf/go-structr v0.8.10 h1:uSapW97/StRnYEhCtycaM0isCsEMYC+tx/knYr6SiVo=
|
codeberg.org/gruf/go-structr v0.8.11 h1:I3cQCHpK3fQSXWaaUfksAJRN4+efULiuF11Oi/m8c+o=
|
||||||
codeberg.org/gruf/go-structr v0.8.10/go.mod h1:zkoXVrAnKosh8VFAsbP/Hhs8FmLBjbVVy5w/Ngm8ApM=
|
codeberg.org/gruf/go-structr v0.8.11/go.mod h1:zkoXVrAnKosh8VFAsbP/Hhs8FmLBjbVVy5w/Ngm8ApM=
|
||||||
codeberg.org/superseriousbusiness/exif-terminator v0.9.0 h1:/EfyGI6HIrbkhFwgXGSjZ9o1kr/+k8v4mKdfXTH02Go=
|
codeberg.org/superseriousbusiness/exif-terminator v0.9.0 h1:/EfyGI6HIrbkhFwgXGSjZ9o1kr/+k8v4mKdfXTH02Go=
|
||||||
codeberg.org/superseriousbusiness/exif-terminator v0.9.0/go.mod h1:gCWKduudUWFzsnixoMzu0FYVdxHWG+AbXnZ50DqxsUE=
|
codeberg.org/superseriousbusiness/exif-terminator v0.9.0/go.mod h1:gCWKduudUWFzsnixoMzu0FYVdxHWG+AbXnZ50DqxsUE=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
|
|
47
vendor/codeberg.org/gruf/go-structr/cache.go
generated
vendored
47
vendor/codeberg.org/gruf/go-structr/cache.go
generated
vendored
|
@ -119,9 +119,9 @@ func (c *Cache[T]) Init(config CacheConfig[T]) {
|
||||||
|
|
||||||
// Index selects index with given name from cache, else panics.
|
// Index selects index with given name from cache, else panics.
|
||||||
func (c *Cache[T]) Index(name string) *Index {
|
func (c *Cache[T]) Index(name string) *Index {
|
||||||
for i := range c.indices {
|
for i, idx := range c.indices {
|
||||||
if c.indices[i].name == name {
|
if idx.name == name {
|
||||||
return &c.indices[i]
|
return &(c.indices[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panic("unknown index: " + name)
|
panic("unknown index: " + name)
|
||||||
|
@ -337,13 +337,16 @@ func (c *Cache[T]) Load(index *Index, keys []Key, load func([]Key) ([]T, error))
|
||||||
panic("not initialized")
|
panic("not initialized")
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(keys); {
|
// Iterate keys and catch uncached.
|
||||||
|
toLoad := make([]Key, 0, len(keys))
|
||||||
|
for _, key := range keys {
|
||||||
|
|
||||||
// Value length before
|
// Value length before
|
||||||
// any below appends.
|
// any below appends.
|
||||||
before := len(values)
|
before := len(values)
|
||||||
|
|
||||||
// Concatenate all *values* from cached items.
|
// Concatenate all *values* from cached items.
|
||||||
index.get(keys[i].key, func(item *indexed_item) {
|
index.get(key.key, func(item *indexed_item) {
|
||||||
if value, ok := item.data.(T); ok {
|
if value, ok := item.data.(T); ok {
|
||||||
// Append value COPY.
|
// Append value COPY.
|
||||||
value = c.copy(value)
|
value = c.copy(value)
|
||||||
|
@ -358,30 +361,22 @@ func (c *Cache[T]) Load(index *Index, keys []Key, load func([]Key) ([]T, error))
|
||||||
|
|
||||||
// Only if values changed did
|
// Only if values changed did
|
||||||
// we actually find anything.
|
// we actually find anything.
|
||||||
if len(values) != before {
|
if len(values) == before {
|
||||||
|
toLoad = append(toLoad, key)
|
||||||
// We found values at key,
|
|
||||||
// drop key from the slice.
|
|
||||||
copy(keys[i:], keys[i+1:])
|
|
||||||
keys = keys[:len(keys)-1]
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iter
|
|
||||||
i++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Done with
|
// Done with
|
||||||
// the lock.
|
// the lock.
|
||||||
unlock()
|
unlock()
|
||||||
|
|
||||||
if len(keys) == 0 {
|
if len(toLoad) == 0 {
|
||||||
// We loaded everything!
|
// We loaded everything!
|
||||||
return values, nil
|
return values, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load uncached values.
|
// Load uncached key values.
|
||||||
uncached, err := load(keys)
|
uncached, err := load(toLoad)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -515,8 +510,8 @@ func (c *Cache[T]) Trim(perc float64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compact index data stores.
|
// Compact index data stores.
|
||||||
for i := range c.indices {
|
for _, idx := range c.indices {
|
||||||
c.indices[i].data.Compact()
|
(&idx).data.Compact()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Done with lock.
|
// Done with lock.
|
||||||
|
@ -536,17 +531,17 @@ func (c *Cache[T]) Len() int {
|
||||||
|
|
||||||
// Debug returns debug stats about cache.
|
// Debug returns debug stats about cache.
|
||||||
func (c *Cache[T]) Debug() map[string]any {
|
func (c *Cache[T]) Debug() map[string]any {
|
||||||
m := make(map[string]any)
|
m := make(map[string]any, 2)
|
||||||
c.mutex.Lock()
|
c.mutex.Lock()
|
||||||
m["lru"] = c.lru.len
|
m["lru"] = c.lru.len
|
||||||
indices := make(map[string]any)
|
indices := make(map[string]any, len(c.indices))
|
||||||
m["indices"] = indices
|
m["indices"] = indices
|
||||||
for i := range c.indices {
|
for _, idx := range c.indices {
|
||||||
var n uint64
|
var n uint64
|
||||||
for _, l := range c.indices[i].data.m {
|
for _, l := range idx.data.m {
|
||||||
n += uint64(l.len)
|
n += uint64(l.len)
|
||||||
}
|
}
|
||||||
indices[c.indices[i].name] = n
|
indices[idx.name] = n
|
||||||
}
|
}
|
||||||
c.mutex.Unlock()
|
c.mutex.Unlock()
|
||||||
return m
|
return m
|
||||||
|
@ -588,7 +583,7 @@ func (c *Cache[T]) store_value(index *Index, key string, value T) {
|
||||||
|
|
||||||
for i := range c.indices {
|
for i := range c.indices {
|
||||||
// Get current index ptr.
|
// Get current index ptr.
|
||||||
idx := &(c.indices[i])
|
idx := (&c.indices[i])
|
||||||
if idx == index {
|
if idx == index {
|
||||||
|
|
||||||
// Already stored under
|
// Already stored under
|
||||||
|
|
42
vendor/codeberg.org/gruf/go-structr/index.go
generated
vendored
42
vendor/codeberg.org/gruf/go-structr/index.go
generated
vendored
|
@ -197,8 +197,13 @@ func (i *Index) get(key string, hook func(*indexed_item)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate all entries in list.
|
// Iterate the list.
|
||||||
l.rangefn(func(elem *list_elem) {
|
for elem := l.head; //
|
||||||
|
elem != nil; //
|
||||||
|
{
|
||||||
|
// Get next before
|
||||||
|
// any modification.
|
||||||
|
next := elem.next
|
||||||
|
|
||||||
// Extract element entry + item.
|
// Extract element entry + item.
|
||||||
entry := (*index_entry)(elem.data)
|
entry := (*index_entry)(elem.data)
|
||||||
|
@ -206,18 +211,21 @@ func (i *Index) get(key string, hook func(*indexed_item)) {
|
||||||
|
|
||||||
// Pass to hook.
|
// Pass to hook.
|
||||||
hook(item)
|
hook(item)
|
||||||
})
|
|
||||||
|
// Set next.
|
||||||
|
elem = next
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// key uses hasher to generate Key{} from given raw parts.
|
// key uses hasher to generate Key{} from given raw parts.
|
||||||
func (i *Index) key(buf *byteutil.Buffer, parts []unsafe.Pointer) string {
|
func (i *Index) key(buf *byteutil.Buffer, parts []unsafe.Pointer) string {
|
||||||
|
buf.B = buf.B[:0]
|
||||||
if len(parts) != len(i.fields) {
|
if len(parts) != len(i.fields) {
|
||||||
panicf("incorrect number key parts: want=%d received=%d",
|
panicf("incorrect number key parts: want=%d received=%d",
|
||||||
len(i.fields),
|
len(i.fields),
|
||||||
len(parts),
|
len(parts),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
buf.B = buf.B[:0]
|
|
||||||
if !allow_zero(i.flags) {
|
if !allow_zero(i.flags) {
|
||||||
for x, field := range i.fields {
|
for x, field := range i.fields {
|
||||||
before := len(buf.B)
|
before := len(buf.B)
|
||||||
|
@ -301,8 +309,13 @@ func (i *Index) delete(key string, hook func(*indexed_item)) {
|
||||||
// Delete at hash.
|
// Delete at hash.
|
||||||
i.data.Delete(key)
|
i.data.Delete(key)
|
||||||
|
|
||||||
// Iterate entries in list.
|
// Iterate the list.
|
||||||
l.rangefn(func(elem *list_elem) {
|
for elem := l.head; //
|
||||||
|
elem != nil; //
|
||||||
|
{
|
||||||
|
// Get next before
|
||||||
|
// any modification.
|
||||||
|
next := elem.next
|
||||||
|
|
||||||
// Remove elem.
|
// Remove elem.
|
||||||
l.remove(elem)
|
l.remove(elem)
|
||||||
|
@ -319,7 +332,10 @@ func (i *Index) delete(key string, hook func(*indexed_item)) {
|
||||||
|
|
||||||
// Pass to hook.
|
// Pass to hook.
|
||||||
hook(item)
|
hook(item)
|
||||||
})
|
|
||||||
|
// Set next.
|
||||||
|
elem = next
|
||||||
|
}
|
||||||
|
|
||||||
// Release list.
|
// Release list.
|
||||||
free_list(l)
|
free_list(l)
|
||||||
|
@ -375,17 +391,21 @@ var index_entry_pool sync.Pool
|
||||||
func new_index_entry() *index_entry {
|
func new_index_entry() *index_entry {
|
||||||
v := index_entry_pool.Get()
|
v := index_entry_pool.Get()
|
||||||
if v == nil {
|
if v == nil {
|
||||||
v = new(index_entry)
|
e := new(index_entry)
|
||||||
|
e.elem.data = unsafe.Pointer(e)
|
||||||
|
v = e
|
||||||
}
|
}
|
||||||
entry := v.(*index_entry)
|
entry := v.(*index_entry)
|
||||||
ptr := unsafe.Pointer(entry)
|
|
||||||
entry.elem.data = ptr
|
|
||||||
return entry
|
return entry
|
||||||
}
|
}
|
||||||
|
|
||||||
// free_index_entry releases the index_entry.
|
// free_index_entry releases the index_entry.
|
||||||
func free_index_entry(entry *index_entry) {
|
func free_index_entry(entry *index_entry) {
|
||||||
entry.elem.data = nil
|
if entry.elem.next != nil ||
|
||||||
|
entry.elem.prev != nil {
|
||||||
|
should_not_reach()
|
||||||
|
return
|
||||||
|
}
|
||||||
entry.key = ""
|
entry.key = ""
|
||||||
entry.index = nil
|
entry.index = nil
|
||||||
entry.item = nil
|
entry.item = nil
|
||||||
|
|
16
vendor/codeberg.org/gruf/go-structr/item.go
generated
vendored
16
vendor/codeberg.org/gruf/go-structr/item.go
generated
vendored
|
@ -24,18 +24,22 @@ var indexed_item_pool sync.Pool
|
||||||
func new_indexed_item() *indexed_item {
|
func new_indexed_item() *indexed_item {
|
||||||
v := indexed_item_pool.Get()
|
v := indexed_item_pool.Get()
|
||||||
if v == nil {
|
if v == nil {
|
||||||
v = new(indexed_item)
|
i := new(indexed_item)
|
||||||
|
i.elem.data = unsafe.Pointer(i)
|
||||||
|
v = i
|
||||||
}
|
}
|
||||||
item := v.(*indexed_item)
|
item := v.(*indexed_item)
|
||||||
ptr := unsafe.Pointer(item)
|
|
||||||
item.elem.data = ptr
|
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
|
|
||||||
// free_indexed_item releases the indexed_item.
|
// free_indexed_item releases the indexed_item.
|
||||||
func free_indexed_item(item *indexed_item) {
|
func free_indexed_item(item *indexed_item) {
|
||||||
item.elem.data = nil
|
if len(item.indexed) > 0 ||
|
||||||
item.indexed = item.indexed[:0]
|
item.elem.next != nil ||
|
||||||
|
item.elem.prev != nil {
|
||||||
|
should_not_reach()
|
||||||
|
return
|
||||||
|
}
|
||||||
item.data = nil
|
item.data = nil
|
||||||
indexed_item_pool.Put(item)
|
indexed_item_pool.Put(item)
|
||||||
}
|
}
|
||||||
|
@ -50,7 +54,7 @@ func (i *indexed_item) drop_index(entry *index_entry) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move all index entries down + reslice.
|
// Reslice index entries minus 'x'.
|
||||||
_ = copy(i.indexed[x:], i.indexed[x+1:])
|
_ = copy(i.indexed[x:], i.indexed[x+1:])
|
||||||
i.indexed[len(i.indexed)-1] = nil
|
i.indexed[len(i.indexed)-1] = nil
|
||||||
i.indexed = i.indexed[:len(i.indexed)-1]
|
i.indexed = i.indexed[:len(i.indexed)-1]
|
||||||
|
|
46
vendor/codeberg.org/gruf/go-structr/list.go
generated
vendored
46
vendor/codeberg.org/gruf/go-structr/list.go
generated
vendored
|
@ -40,9 +40,12 @@ func new_list() *list {
|
||||||
|
|
||||||
// free_list releases the list.
|
// free_list releases the list.
|
||||||
func free_list(list *list) {
|
func free_list(list *list) {
|
||||||
list.head = nil
|
if list.head != nil ||
|
||||||
list.tail = nil
|
list.tail != nil ||
|
||||||
list.len = 0
|
list.len != 0 {
|
||||||
|
should_not_reach()
|
||||||
|
return
|
||||||
|
}
|
||||||
list_pool.Put(list)
|
list_pool.Put(list)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,20 +118,27 @@ func (l *list) remove(elem *list_elem) {
|
||||||
elem.prev = nil
|
elem.prev = nil
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
case next == nil:
|
||||||
|
if prev == nil {
|
||||||
|
// next == nil && prev == nil
|
||||||
|
//
|
||||||
// elem is ONLY one in list.
|
// elem is ONLY one in list.
|
||||||
case next == nil && prev == nil:
|
|
||||||
l.head = nil
|
l.head = nil
|
||||||
l.tail = nil
|
l.tail = nil
|
||||||
|
} else {
|
||||||
// elem is front in list.
|
// next == nil && prev != nil
|
||||||
case next != nil && prev == nil:
|
//
|
||||||
l.head = next
|
|
||||||
next.prev = nil
|
|
||||||
|
|
||||||
// elem is last in list.
|
// elem is last in list.
|
||||||
case prev != nil && next == nil:
|
|
||||||
l.tail = prev
|
l.tail = prev
|
||||||
prev.next = nil
|
prev.next = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
case prev == nil:
|
||||||
|
// next != nil && prev == nil
|
||||||
|
//
|
||||||
|
// elem is front in list.
|
||||||
|
l.head = next
|
||||||
|
next.prev = nil
|
||||||
|
|
||||||
// elem in middle of list.
|
// elem in middle of list.
|
||||||
default:
|
default:
|
||||||
|
@ -139,17 +149,3 @@ func (l *list) remove(elem *list_elem) {
|
||||||
// Decr count
|
// Decr count
|
||||||
l.len--
|
l.len--
|
||||||
}
|
}
|
||||||
|
|
||||||
// rangefn will range all elems in list, passing each to fn.
|
|
||||||
func (l *list) rangefn(fn func(*list_elem)) {
|
|
||||||
if fn == nil {
|
|
||||||
panic("nil fn")
|
|
||||||
}
|
|
||||||
for e := l.head; //
|
|
||||||
e != nil; //
|
|
||||||
{
|
|
||||||
n := e.next
|
|
||||||
fn(e)
|
|
||||||
e = n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
180
vendor/codeberg.org/gruf/go-structr/ordered_list.bak
generated
vendored
Normal file
180
vendor/codeberg.org/gruf/go-structr/ordered_list.bak
generated
vendored
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
package structr
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
|
type Timeline[StructType any, PK comparable] struct {
|
||||||
|
|
||||||
|
// hook functions.
|
||||||
|
pkey func(StructType) PK
|
||||||
|
gte func(PK, PK) bool
|
||||||
|
lte func(PK, PK) bool
|
||||||
|
copy func(StructType) StructType
|
||||||
|
|
||||||
|
// main underlying
|
||||||
|
// ordered item list.
|
||||||
|
list list
|
||||||
|
|
||||||
|
// indices used in storing passed struct
|
||||||
|
// types by user defined sets of fields.
|
||||||
|
indices []Index
|
||||||
|
|
||||||
|
// protective mutex, guards:
|
||||||
|
// - TODO
|
||||||
|
mutex sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Timeline[T, PK]) Init(config any) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Timeline[T, PK]) Index(name string) *Index {
|
||||||
|
for i := range t.indices {
|
||||||
|
if t.indices[i].name == name {
|
||||||
|
return &t.indices[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic("unknown index: " + name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Timeline[T, PK]) Insert(values ...T) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Timeline[T, PK]) LoadTop(min, max PK, length int, load func(min, max PK, length int) ([]T, error)) ([]T, error) {
|
||||||
|
// Allocate expected no. values.
|
||||||
|
values := make([]T, 0, length)
|
||||||
|
|
||||||
|
// Acquire lock.
|
||||||
|
t.mutex.Lock()
|
||||||
|
|
||||||
|
// Wrap unlock to only do once.
|
||||||
|
unlock := once(t.mutex.Unlock)
|
||||||
|
defer unlock()
|
||||||
|
|
||||||
|
// Check init'd.
|
||||||
|
if t.copy == nil {
|
||||||
|
panic("not initialized")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate through linked list from top (i.e. head).
|
||||||
|
for next := t.list.head; next != nil; next = next.next {
|
||||||
|
|
||||||
|
// Check if we've gathered
|
||||||
|
// enough values from timeline.
|
||||||
|
if len(values) >= length {
|
||||||
|
return values, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
item := (*indexed_item)(next.data)
|
||||||
|
value := item.data.(T)
|
||||||
|
pkey := t.pkey(value)
|
||||||
|
|
||||||
|
// Check if below min.
|
||||||
|
if t.lte(pkey, min) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update min.
|
||||||
|
min = pkey
|
||||||
|
|
||||||
|
// Check if above max.
|
||||||
|
if t.gte(pkey, max) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append value copy.
|
||||||
|
value = t.copy(value)
|
||||||
|
values = append(values, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Timeline[T, PK]) LoadBottom(min, max PK, length int, load func(min, max PK, length int) ([]T, error)) ([]T, error) {
|
||||||
|
// Allocate expected no. values.
|
||||||
|
values := make([]T, 0, length)
|
||||||
|
|
||||||
|
// Acquire lock.
|
||||||
|
t.mutex.Lock()
|
||||||
|
|
||||||
|
// Wrap unlock to only do once.
|
||||||
|
unlock := once(t.mutex.Unlock)
|
||||||
|
defer unlock()
|
||||||
|
|
||||||
|
// Check init'd.
|
||||||
|
if t.copy == nil {
|
||||||
|
panic("not initialized")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate through linked list from bottom (i.e. tail).
|
||||||
|
for next := t.list.tail; next != nil; next = next.prev {
|
||||||
|
|
||||||
|
// Check if we've gathered
|
||||||
|
// enough values from timeline.
|
||||||
|
if len(values) >= length {
|
||||||
|
return values, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
item := (*indexed_item)(next.data)
|
||||||
|
value := item.data.(T)
|
||||||
|
pkey := t.pkey(value)
|
||||||
|
|
||||||
|
// Check if above max.
|
||||||
|
if t.gte(pkey, max) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update max.
|
||||||
|
max = pkey
|
||||||
|
|
||||||
|
// Check if below min.
|
||||||
|
if t.lte(pkey, min) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append value copy.
|
||||||
|
value = t.copy(value)
|
||||||
|
values = append(values, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done with
|
||||||
|
// the lock.
|
||||||
|
unlock()
|
||||||
|
|
||||||
|
// Attempt to load values up to given length.
|
||||||
|
next, err := load(min, max, length-len(values))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Acquire lock.
|
||||||
|
t.mutex.Lock()
|
||||||
|
|
||||||
|
// Store uncached values.
|
||||||
|
for i := range next {
|
||||||
|
t.store_value(
|
||||||
|
nil, "",
|
||||||
|
uncached[i],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done with lock.
|
||||||
|
t.mutex.Unlock()
|
||||||
|
|
||||||
|
// Append uncached to return values.
|
||||||
|
values = append(values, next...)
|
||||||
|
|
||||||
|
return values, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Timeline[T, PK]) index(value T) *indexed_item {
|
||||||
|
pk := t.pkey(value)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case t.list.len == 0:
|
||||||
|
|
||||||
|
case pk < t.list.head.data:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Timeline[T, PK]) delete(item *indexed_item) {
|
||||||
|
|
||||||
|
}
|
16
vendor/codeberg.org/gruf/go-structr/queue.go
generated
vendored
16
vendor/codeberg.org/gruf/go-structr/queue.go
generated
vendored
|
@ -68,9 +68,9 @@ func (q *Queue[T]) Init(config QueueConfig[T]) {
|
||||||
|
|
||||||
// Index selects index with given name from queue, else panics.
|
// Index selects index with given name from queue, else panics.
|
||||||
func (q *Queue[T]) Index(name string) *Index {
|
func (q *Queue[T]) Index(name string) *Index {
|
||||||
for i := range q.indices {
|
for i, idx := range q.indices {
|
||||||
if q.indices[i].name == name {
|
if idx.name == name {
|
||||||
return &q.indices[i]
|
return &(q.indices[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panic("unknown index: " + name)
|
panic("unknown index: " + name)
|
||||||
|
@ -207,17 +207,17 @@ func (q *Queue[T]) Len() int {
|
||||||
|
|
||||||
// Debug returns debug stats about queue.
|
// Debug returns debug stats about queue.
|
||||||
func (q *Queue[T]) Debug() map[string]any {
|
func (q *Queue[T]) Debug() map[string]any {
|
||||||
m := make(map[string]any)
|
m := make(map[string]any, 2)
|
||||||
q.mutex.Lock()
|
q.mutex.Lock()
|
||||||
m["queue"] = q.queue.len
|
m["queue"] = q.queue.len
|
||||||
indices := make(map[string]any)
|
indices := make(map[string]any, len(q.indices))
|
||||||
m["indices"] = indices
|
m["indices"] = indices
|
||||||
for i := range q.indices {
|
for _, idx := range q.indices {
|
||||||
var n uint64
|
var n uint64
|
||||||
for _, l := range q.indices[i].data.m {
|
for _, l := range idx.data.m {
|
||||||
n += uint64(l.len)
|
n += uint64(l.len)
|
||||||
}
|
}
|
||||||
indices[q.indices[i].name] = n
|
indices[idx.name] = n
|
||||||
}
|
}
|
||||||
q.mutex.Unlock()
|
q.mutex.Unlock()
|
||||||
return m
|
return m
|
||||||
|
|
28
vendor/codeberg.org/gruf/go-structr/runtime.go
generated
vendored
28
vendor/codeberg.org/gruf/go-structr/runtime.go
generated
vendored
|
@ -2,7 +2,10 @@ package structr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
@ -182,7 +185,32 @@ func deref(p unsafe.Pointer, n uint) unsafe.Pointer {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eface_data returns the data ptr from an empty interface.
|
||||||
|
func eface_data(a any) unsafe.Pointer {
|
||||||
|
type eface struct{ _, data unsafe.Pointer }
|
||||||
|
return (*eface)(unsafe.Pointer(&a)).data
|
||||||
|
}
|
||||||
|
|
||||||
// panicf provides a panic with string formatting.
|
// panicf provides a panic with string formatting.
|
||||||
func panicf(format string, args ...any) {
|
func panicf(format string, args ...any) {
|
||||||
panic(fmt.Sprintf(format, args...))
|
panic(fmt.Sprintf(format, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// should_not_reach can be called to indicated a
|
||||||
|
// block of code should not be able to be reached,
|
||||||
|
// else it prints callsite info with a BUG report.
|
||||||
|
//
|
||||||
|
//go:noinline
|
||||||
|
func should_not_reach() {
|
||||||
|
pcs := make([]uintptr, 1)
|
||||||
|
_ = runtime.Callers(2, pcs)
|
||||||
|
fn := runtime.FuncForPC(pcs[0])
|
||||||
|
funcname := "go-structr" // by default use just our library name
|
||||||
|
if fn != nil {
|
||||||
|
funcname = fn.Name()
|
||||||
|
if i := strings.LastIndexByte(funcname, '/'); i != -1 {
|
||||||
|
funcname = funcname[i+1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
os.Stderr.WriteString("BUG: assertion failed in " + funcname + "\n")
|
||||||
|
}
|
||||||
|
|
8
vendor/codeberg.org/gruf/go-structr/util.go
generated
vendored
8
vendor/codeberg.org/gruf/go-structr/util.go
generated
vendored
|
@ -1,7 +1,5 @@
|
||||||
package structr
|
package structr
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
// once only executes 'fn' once.
|
// once only executes 'fn' once.
|
||||||
func once(fn func()) func() {
|
func once(fn func()) func() {
|
||||||
var once int32
|
var once int32
|
||||||
|
@ -13,9 +11,3 @@ func once(fn func()) func() {
|
||||||
fn()
|
fn()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// eface_data returns the data ptr from an empty interface.
|
|
||||||
func eface_data(a any) unsafe.Pointer {
|
|
||||||
type eface struct{ _, data unsafe.Pointer }
|
|
||||||
return (*eface)(unsafe.Pointer(&a)).data
|
|
||||||
}
|
|
||||||
|
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
|
@ -66,7 +66,7 @@ codeberg.org/gruf/go-storage/disk
|
||||||
codeberg.org/gruf/go-storage/internal
|
codeberg.org/gruf/go-storage/internal
|
||||||
codeberg.org/gruf/go-storage/memory
|
codeberg.org/gruf/go-storage/memory
|
||||||
codeberg.org/gruf/go-storage/s3
|
codeberg.org/gruf/go-storage/s3
|
||||||
# codeberg.org/gruf/go-structr v0.8.10
|
# codeberg.org/gruf/go-structr v0.8.11
|
||||||
## explicit; go 1.21
|
## explicit; go 1.21
|
||||||
codeberg.org/gruf/go-structr
|
codeberg.org/gruf/go-structr
|
||||||
# codeberg.org/superseriousbusiness/exif-terminator v0.9.0
|
# codeberg.org/superseriousbusiness/exif-terminator v0.9.0
|
||||||
|
|
Loading…
Reference in a new issue