diff options
Diffstat (limited to 'vendor')
| -rw-r--r-- | vendor/codeberg.org/gruf/go-cache/v3/result/cache.go | 86 | ||||
| -rw-r--r-- | vendor/codeberg.org/gruf/go-cache/v3/result/key.go | 147 | ||||
| -rw-r--r-- | vendor/codeberg.org/gruf/go-cache/v3/simple/cache.go | 16 | ||||
| -rw-r--r-- | vendor/codeberg.org/gruf/go-cache/v3/simple/pool.go | 8 | ||||
| -rw-r--r-- | vendor/modules.txt | 2 | 
5 files changed, 144 insertions, 115 deletions
diff --git a/vendor/codeberg.org/gruf/go-cache/v3/result/cache.go b/vendor/codeberg.org/gruf/go-cache/v3/result/cache.go index f31e6604a..665481d55 100644 --- a/vendor/codeberg.org/gruf/go-cache/v3/result/cache.go +++ b/vendor/codeberg.org/gruf/go-cache/v3/result/cache.go @@ -11,28 +11,7 @@ import (  	"codeberg.org/gruf/go-errors/v2"  ) -type result struct { -	// Result primary key -	PKey int64 - -	// keys accessible under -	Keys cacheKeys - -	// cached value -	Value any - -	// cached error -	Error error -} - -// getResultValue is a safe way of casting and fetching result value. -func getResultValue[T any](res *result) T { -	v, ok := res.Value.(T) -	if !ok { -		fmt.Fprintf(os.Stderr, "!! BUG: unexpected value type in result: %T\n", res.Value) -	} -	return v -} +var ErrUnsupportedZero = errors.New("")  // Lookup represents a struct object lookup method in the cache.  type Lookup struct { @@ -255,13 +234,15 @@ func (c *Cache[T]) Load(lookup string, load func() (T, error), keyParts ...any)  		evict = c.store(res)  	} -	// Catch and return error -	if res.Error != nil { -		return zero, res.Error +	// Catch and return cached error +	if err := res.Error; err != nil { +		return zero, err  	} -	// Return a copy of value from cache -	return c.copy(getResultValue[T](res)), nil +	// Copy value from cached result. +	v := c.copy(getResultValue[T](res)) + +	return v, nil  }  // Store will call the given store function, and on success store the value in the cache as a positive result. @@ -332,11 +313,13 @@ func (c *Cache[T]) Has(lookup string, keyParts ...any) bool {  		}  	} +	// Check for result AND non-error result. +	ok := (res != nil && res.Error == nil) +  	// Done with lock  	c.cache.Unlock() -	// Check for result AND non-error result. -	return (res != nil && res.Error == nil) +	return ok  }  // Invalidate will invalidate any result from the cache found under given lookup and key parts. @@ -407,13 +390,18 @@ func (c *Cache[T]) store(res *result) (evict func()) {  		key.info.pkeys[key.key] = pkeys  	} +	// Acquire new cache entry. +	entry := simple.GetEntry() +	entry.Key = res.PKey +	entry.Value = res + +	evictFn := func(_ int64, entry *simple.Entry) { +		// on evict during set, store evicted result. +		toEvict = append(toEvict, entry.Value.(*result)) +	} +  	// Store main entry under primary key, catch evicted. -	c.cache.Cache.SetWithHook(res.PKey, &simple.Entry{ -		Key:   res.PKey, -		Value: res, -	}, func(_ int64, item *simple.Entry) { -		toEvict = append(toEvict, item.Value.(*result)) -	}) +	c.cache.Cache.SetWithHook(res.PKey, entry, evictFn)  	if len(toEvict) == 0 {  		// none evicted. @@ -421,9 +409,35 @@ func (c *Cache[T]) store(res *result) (evict func()) {  	}  	return func() { -		for _, res := range toEvict { +		for i := range toEvict { +			// Rescope result. +			res := toEvict[i] +  			// Call evict hook on each entry.  			c.cache.Evict(res.PKey, res)  		}  	}  } + +type result struct { +	// Result primary key +	PKey int64 + +	// keys accessible under +	Keys cacheKeys + +	// cached value +	Value any + +	// cached error +	Error error +} + +// getResultValue is a safe way of casting and fetching result value. +func getResultValue[T any](res *result) T { +	v, ok := res.Value.(T) +	if !ok { +		fmt.Fprintf(os.Stderr, "!! BUG: unexpected value type in result: %T\n", res.Value) +	} +	return v +} diff --git a/vendor/codeberg.org/gruf/go-cache/v3/result/key.go b/vendor/codeberg.org/gruf/go-cache/v3/result/key.go index cf86c7c30..5e10e6fa1 100644 --- a/vendor/codeberg.org/gruf/go-cache/v3/result/key.go +++ b/vendor/codeberg.org/gruf/go-cache/v3/result/key.go @@ -47,27 +47,32 @@ func (sk structKeys) generate(a any) []cacheKey {  	buf := getBuf()  	defer putBuf(buf) +outer:  	for i := range sk {  		// Reset buffer -		buf.B = buf.B[:0] +		buf.Reset()  		// Append each field value to buffer.  		for _, field := range sk[i].fields {  			fv := v.Field(field.index)  			fi := fv.Interface() -			buf.B = field.mangle(buf.B, fi) + +			// Mangle this key part into buffer. +			ok := field.manglePart(buf, fi) + +			if !ok { +				// don't generate keys +				// for zero value parts. +				continue outer +			} + +			// Append part separator.  			buf.B = append(buf.B, '.')  		}  		// Drop last '.'  		buf.Truncate(1) -		// Don't generate keys for zero values -		if allowZero := sk[i].zero == ""; // nocollapse -		!allowZero && buf.String() == sk[i].zero { -			continue -		} -  		// Append new cached key to slice  		keys = append(keys, cacheKey{  			info: &sk[i], @@ -114,14 +119,6 @@ type structKey struct {  	// period ('.') separated struct field names.  	name string -	// zero is the possible zero value for this key. -	// if set, this will _always_ be non-empty, as -	// the mangled cache key will never be empty. -	// -	// i.e. zero = ""  --> allow zero value keys -	//      zero != "" --> don't allow zero value keys -	zero string -  	// unique determines whether this structKey supports  	// multiple or just the singular unique result.  	unique bool @@ -135,47 +132,10 @@ type structKey struct {  	pkeys map[string][]int64  } -type structField struct { -	// index is the reflect index of this struct field. -	index int - -	// mangle is the mangler function for -	// serializing values of this struct field. -	mangle mangler.Mangler -} - -// genKey generates a cache key string for given key parts (i.e. serializes them using "go-mangler"). -func (sk *structKey) genKey(parts []any) string { -	// Check this expected no. key parts. -	if len(parts) != len(sk.fields) { -		panic(fmt.Sprintf("incorrect no. key parts provided: want=%d received=%d", len(parts), len(sk.fields))) -	} - -	// Acquire byte buffer -	buf := getBuf() -	defer putBuf(buf) -	buf.Reset() - -	// Encode each key part -	for i, part := range parts { -		buf.B = sk.fields[i].mangle(buf.B, part) -		buf.B = append(buf.B, '.') -	} - -	// Drop last '.' -	buf.Truncate(1) - -	// Return string copy -	return string(buf.B) -} -  // newStructKey will generate a structKey{} information object for user-given lookup  // key information, and the receiving generic paramter's type information. Panics on error.  func newStructKey(lk Lookup, t reflect.Type) structKey { -	var ( -		sk    structKey -		zeros []any -	) +	var sk structKey  	// Set the lookup name  	sk.name = lk.Name @@ -183,9 +143,6 @@ func newStructKey(lk Lookup, t reflect.Type) structKey {  	// Split dot-separated lookup to get  	// the individual struct field names  	names := strings.Split(lk.Name, ".") -	if len(names) == 0 { -		panic("no key fields specified") -	}  	// Allocate the mangler and field indices slice.  	sk.fields = make([]structField, len(names)) @@ -213,16 +170,12 @@ func newStructKey(lk Lookup, t reflect.Type) structKey {  		sk.fields[i].mangle = mangler.Get(ft.Type)  		if !lk.AllowZero { -			// Append the zero value interface -			zeros = append(zeros, v.Interface()) +			// Append the mangled zero value interface +			zero := sk.fields[i].mangle(nil, v.Interface()) +			sk.fields[i].zero = string(zero)  		}  	} -	if len(zeros) > 0 { -		// Generate zero value string -		sk.zero = sk.genKey(zeros) -	} -  	// Set unique lookup flag.  	sk.unique = !lk.Multi @@ -232,6 +185,68 @@ func newStructKey(lk Lookup, t reflect.Type) structKey {  	return sk  } +// genKey generates a cache key string for given key parts (i.e. serializes them using "go-mangler"). +func (sk *structKey) genKey(parts []any) string { +	// Check this expected no. key parts. +	if len(parts) != len(sk.fields) { +		panic(fmt.Sprintf("incorrect no. key parts provided: want=%d received=%d", len(parts), len(sk.fields))) +	} + +	// Acquire byte buffer +	buf := getBuf() +	defer putBuf(buf) +	buf.Reset() + +	for i, part := range parts { +		// Mangle this key part into buffer. +		// specifically ignoring whether this +		// is returning a zero value key part. +		_ = sk.fields[i].manglePart(buf, part) + +		// Append part separator. +		buf.B = append(buf.B, '.') +	} + +	// Drop last '.' +	buf.Truncate(1) + +	// Return string copy +	return string(buf.B) +} + +type structField struct { +	// index is the reflect index of this struct field. +	index int + +	// zero is the possible zero value for this +	// key part. if set, this will _always_ be +	// non-empty due to how the mangler works. +	// +	// i.e. zero = ""  --> allow zero value keys +	//      zero != "" --> don't allow zero value keys +	zero string + +	// mangle is the mangler function for +	// serializing values of this struct field. +	mangle mangler.Mangler +} + +// manglePart ... +func (field *structField) manglePart(buf *byteutil.Buffer, part any) bool { +	// Start of part bytes. +	start := len(buf.B) + +	// Mangle this key part into buffer. +	buf.B = field.mangle(buf.B, part) + +	// End of part bytes. +	end := len(buf.B) + +	// Return whether this is zero value. +	return (field.zero == "" || +		string(buf.B[start:end]) != field.zero) +} +  // isExported checks whether function name is exported.  func isExported(fnName string) bool {  	r, _ := utf8.DecodeRuneInString(fnName) @@ -246,12 +261,12 @@ var bufPool = sync.Pool{  	},  } -// getBuf ... +// getBuf acquires a byte buffer from memory pool.  func getBuf() *byteutil.Buffer {  	return bufPool.Get().(*byteutil.Buffer)  } -// putBuf ... +// putBuf replaces a byte buffer back in memory pool.  func putBuf(buf *byteutil.Buffer) {  	if buf.Cap() > int(^uint16(0)) {  		return // drop large bufs diff --git a/vendor/codeberg.org/gruf/go-cache/v3/simple/cache.go b/vendor/codeberg.org/gruf/go-cache/v3/simple/cache.go index 0224871bc..1452a0648 100644 --- a/vendor/codeberg.org/gruf/go-cache/v3/simple/cache.go +++ b/vendor/codeberg.org/gruf/go-cache/v3/simple/cache.go @@ -102,7 +102,7 @@ func (c *Cache[K, V]) Add(key K, value V) bool {  		}  		// Alloc new entry. -		new := getEntry() +		new := GetEntry()  		new.Key = key  		new.Value = value @@ -111,7 +111,7 @@ func (c *Cache[K, V]) Add(key K, value V) bool {  			evcK = item.Key.(K)  			evcV = item.Value.(V)  			ev = true -			putEntry(item) +			PutEntry(item)  		})  		// Set hook func ptr. @@ -161,7 +161,7 @@ func (c *Cache[K, V]) Set(key K, value V) {  			item.Value = value  		} else {  			// Alloc new entry. -			new := getEntry() +			new := GetEntry()  			new.Key = key  			new.Value = value @@ -170,7 +170,7 @@ func (c *Cache[K, V]) Set(key K, value V) {  				evcK = item.Key.(K)  				evcV = item.Value.(V)  				ev = true -				putEntry(item) +				PutEntry(item)  			})  		} @@ -311,7 +311,7 @@ func (c *Cache[K, V]) Invalidate(key K) (ok bool) {  		_ = c.Cache.Delete(key)  		// Free entry -		putEntry(item) +		PutEntry(item)  		// Set hook func ptrs.  		invalid = c.Invalid @@ -367,7 +367,7 @@ func (c *Cache[K, V]) InvalidateAll(keys ...K) (ok bool) {  			invalid(k, v)  			// Free this entry. -			putEntry(items[x]) +			PutEntry(items[x])  		}  	} @@ -410,7 +410,7 @@ func (c *Cache[K, V]) Trim(perc float64) {  			invalid(k, v)  			// Free this entry. -			putEntry(items[x]) +			PutEntry(items[x])  		}  	}  } @@ -438,7 +438,7 @@ func (c *Cache[K, V]) locked(fn func()) {  func (c *Cache[K, V]) truncate(sz int, hook func(K, V)) []*Entry {  	if hook == nil {  		// No hook to execute, simply release all truncated entries. -		c.Cache.Truncate(sz, func(_ K, item *Entry) { putEntry(item) }) +		c.Cache.Truncate(sz, func(_ K, item *Entry) { PutEntry(item) })  		return nil  	} diff --git a/vendor/codeberg.org/gruf/go-cache/v3/simple/pool.go b/vendor/codeberg.org/gruf/go-cache/v3/simple/pool.go index 2fc99ab0f..34ae17546 100644 --- a/vendor/codeberg.org/gruf/go-cache/v3/simple/pool.go +++ b/vendor/codeberg.org/gruf/go-cache/v3/simple/pool.go @@ -6,8 +6,8 @@ import "sync"  // objects, regardless of cache type.  var entryPool sync.Pool -// getEntry fetches an Entry from pool, or allocates new. -func getEntry() *Entry { +// GetEntry fetches an Entry from pool, or allocates new. +func GetEntry() *Entry {  	v := entryPool.Get()  	if v == nil {  		return new(Entry) @@ -15,8 +15,8 @@ func getEntry() *Entry {  	return v.(*Entry)  } -// putEntry replaces an Entry in the pool. -func putEntry(e *Entry) { +// PutEntry replaces an Entry in the pool. +func PutEntry(e *Entry) {  	e.Key = nil  	e.Value = nil  	entryPool.Put(e) diff --git a/vendor/modules.txt b/vendor/modules.txt index a711fcba7..54425e3d3 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -13,7 +13,7 @@ codeberg.org/gruf/go-bytesize  # codeberg.org/gruf/go-byteutil v1.1.2  ## explicit; go 1.16  codeberg.org/gruf/go-byteutil -# codeberg.org/gruf/go-cache/v3 v3.5.3 +# codeberg.org/gruf/go-cache/v3 v3.5.5  ## explicit; go 1.19  codeberg.org/gruf/go-cache/v3  codeberg.org/gruf/go-cache/v3/result  | 
