cache

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Sep 3, 2022 License: MIT Imports: 4 Imported by: 8

README

expirable-cache

Build Status Coverage Status godoc

Package cache implements expirable cache.

  • Support LRC, LRU and TTL-based eviction.
  • Package is thread-safe and doesn't spawn any goroutines.
  • On every Set() call, cache deletes single oldest entry in case it's expired.
  • In case MaxSize is set, cache deletes the oldest entry disregarding its expiration date to maintain the size, either using LRC or LRU eviction.
  • In case of default TTL (10 years) and default MaxSize (0, unlimited) the cache will be truly unlimited and will never delete entries from itself automatically.

Important: only reliable way of not having expired entries stuck in a cache is to run cache.DeleteExpired periodically using time.Ticker, advisable period is 1/2 of TTL.

This cache is heavily inspired by hashicorp/golang-lru simplelru implementation.

Usage example
package main

import (
	"fmt"
	"time"

	"github.com/go-pkgz/expirable-cache/v2"
)

func main() {
	// make cache with short TTL and 3 max keys
	c := cache.NewCache[string, string]().WithMaxKeys(3).WithTTL(time.Millisecond * 10)

	// set value under key1.
	// with 0 ttl (last parameter) will use cache-wide setting instead (10ms).
	c.Set("key1", "val1", 0)

	// get value under key1
	r, ok := c.Get("key1")

	// check for OK value, because otherwise return would be nil and
	// type conversion will panic
	if ok {
		rstr := r.(string) // convert cached value from interface{} to real type
		fmt.Printf("value before expiration is found: %v, value: %v\n", ok, rstr)
	}

	time.Sleep(time.Millisecond * 11)

	// get value under key1 after key expiration
	r, ok = c.Get("key1")
	// don't convert to string as with ok == false value would be nil
	fmt.Printf("value after expiration is found: %v, value: %v\n", ok, r)

	// set value under key2, would evict old entry because it is already expired.
	// ttl (last parameter) overrides cache-wide ttl.
	c.Set("key2", "val2", time.Minute*5)

	fmt.Printf("%+v\n", c)
	// Output:
	// value before expiration is found: true, value: val1
	// value after expiration is found: false, value: <nil>
	// Size: 1, Stats: {Hits:1 Misses:1 Added:2 Evicted:1} (50.0%)
}

Documentation

Overview

Package cache implements Cache similar to hashicorp/golang-lru

Support LRC, LRU and TTL-based eviction. Package is thread-safe and doesn't spawn any goroutines. On every Set() call, cache deletes single oldest entry in case it's expired. In case MaxSize is set, cache deletes the oldest entry disregarding its expiration date to maintain the size, either using LRC or LRU eviction. In case of default TTL (10 years) and default MaxSize (0, unlimited) the cache will be truly unlimited and will never delete entries from itself automatically.

Important: only reliable way of not having expired entries stuck in a cache is to run cache.DeleteExpired periodically using time.Ticker, advisable period is 1/2 of TTL.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Cache added in v0.0.3

type Cache interface {
	fmt.Stringer
	Set(key string, value interface{}, ttl time.Duration)
	Get(key string) (interface{}, bool)
	Peek(key string) (interface{}, bool)
	Keys() []string
	Len() int
	Invalidate(key string)
	InvalidateFn(fn func(key string) bool)
	RemoveOldest()
	DeleteExpired()
	Purge()
	Stat() Stats
}

Cache defines cache interface

Example
// make cache with short TTL and 3 max keys
cache, _ := NewCache(MaxKeys(3), TTL(time.Millisecond*10))

// set value under key1.
// with 0 ttl (last parameter) will use cache-wide setting instead (10ms).
cache.Set("key1", "val1", 0)

// get value under key1
r, ok := cache.Get("key1")

// check for OK value, because otherwise return would be nil and
// type conversion will panic
if ok {
	rstr := r.(string) // convert cached value from interface{} to real type
	fmt.Printf("value before expiration is found: %v, value: %v\n", ok, rstr)
}

time.Sleep(time.Millisecond * 11)

// get value under key1 after key expiration
r, ok = cache.Get("key1")
// don't convert to string as with ok == false value would be nil
fmt.Printf("value after expiration is found: %v, value: %v\n", ok, r)

// set value under key2, would evict old entry because it is already expired.
// ttl (last parameter) overrides cache-wide ttl.
cache.Set("key2", "val2", time.Minute*5)

fmt.Printf("%+v\n", cache)
Output:

value before expiration is found: true, value: val1
value after expiration is found: false, value: <nil>
Size: 1, Stats: {Hits:1 Misses:1 Added:2 Evicted:1} (50.0%)

func NewCache added in v0.0.3

func NewCache(options ...Option) (Cache, error)

NewCache returns a new Cache. Default MaxKeys is unlimited (0). Default TTL is 10 years, sane value for expirable cache is 5 minutes. Default eviction mode is LRC, appropriate option allow to change it to LRU.

type Option

type Option func(lc *cacheImpl) error

Option func type

func LRU

func LRU() Option

LRU sets cache to LRU (Least Recently Used) eviction mode.

func MaxKeys

func MaxKeys(max int) Option

MaxKeys functional option defines how many keys to keep. By default it is 0, which means unlimited.

func OnEvicted

func OnEvicted(fn func(key string, value interface{})) Option

OnEvicted called automatically for automatically and manually deleted entries

func TTL

func TTL(ttl time.Duration) Option

TTL functional option defines TTL for all cache entries. By default it is set to 10 years, sane option for expirable cache might be 5 minutes.

type Stats

type Stats struct {
	Hits, Misses   int // cache effectiveness
	Added, Evicted int // number of added and evicted records
}

Stats provides statistics for cache

Jump to

Keyboard shortcuts

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