github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/utils/cache/cache.go (about) 1 package cache 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "os" 8 "time" 9 "unsafe" 10 11 "github.com/lmorg/murex/debug" 12 ) 13 14 func initCache(namespace string) { 15 if configCacheDisabled { 16 return 17 } 18 19 cache[namespace] = new(internalCacheT) 20 cache[namespace].cache = make(map[string]*cacheItemT) 21 disabled = false 22 createDb(namespace) 23 } 24 25 func read(namespace string, key string, ptr any) bool { 26 if ptr == nil { 27 return false 28 } 29 30 var b []byte 31 ok := cache[namespace].Read(key, unsafe.Pointer(&b)) 32 if !ok { 33 return false 34 } 35 36 if err := json.Unmarshal(b, ptr); err != nil { 37 if debug.Enabled { 38 os.Stderr.WriteString(fmt.Sprintf("Error unmarshalling cache in "+namespace, err)) 39 } 40 return false 41 } 42 43 return true 44 } 45 46 type dumpT struct { 47 Internal interface{} 48 CacheDb interface{} 49 } 50 51 func Dump(ctx context.Context) (interface{}, error) { 52 dump := make(map[string]dumpT) 53 54 for namespace := range cache { 55 internal := cache[namespace].Dump(ctx) 56 cacheDb, err := listDb(ctx, namespace) 57 dump[namespace] = dumpT{internal, cacheDb} 58 59 if err != nil { 60 return dump, err 61 } 62 } 63 64 return dump, nil 65 } 66 67 func write(namespace string, key string, value any, ttl time.Time) { 68 if value == nil { 69 return 70 } 71 72 b, err := json.Marshal(value) 73 if err != nil { 74 if debug.Enabled { 75 os.Stderr.WriteString(fmt.Sprintf("Error marshalling cache in "+namespace, err)) 76 } 77 return 78 } 79 80 cache[namespace].Write(key, &b, ttl) 81 } 82 83 func ListCaches() []string { 84 var ( 85 ret = make([]string, len(cache)) 86 i int 87 ) 88 89 for namespace := range cache { 90 ret[i] = namespace 91 i++ 92 } 93 94 return ret 95 } 96 97 type trimmedT struct { 98 Internal []string 99 CacheDb []string 100 } 101 102 func Trim(ctx context.Context) (interface{}, error) { 103 trimmed := make(map[string]trimmedT) 104 105 for namespace := range cache { 106 internal := cache[namespace].Trim(ctx) 107 cacheDb, err := trimDb(ctx, namespace) 108 trimmed[namespace] = trimmedT{internal, cacheDb} 109 110 if err != nil { 111 return trimmed, err 112 } 113 } 114 115 return trimmed, nil 116 } 117 118 func Flush(ctx context.Context) (interface{}, error) { 119 flushed := make(map[string]trimmedT) 120 121 for namespace := range cache { 122 internal := cache[namespace].Flush(ctx) 123 cacheDb, err := flushDb(ctx, namespace) 124 flushed[namespace] = trimmedT{internal, cacheDb} 125 126 if err != nil { 127 return flushed, err 128 } 129 } 130 131 return flushed, nil 132 }