summaryrefslogtreecommitdiff
path: root/vendor/codeberg.org/gruf/go-cache/v3/result/key.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/codeberg.org/gruf/go-cache/v3/result/key.go')
-rw-r--r--vendor/codeberg.org/gruf/go-cache/v3/result/key.go282
1 files changed, 0 insertions, 282 deletions
diff --git a/vendor/codeberg.org/gruf/go-cache/v3/result/key.go b/vendor/codeberg.org/gruf/go-cache/v3/result/key.go
deleted file mode 100644
index 5508936ba..000000000
--- a/vendor/codeberg.org/gruf/go-cache/v3/result/key.go
+++ /dev/null
@@ -1,282 +0,0 @@
-package result
-
-import (
- "fmt"
- "reflect"
- "strings"
- "sync"
- "unicode"
- "unicode/utf8"
-
- "codeberg.org/gruf/go-byteutil"
- "codeberg.org/gruf/go-mangler"
-)
-
-// structKeys provides convience methods for a list
-// of structKey field combinations used for cache keys.
-type structKeys []structKey
-
-// get fetches the structKey info for given lookup name (else, panics).
-func (sk structKeys) get(name string) *structKey {
- for i := range sk {
- if sk[i].name == name {
- return &sk[i]
- }
- }
- panic("unknown lookup: \"" + name + "\"")
-}
-
-// generate will calculate and produce a slice of cache keys the given value
-// can be stored under in the, as determined by receiving struct keys.
-func (sk structKeys) generate(a any) []cacheKey {
- var keys []cacheKey
-
- // Get reflected value in order
- // to access the struct fields
- v := reflect.ValueOf(a)
-
- // Iteratively deref pointer value
- for v.Kind() == reflect.Pointer {
- if v.IsNil() {
- panic("nil ptr")
- }
- v = v.Elem()
- }
-
- // Acquire buffer
- buf := getBuf()
-
-outer:
- for i := range sk {
- // Reset buffer
- buf.Reset()
-
- // Append each field value to buffer.
- for _, field := range sk[i].fields {
- fv := v.Field(field.index)
- fi := fv.Interface()
-
- // 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)
-
- // Append new cached key to slice
- keys = append(keys, cacheKey{
- info: &sk[i],
- key: string(buf.B), // copy
- })
- }
-
- // Release buf
- putBuf(buf)
-
- return keys
-}
-
-type cacheKeys []cacheKey
-
-// drop will drop the cachedKey with lookup name from receiving cacheKeys slice.
-func (ck *cacheKeys) drop(name string) {
- _ = *ck // move out of loop
- for i := range *ck {
- if (*ck)[i].info.name == name {
- (*ck) = append((*ck)[:i], (*ck)[i+1:]...)
- break
- }
- }
-}
-
-// cacheKey represents an actual cached key.
-type cacheKey struct {
- // info is a reference to the structKey this
- // cacheKey is representing. This is a shared
- // reference and as such only the structKey.pkeys
- // lookup map is expecting to be modified.
- info *structKey
-
- // value is the actual string representing
- // this cache key for hashmap lookups.
- key string
-}
-
-// structKey represents a list of struct fields
-// encompassing a single cache key, the string name
-// of the lookup, the lookup map to primary cache
-// keys, and the key's possible zero value string.
-type structKey struct {
- // name is the provided cache lookup name for
- // this particular struct key, consisting of
- // period ('.') separated struct field names.
- name string
-
- // unique determines whether this structKey supports
- // multiple or just the singular unique result.
- unique bool
-
- // fields is a slice of runtime struct field
- // indices, of fields encompassed by this key.
- fields []structField
-
- // pkeys is a lookup of stored struct key values
- // to the primary cache lookup key (int64). this
- // is protected by the main cache mutex.
- pkeys map[string][]int64
-}
-
-// 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
-
- // Set the lookup name
- sk.name = lk.Name
-
- // Split dot-separated lookup to get
- // the individual struct field names
- names := strings.Split(lk.Name, ".")
-
- // Allocate the mangler and field indices slice.
- sk.fields = make([]structField, len(names))
-
- for i, name := range names {
- // Get field info for given name
- ft, ok := t.FieldByName(name)
- if !ok {
- panic("no field found for name: \"" + name + "\"")
- }
-
- // Check field is usable
- if !isExported(name) {
- panic("field must be exported")
- }
-
- // Set the runtime field index
- sk.fields[i].index = ft.Index[0]
-
- // Allocate new instance of field
- v := reflect.New(ft.Type)
- v = v.Elem()
-
- // Fetch mangler for field type.
- sk.fields[i].mangle = mangler.Get(ft.Type)
-
- if !lk.AllowZero {
- // Append the mangled zero value interface
- zero := sk.fields[i].mangle(nil, v.Interface())
- sk.fields[i].zero = string(zero)
- }
- }
-
- // Set unique lookup flag.
- sk.unique = !lk.Multi
-
- // Allocate primary lookup map
- sk.pkeys = make(map[string][]int64)
-
- 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 buffer
- buf := getBuf()
- 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)
-
- // Create str copy
- str := string(buf.B)
-
- // Release buf
- putBuf(buf)
-
- return str
-}
-
-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)
- return unicode.IsUpper(r)
-}
-
-// bufpool provides a memory pool of byte
-// buffers use when encoding key types.
-var bufPool = sync.Pool{
- New: func() any {
- return &byteutil.Buffer{B: make([]byte, 0, 512)}
- },
-}
-
-// getBuf acquires a byte buffer from memory pool.
-func getBuf() *byteutil.Buffer {
- return bufPool.Get().(*byteutil.Buffer)
-}
-
-// putBuf replaces a byte buffer back in memory pool.
-func putBuf(buf *byteutil.Buffer) {
- if buf.Cap() > int(^uint16(0)) {
- return // drop large bufs
- }
- bufPool.Put(buf)
-}