cache

package module
v1.5.1 Latest Latest
Warning

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

Go to latest
Published: Apr 15, 2024 License: MIT Imports: 11 Imported by: 55

README

go-generics-cache

.github/workflows/test.yml codecov Go Reference

go-generics-cache is an in-memory key:value store/cache that is suitable for applications running on a single machine. This in-memory cache uses Go Generics which is introduced in 1.18.

  • a thread-safe
  • implemented with Go Generics
  • TTL supported (with expiration times)
  • Simple cache is like map[string]interface{}
  • Cache replacement policies
    • Least recently used (LRU)
      • Discards the least recently used items first.
      • See examples
    • Least-frequently used (LFU)
    • First in first out (FIFO)
      • Using this algorithm the cache behaves in the same way as a FIFO queue.
      • The cache evicts the blocks in the order they were added, without any regard to how often or how many times they were accessed before.
      • See examples
    • Most recently used (MRU)
      • In contrast to Least Recently Used (LRU), MRU discards the most recently used items first.
      • See examples
    • Clock
      • Clock is a more efficient version of FIFO than Second-chance cache algorithm.
      • See examples

Requirements

Go 1.18 or later.

Install

$ go get github.com/Code-Hex/go-generics-cache

Usage

See also examples or go playground

package main

import (
	"context"
	"fmt"
	"time"

	cache "github.com/Code-Hex/go-generics-cache"
)

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// use simple cache algorithm without options.
	c := cache.NewContext[string, int](ctx)
	c.Set("a", 1)
	gota, aok := c.Get("a")
	gotb, bok := c.Get("b")
	fmt.Println(gota, aok) // 1 true
	fmt.Println(gotb, bok) // 0 false

	// Create a cache for Number constraint. key as string, value as int.
	nc := cache.NewNumber[string, int]()
	nc.Set("age", 26, cache.WithExpiration(time.Hour))

	incremented := nc.Increment("age", 1)
	fmt.Println(incremented) // 27

	decremented := nc.Decrement("age", 1)
	fmt.Println(decremented) // 26
}

Articles

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Cache

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

Cache is a thread safe cache.

Example
package main

import (
	"fmt"

	cache "github.com/Code-Hex/go-generics-cache"
)

func main() {
	// use simple cache algorithm without options.
	c := cache.New[string, int]()
	c.Set("a", 1)
	gota, aok := c.Get("a")
	gotb, bok := c.Get("b")
	fmt.Println(gota, aok)
	fmt.Println(gotb, bok)
}
Output:

1 true
0 false

func New

func New[K comparable, V any](opts ...Option[K, V]) *Cache[K, V]

New creates a new thread safe Cache. The janitor will not be stopped which is created by this function. If you want to stop the janitor gracefully, You should use the `NewContext` function instead of this.

There are several Cache replacement policies available with you specified any options.

func NewContext added in v1.1.0

func NewContext[K comparable, V any](ctx context.Context, opts ...Option[K, V]) *Cache[K, V]

NewContext creates a new thread safe Cache with context. This function will be stopped an internal janitor when the context is cancelled.

There are several Cache replacement policies available with you specified any options.

Example
package main

import (
	"context"
	"fmt"
	"time"

	cache "github.com/Code-Hex/go-generics-cache"
)

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// use simple cache algorithm without options.
	// an internal janitor will be stopped if specified the context is cancelled.
	c := cache.NewContext(ctx, cache.WithJanitorInterval[string, int](3*time.Second))
	c.Set("a", 1)
	gota, aok := c.Get("a")
	gotb, bok := c.Get("b")
	fmt.Println(gota, aok)
	fmt.Println(gotb, bok)
}
Output:

1 true
0 false

func (*Cache[K, V]) Contains

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

Contains reports whether key is within cache.

Example
package main

import (
	"fmt"

	cache "github.com/Code-Hex/go-generics-cache"
)

func main() {
	c := cache.New(cache.AsLRU[string, int]())
	c.Set("a", 1)
	fmt.Println(c.Contains("a"))
	fmt.Println(c.Contains("b"))
}
Output:

true
false

func (*Cache[K, V]) Delete

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

Delete deletes the item with provided key from the cache.

Example
package main

import (
	"fmt"

	cache "github.com/Code-Hex/go-generics-cache"
)

func main() {
	c := cache.New(cache.AsMRU[string, int]())
	c.Set("a", 1)
	c.Delete("a")
	gota, aok := c.Get("a")
	fmt.Println(gota, aok)
}
Output:

0 false

func (*Cache[K, V]) DeleteExpired added in v1.1.0

func (c *Cache[K, V]) DeleteExpired()

DeleteExpired all expired items from the cache.

func (*Cache[K, V]) Get

func (c *Cache[K, V]) Get(key K) (zero V, ok bool)

Get looks up a key's value from the cache.

func (*Cache[K, V]) GetOrSet added in v1.5.0

func (c *Cache[K, V]) GetOrSet(key K, val V, opts ...ItemOption) (actual V, loaded bool)

GetOrSet atomically gets a key's value from the cache, or if the key is not present, sets the given value. The loaded result is true if the value was loaded, false if stored.

Example
package main

import (
	"fmt"

	cache "github.com/Code-Hex/go-generics-cache"
	"github.com/Code-Hex/go-generics-cache/policy/lru"
)

func main() {
	c := cache.New(cache.AsLRU[string, int](lru.WithCapacity(10)))
	c.Set("a", 1)

	val1, ok1 := c.GetOrSet("b", 2)
	fmt.Println(val1, ok1)
	val2, ok2 := c.GetOrSet("a", 3)
	fmt.Println(val2, ok2)
}
Output:

2 false
1 true

func (*Cache[K, V]) Keys

func (c *Cache[K, V]) Keys() []K

Keys returns the keys of the cache. the order is relied on algorithms.

Example
package main

import (
	"fmt"

	cache "github.com/Code-Hex/go-generics-cache"
)

func main() {
	c := cache.New(cache.AsLFU[string, int]())
	c.Set("a", 1)
	c.Set("b", 1)
	c.Set("c", 1)
	fmt.Println(c.Keys())
}
Output:

[a b c]

func (*Cache[K, V]) Len added in v1.4.0

func (c *Cache[K, V]) Len() int

Len returns the number of items in the cache.

Example
package main

import (
	"fmt"

	cache "github.com/Code-Hex/go-generics-cache"
)

func main() {
	c := cache.New(cache.AsLFU[string, int]())
	c.Set("a", 1)
	c.Set("b", 1)
	c.Set("c", 1)
	fmt.Println(c.Len())
}
Output:

3

func (*Cache[K, V]) Set

func (c *Cache[K, V]) Set(key K, val V, opts ...ItemOption)

Set sets a value to the cache with key. replacing any existing value.

type Interface

type Interface[K comparable, V any] interface {
	// Get looks up a key's value from the cache.
	Get(key K) (value V, ok bool)
	// Set sets a value to the cache with key. replacing any existing value.
	Set(key K, val V)
	// Keys returns the keys of the cache. The order is relied on algorithms.
	Keys() []K
	// Delete deletes the item with provided key from the cache.
	Delete(key K)
	// Len returns the number of items in the cache.
	Len() int
}

Interface is a common-cache interface.

type Item

type Item[K comparable, V any] struct {
	Key                   K
	Value                 V
	Expiration            time.Time
	InitialReferenceCount int
}

Item is an item

func (*Item[K, V]) Expired added in v1.1.0

func (item *Item[K, V]) Expired() bool

Expired returns true if the item has expired.

func (*Item[K, V]) GetReferenceCount added in v1.3.0

func (item *Item[K, V]) GetReferenceCount() int

GetReferenceCount returns reference count to be used when setting the cache item for the first time.

type ItemOption

type ItemOption func(*itemOptions)

ItemOption is an option for cache item.

func WithExpiration

func WithExpiration(exp time.Duration) ItemOption

WithExpiration is an option to set expiration time for any items. If the expiration is zero or negative value, it treats as w/o expiration.

Example
package main

import (
	"fmt"
	"time"

	cache "github.com/Code-Hex/go-generics-cache"
)

func main() {
	c := cache.New(cache.AsFIFO[string, int]())
	exp := 250 * time.Millisecond
	c.Set("a", 1, cache.WithExpiration(exp))

	// check item is set.
	gota, aok := c.Get("a")
	fmt.Println(gota, aok)

	// set again
	c.Set("a", 2, cache.WithExpiration(exp))
	gota2, aok2 := c.Get("a")
	fmt.Println(gota2, aok2)

	// waiting expiration.
	time.Sleep(exp + 100*time.Millisecond) // + buffer

	gota3, aok3 := c.Get("a") // expired
	fmt.Println(gota3, aok3)
}
Output:

1 true
2 true
0 false

func WithReferenceCount added in v1.3.0

func WithReferenceCount(referenceCount int) ItemOption

WithReferenceCount is an option to set reference count for any items. This option is only applicable to cache policies that have a reference count (e.g., Clock, LFU). referenceCount specifies the reference count value to set for the cache item.

the default is 1.

Example
package main

import (
	"fmt"

	cache "github.com/Code-Hex/go-generics-cache"
	"github.com/Code-Hex/go-generics-cache/policy/lfu"
)

func main() {
	c := cache.New(cache.AsLFU[string, int](lfu.WithCapacity(2)))

	// set item with reference count
	c.Set("a", 1, cache.WithReferenceCount(5))

	// check item is set.
	gota, aok := c.Get("a")
	fmt.Println(gota, aok)

	c.Set("b", 2)
	c.Set("c", 3)

	// evicted becauce the lowest reference count.
	gotb, bok := c.Get("b")
	fmt.Println(gotb, bok)

	gotc, cok := c.Get("c")
	fmt.Println(gotc, cok)

}
Output:

1 true
0 false
3 true

type Number

type Number interface {
	constraints.Integer | constraints.Float | constraints.Complex
}

Number is a constraint that permits any numeric types.

type NumberCache

type NumberCache[K comparable, V Number] struct {
	*Cache[K, V]
	// contains filtered or unexported fields
}

NumberCache is a in-memory cache which is able to store only Number constraint.

func NewNumber

func NewNumber[K comparable, V Number](opts ...Option[K, V]) *NumberCache[K, V]

NewNumber creates a new cache for Number constraint.

Example
package main

import (
	"fmt"
	"time"

	cache "github.com/Code-Hex/go-generics-cache"
)

func main() {
	nc := cache.NewNumber[string, int]()
	nc.Set("a", 1)
	nc.Set("b", 2, cache.WithExpiration(time.Minute))
	av := nc.Increment("a", 1)
	gota, aok := nc.Get("a")

	bv := nc.Decrement("b", 1)
	gotb, bok := nc.Get("b")

	// not set keys
	cv := nc.Increment("c", 100)
	dv := nc.Decrement("d", 100)
	fmt.Println(av, gota, aok)
	fmt.Println(bv, gotb, bok)
	fmt.Println(cv)
	fmt.Println(dv)
}
Output:

2 2 true
1 1 true
100
-100

func (*NumberCache[K, V]) Decrement

func (nc *NumberCache[K, V]) Decrement(key K, n V) V

Decrement an item of type Number constraint by n. Returns the decremented value.

func (*NumberCache[K, V]) Increment

func (nc *NumberCache[K, V]) Increment(key K, n V) V

Increment an item of type Number constraint by n. Returns the incremented value.

type Option

type Option[K comparable, V any] func(*options[K, V])

Option is an option for cache.

func AsClock

func AsClock[K comparable, V any](opts ...clock.Option) Option[K, V]

AsClock is an option to make a new Cache as clock algorithm.

Example
package main

import (
	"fmt"

	cache "github.com/Code-Hex/go-generics-cache"
)

func main() {
	// use clock cache algorithm.
	c := cache.New(cache.AsClock[string, int]())
	c.Set("a", 1)
	gota, aok := c.Get("a")
	gotb, bok := c.Get("b")
	fmt.Println(gota, aok)
	fmt.Println(gotb, bok)
}
Output:

1 true
0 false

func AsFIFO

func AsFIFO[K comparable, V any](opts ...fifo.Option) Option[K, V]

AsFIFO is an option to make a new Cache as FIFO algorithm.

func AsLFU

func AsLFU[K comparable, V any](opts ...lfu.Option) Option[K, V]

AsLFU is an option to make a new Cache as LFU algorithm.

func AsLRU

func AsLRU[K comparable, V any](opts ...lru.Option) Option[K, V]

AsLRU is an option to make a new Cache as LRU algorithm.

func AsMRU

func AsMRU[K comparable, V any](opts ...mru.Option) Option[K, V]

AsMRU is an option to make a new Cache as MRU algorithm.

func WithJanitorInterval added in v1.1.0

func WithJanitorInterval[K comparable, V any](d time.Duration) Option[K, V]

WithJanitorInterval is an option to specify how often cache should delete expired items.

Default is 1 minute.

Directories

Path Synopsis
policy
lfu
lru
mru

Jump to

Keyboard shortcuts

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