ezcache

package module
v0.0.0-...-637513d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 17, 2021 License: MIT Imports: 7 Imported by: 0

README

Goals

  • Cache Loader support
  • Capacity
  • TTL
  • Write through
  • Cache Loader with current entry (-> Multiple implementations for the cache loader possible)
  • Bulk Loader
  • TBD: Sync vs Async load. What would it mean?
  • Refresh Ahead
  • Invalidation via stream?
  • Cache errors?
  • Metrics
  • Capacity
  • Security,Safety: There are no collisions, i.e. if you Set/Get a key, you will never get a different key's value back because (with low chance) some other key got the same hash. Not even with low odds - not at all. We consider this extremely important for multi-tenant systems, where even rare collisions can comprimise other user's data.
  • Sub-package for practical, ready to use modules that use the cache, i.e.: grpc caching middleware, etag based cache for http, ...
  • Eviction callbacks
  • Admission policy? (See TinyLFU paper)
  • Generic map mit equals + hashcode !
  • Generic singleflight
  • Equals() + HashCode() vs comparable + hashCode -> use equals ?!
  • Refactor shard.go to not use map, but use slice/array + linkedlist
  • Frequently used vs Recently; auto refresh top frequently used? frequently more realistic?
  • refresh only frequent, but not recent data?
  • bloomfilter
  • copy key?
  • More flexible expiry + evict + admission policy
  • Split expiration into specific type, to only use it if needed. Expiration manager?
  • CacheLoader: reload
  • Singleflight
  • Expiration optional

TBD/TODO

  • Cache errors, when would you want to have this?
  • LoaderFn where previous value is known
  • What about ctx?
  • Reduce number of hash func calls
  • Allow unlimited capacity?
  • Allow unlimited TTL
  • Try to not alloc for LinkedList/Heap - we could use the same pointer as for bucketItem, but add relevant methods for LL/Heap operations.
  • LinkedList should be pointer to bucketItem ? then deletes can avoid hashing key again.
  • Cached timer! every 1s/ms

Performance

go test -benchtime=10000000x -run='^$' -bench=BenchmarkSet -benchmem -memprofile memprofile.out -cpuprofile profile.out -count=5
goos: linux
goarch: amd64
pkg: github.com/birdayz/ezcache
cpu: AMD Ryzen 9 3900X 12-Core Processor
BenchmarkSetString/Set-24         	10000000	       691.6 ns/op	     276 B/op	       7 allocs/op
BenchmarkSetString/Set-24         	10000000	       684.9 ns/op	     276 B/op	       7 allocs/op
BenchmarkSetString/Set-24         	10000000	       701.2 ns/op	     276 B/op	       7 allocs/op
BenchmarkSetString/Set-24         	10000000	       711.4 ns/op	     276 B/op	       7 allocs/op
BenchmarkSetString/Set-24         	10000000	       701.0 ns/op	     276 B/op	       7 allocs/op
BenchmarkSetString/Get-24         	10000000	       259.6 ns/op	      23 B/op	       1 allocs/op
BenchmarkSetString/Get-24         	10000000	       253.7 ns/op	      23 B/op	       1 allocs/op
BenchmarkSetString/Get-24         	10000000	       260.4 ns/op	      23 B/op	       1 allocs/op
BenchmarkSetString/Get-24         	10000000	       251.7 ns/op	      23 B/op	       1 allocs/op
BenchmarkSetString/Get-24         	10000000	       257.0 ns/op	      23 B/op	       1 allocs/op
BenchmarkSetInt/Set-24            	10000000	       439.6 ns/op	     208 B/op	       6 allocs/op
BenchmarkSetInt/Set-24            	10000000	       441.9 ns/op	     208 B/op	       6 allocs/op
BenchmarkSetInt/Set-24            	10000000	       445.4 ns/op	     208 B/op	       6 allocs/op
BenchmarkSetInt/Set-24            	10000000	       431.5 ns/op	     208 B/op	       6 allocs/op
BenchmarkSetInt/Set-24            	10000000	       439.8 ns/op	     208 B/op	       6 allocs/op
BenchmarkSetInt/Get-24            	10000000	        82.50 ns/op	       7 B/op	       0 allocs/op
BenchmarkSetInt/Get-24            	10000000	        79.30 ns/op	       7 B/op	       0 allocs/op
BenchmarkSetInt/Get-24            	10000000	        79.43 ns/op	       8 B/op	       0 allocs/op
BenchmarkSetInt/Get-24            	10000000	        82.02 ns/op	       7 B/op	       0 allocs/op
BenchmarkSetInt/Get-24            	10000000	        82.85 ns/op	       7 B/op	       0 allocs/op
PASS
ok  	github.com/birdayz/ezcache	134.206s

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultHasher = func(key string) uint64 {
	h := fnv.New64a()
	h.Write([]byte(fmt.Sprintf("%v", key)))
	return h.Sum64()
}
View Source
var ErrNotFound = errors.New("not found")
View Source
var StringHasher = func(key string) uint64 {
	h := fnv.New64a()
	h.Write([]byte(key))
	return h.Sum64()

}

Functions

func AscendingComparator

func AscendingComparator[T constraints.Ordered](t1, t2 T) int

Types

type Cache

type Cache[K Key[K], V any] struct {
	// contains filtered or unexported fields
}

func New

func New[K Key[K], V any](cfg *CacheConfig[K, V]) *Cache[K, V]

func (*Cache[K, V]) Delete

func (c *Cache[K, V]) Delete(key K)

func (*Cache[K, V]) Get

func (c *Cache[K, V]) Get(key K) (V, error)

func (*Cache[K, V]) Set

func (c *Cache[K, V]) Set(key K, value V)

type CacheConfig

type CacheConfig[K Key[K], V any] struct {
	// contains filtered or unexported fields
}

func NewBuilder

func NewBuilder[K Key[K], V any]() *CacheConfig[K, V]

func (*CacheConfig[K, V]) Build

func (cb *CacheConfig[K, V]) Build() *Cache[K, V]

func (*CacheConfig[K, V]) Capacity

func (cb *CacheConfig[K, V]) Capacity(capacity int) *CacheConfig[K, V]

func (*CacheConfig[K, V]) Loader

func (cb *CacheConfig[K, V]) Loader(loader LoaderFn[K, V]) *CacheConfig[K, V]

func (*CacheConfig[K, V]) NumShards

func (cb *CacheConfig[K, V]) NumShards(numShards int) *CacheConfig[K, V]

func (*CacheConfig[K, V]) TTL

func (cb *CacheConfig[K, V]) TTL(ttl time.Duration) *CacheConfig[K, V]

type Comparator

type Comparator[T any] func(t1, t2 T) int

type Element

type Element[T any] struct {

	// The value stored with this element.
	Value T
	// contains filtered or unexported fields
}

Element is an element of a linked list.

func (*Element[T]) Next

func (e *Element[T]) Next() *Element[T]

Next returns the next list element or nil.

func (*Element[T]) Prev

func (e *Element[T]) Prev() *Element[T]

Prev returns the previous list element or nil.

type HashCoder

type HashCoder interface {
	HashCode() uint64
}

type HashMap

type HashMap[K Key[K], V any] struct {
	// contains filtered or unexported fields
}

func NewHashMap

func NewHashMap[K Key[K], V any](initialCapacity int) *HashMap[K, V]

func (*HashMap[K, V]) Delete

func (h *HashMap[K, V]) Delete(key K) (prev V, deleted bool)

func (*HashMap[K, V]) DeleteH

func (h *HashMap[K, V]) DeleteH(key K, hash uint64) (prev V, deleted bool)

func (*HashMap[K, V]) Get

func (h *HashMap[K, V]) Get(key K) (value V, found bool)

func (*HashMap[K, V]) GetH

func (h *HashMap[K, V]) GetH(key K, hash uint64) (value V, found bool)

func (*HashMap[K, V]) Set

func (h *HashMap[K, V]) Set(key K, value V) bool

func (*HashMap[K, V]) SetH

func (h *HashMap[K, V]) SetH(key K, value V, hash uint64) bool

type Heap

type Heap[T any] struct {
	// contains filtered or unexported fields
}

func NewHeap

func NewHeap[T any](comparator Comparator[T], initialCapacity int) *Heap[T]

func (*Heap[T]) Fix

func (t *Heap[T]) Fix(he *HeapElement[T])

func (*Heap[T]) Init

func (t *Heap[T]) Init()

func (*Heap[T]) Peek

func (t *Heap[T]) Peek() (item *HeapElement[T])

func (*Heap[T]) Pop

func (t *Heap[T]) Pop() (item *HeapElement[T])

func (*Heap[T]) Push

func (t *Heap[T]) Push(item T) *HeapElement[T]

func (*Heap[T]) Remove

func (t *Heap[T]) Remove(he *HeapElement[T])

type HeapElement

type HeapElement[T any] struct {
	Item T
	// contains filtered or unexported fields
}

type IntKey

type IntKey int

func (IntKey) Equals

func (ik IntKey) Equals(s IntKey) bool

func (IntKey) HashCode

func (ik IntKey) HashCode() uint64

type Key

type Key[K any] interface {
	Equals(K) bool
	HashCoder
}

type List

type List[T any] struct {
	// contains filtered or unexported fields
}

List represents a doubly linked list. The zero value for List is an empty list ready to use.

func NewList

func NewList[T any]() *List[T]

New returns an initialized list.

func (*List[T]) Back

func (l *List[T]) Back() *Element[T]

Back returns the last element of list l or nil if the list is empty.

func (*List[T]) Front

func (l *List[T]) Front() *Element[T]

Front returns the first element of list l or nil if the list is empty.

func (*List[T]) Init

func (l *List[T]) Init() *List[T]

Init initializes or clears list l.

func (*List[T]) InsertAfter

func (l *List[T]) InsertAfter(v T, mark *Element[T]) *Element[T]

InsertAfter inserts a new element e with value v immediately after mark and returns e. If mark is not an element of l, the list is not modified. The mark must not be nil.

func (*List[T]) InsertBefore

func (l *List[T]) InsertBefore(v T, mark *Element[T]) *Element[T]

InsertBefore inserts a new element e with value v immediately before mark and returns e. If mark is not an element of l, the list is not modified. The mark must not be nil.

func (*List[T]) Len

func (l *List[T]) Len() int

Len returns the number of elements of list l. The complexity is O(1).

func (*List[T]) MoveAfter

func (l *List[T]) MoveAfter(e, mark *Element[T])

MoveAfter moves element e to its new position after mark. If e or mark is not an element of l, or e == mark, the list is not modified. The element and mark must not be nil.

func (*List[T]) MoveBefore

func (l *List[T]) MoveBefore(e, mark *Element[T])

MoveBefore moves element e to its new position before mark. If e or mark is not an element of l, or e == mark, the list is not modified. The element and mark must not be nil.

func (*List[T]) MoveToBack

func (l *List[T]) MoveToBack(e *Element[T])

MoveToBack moves element e to the back of list l. If e is not an element of l, the list is not modified. The element must not be nil.

func (*List[T]) MoveToFront

func (l *List[T]) MoveToFront(e *Element[T])

MoveToFront moves element e to the front of list l. If e is not an element of l, the list is not modified. The element must not be nil.

func (*List[T]) PushBack

func (l *List[T]) PushBack(v T) *Element[T]

PushBack inserts a new element e with value v at the back of list l and returns e.

func (*List[T]) PushBackList

func (l *List[T]) PushBackList(other *List[T])

PushBackList inserts a copy of another list at the back of list l. The lists l and other may be the same. They must not be nil.

func (*List[T]) PushFront

func (l *List[T]) PushFront(v T) *Element[T]

PushFront inserts a new element e with value v at the front of list l and returns e.

func (*List[T]) PushFrontList

func (l *List[T]) PushFrontList(other *List[T])

PushFrontList inserts a copy of another list at the front of list l. The lists l and other may be the same. They must not be nil.

func (*List[T]) Remove

func (l *List[T]) Remove(e *Element[T]) T

Remove removes e from l if e is an element of list l. It returns the element value e.Value. The element must not be nil.

type LoaderFn

type LoaderFn[K Key[K], V any] func(key K) (value V, err error)

type StringKey

type StringKey string

func (StringKey) Equals

func (ks StringKey) Equals(s StringKey) bool

func (StringKey) HashCode

func (ks StringKey) HashCode() uint64

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL