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  }