cache

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Apr 19, 2021 License: MIT Imports: 12 Imported by: 0

README

cache

A Golang package for data caching.

It provides several caching mechanisms, which follow these general rules:

  • Thread safety
  • Expiring values are removed by background routines
  • Updating values are updated by background routines

You can find in this package two kinds of cache mechanisms:

  • Concrete cache - Those cache implementations use various system resources to cache your concrete data (memory, storage, network, etc)
  • Behavioural cache - Those cache implementations wrap the concrete cache types and meant to implement advanced caching algorithms such as Least recenlty used or Least Frequently Used. Behavioural cache type are not independent, they can rely on each cache type that implements this package's interface.

Get it

To install, use go get, preferrably from a tagged release, for example v0.1.15

go get github.com/apidome/cache@v0.1.15

Concrete Cache

You can use the following concrete cache types:

  • Map Cache
  • Directory Cache
  • Redis Cache

Behavioural Cache

You can wrap your concrete cache with the following behavioural cache types:

  • LRU Cache (Least Recently Used)
  • LFU Cache (Least Frequently Used)

Usage

MapCache

A cache that stores your data in the process's memory.

import (
  "github.com/apidome/cache"
  "time"
 )

func main() {
    // MapCache is currently the only implemented cache backend
    mc := cache.NewMapCache()

    // Keys and values can be of any type
    var key, val interface{} = "key", "val"

    // Store a persistent value
    err := mc.Store(key, val)

    // Get a value
    v, err = mc.Get(key)

    // Remove a value
    err = mc.Remove(key)

    // Replace a value
    err = mc.Replace(key, val.(string)+"2")

    // Clear the cache (remove all values and stop all background routines)
    err = mc.Clear()

    // Gets all keys in the cache
    keys, err := mc.Keys()

    // Store an expiring value, it will be removed after a minute
    err = mc.StoreWithExpiration(key, val, time.Minute)

    // Replace a value with an expiring value, it will be removed a minute
    // after this call
    err = mc.ReplaceWithExpiration(key, val.(string)+"2", time.Minute)

    // Set an expiration duration for a value, it will be removed a minute
    // after this call
    err = mc.Expire(key, time.Minute)

    // Store a continuosly updating value, it will be updated every minute
    // using the provided update function
    err = mc.StoreWithUpdate(key, val, func(currValue interface{}) interface{} {
        return currVal.(string)+"."
    }, time.Minute)

    // Replace a value with a continously updating value, it will be updated every
    // minute using the provided update function
    err = mc.ReplaceWithUpdate(key, val, func(currValue interface{}) interface{} {
        return currVal.(string)+"."
    }, time.Minute)

DirectoryCache

A cache that store your data in a certain directory in the file system.

import (
  "github.com/apidome/cache"
  "time"
  "fmt"
 )

func main() {
    // An example, can be any directory
    cacheDir := fmt.Sprintf("%s/%s", os.TempDir(), "dir-cache")

    dc, err := cache.NewDirectoryCache(cacheDir, func(key string, err error) {
        fmt.Println("Something happened in a background routine")
    })

    // Values of DirectoryCache must be any of:
    // - Maps
    // - Slices
    // - Structs that can be fully marshalled to JSON
    type exampleValue struct {
        Str string `json:"str"`
    }

    // Keys of DirectoryCache must be strings
    var key string = "key"
    var val exampleStruct = exampleStruct{"example"}

    // Store a value
    err = dc.Store(key, val)

    // Get a value
    v, err = dc.Get(key)

    // Remove a value
    err = dc.Remove(key)

    // Replace a value
    err = dc.Replace(key, exampleStruct{"newExample"})

    // Clear the cache, it will not be usable once cleared
    err = dc.Clear()

    // Gets all keys in the cache
    keys, err = dc.Keys()

    // Store an expiring value, it will be removed after a minute
    err = dc.StoreWithExpiration(key, val, time.Minute)

    // Replace an expiring value
    err = dc.ReplaceWithExpiration(key, exampleStruct{"newExample"}, time.Minute)

    // Set an expiration time for a value
    err = dc.Expire(key, 2*time.Minute)

    // Store a continously updating value
    err = dc.StoreWithUpdate(key, val, func(currValue interface{}) interface{} {
        return exampleStruct{"newExample"}
    }, time.Minute)

    // Replace a value with a continously updating one
    err = dc.ReplaceWithUpdate(key, val, func(currValue interface{}) interface{} {
        return exampleStruct{"newExample"}
    }, time.Minute)
}

Redis Cache

A bridge between our cache interface and a Redis server.

import (
  "github.com/apidome/cache"
  "fmt"
)

func main() {
    // Initializing a RedisCache instance. The third argument is the
    // redis database number.
    redisCache := NewRedisCache("127.0.0.1", "password", 0)
}

LRU Cache

An implementation of Least Recently Used cache algorithm. Although behavioural cache types are not independent, LRU cache will work with MapCache by default.

import (
  "github.com/apidome/cache"
  "fmt"
 )

func main() {
    // An LRU cache requires a predefined capacity
    lru := NewLru(3)

    // Get the amount of stored items 
    numberOfItems := lru.Count()

    // Check if lru cache is full
    isFull := lru.IsFull()

    // Check if lru cache is empty
    isEmpty := lru.IsEmpty()

    // Get the most recently used key
    mostRecent := lru.GetMostRecentlyUsedKey()

    // Get the least recently used key
    leastRecent := lru.GetLeastRecentlyUsedKey()
}

LFU Cache

An implementation of Least Frequently Used cache algorithm.

import (
  "github.com/apidome/cache"
  "fmt"
 )

func main() {
    // An LFU cache requires a predefined capacity
    lfu := NewLfu(3)

    // Get the amount of stored items 
    numberOfItems := lfu.Count()

    // Check if lfu cache is full
    isFull := lfu.IsFull()

    // Check if lfu cache is empty
    isEmpty := lfu.IsEmpty()

    // Get the least frequqntly used key
    leastFrequent := lfu.GetLeastFrequentlyUsedKey()
}

Cache combination

It is possible to create a behavioural Cache that works with other type of cache, DirectoryCache for example.

func main() {
    // Initialize your own cache
    dc := NewDirectoryCache()

    // Create a new lru with a given instance
    lru := NewLruWithCustomCache(3, dc)
}

NOTE: When creating a behavioural cache with custom concrete cache, the given concrete cahce must be empty!

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsAlreadyExists added in v0.1.13

func IsAlreadyExists(err error) bool

func IsClearedCache added in v0.1.13

func IsClearedCache(err error) bool

func IsDoesNotExist added in v0.1.13

func IsDoesNotExist(err error) bool

func IsInvalidKeyType added in v0.1.13

func IsInvalidKeyType(err error) bool

func IsInvalidMessage added in v0.1.15

func IsInvalidMessage(err error) bool

func IsInvalidValueType added in v0.1.13

func IsInvalidValueType(err error) bool

func IsNilUpdateFunc added in v0.1.13

func IsNilUpdateFunc(err error) bool

func IsNilValue added in v0.1.13

func IsNilValue(err error) bool

func IsNonPositivePeriod added in v0.1.13

func IsNonPositivePeriod(err error) bool

func IsUnexpectedError added in v0.1.15

func IsUnexpectedError(err error) bool

func IsUnrecoverableValue added in v0.1.13

func IsUnrecoverableValue(err error) bool

func NewDirectoryCache added in v0.1.13

func NewDirectoryCache(dir string) (*directoryCache, error)

Create a new Cache object that is backed up by a directory.

If dir does not exist, it will be created.

func NewLfu added in v0.2.0

func NewLfu(capacity int) *lfuCache

NewLfu creates a new lfuCache instance using mapCache.

func NewLfuWithCustomCache added in v0.2.0

func NewLfuWithCustomCache(capacity int, cache Cache) (*lfuCache, error)

NewLfuWithCustomCache creates a new lfuCache with custom cache.

func NewLru added in v0.2.0

func NewLru(capacity int) *lruCache

NewLru creates a new lruCache instance using mapCache.

func NewLruWithCustomCache added in v0.2.0

func NewLruWithCustomCache(capacity int, cache Cache) (*lruCache, error)

NewLruWithCustomCache creates a new lruCache with custom cache.

func NewMapCache

func NewMapCache() *mapCache

NewMapCache creates a new Cache object that is backed by a map.

Types

type Cache

type Cache interface {
	// Store a value permanently.
	Store(key, val interface{}) error

	// Get a value.
	Get(key interface{}) (interface{}, error)

	// Remove a value.
	Remove(key interface{}) error

	// Replace a value.
	Replace(key, val interface{}) error

	// Clears the cache.
	Clear() error

	// Get all keys from the cache.
	Keys() ([]interface{}, error)
}

type ExpiringCache added in v0.1.13

type ExpiringCache interface {
	Cache

	// Store a value that will be removed after the specified ttl.
	StoreWithExpiration(key, val interface{}, ttl time.Duration) error

	// Replaces the value of a key.
	ReplaceWithExpiration(key, val interface{}, ttl time.Duration) error

	// Expire resets and updates the ttl of a value.
	Expire(key interface{}, ttl time.Duration) error
}

type RedisCache added in v0.2.0

type RedisCache struct {
	// contains filtered or unexported fields
}

RedisCache is a client that implements Cache interface.

func NewRedisCache added in v0.2.0

func NewRedisCache(address, password string, db int) *RedisCache

NewRedisCache creates and returns a reference to a RedisCache instance.

func (*RedisCache) Clear added in v0.2.0

func (r *RedisCache) Clear() error

Clear all values that maintained by this RedisCache instance.

func (*RedisCache) Expire added in v0.2.0

func (r *RedisCache) Expire(key interface{}, ttl time.Duration) error

Expire a key-value pair.

func (*RedisCache) Get added in v0.2.0

func (r *RedisCache) Get(key interface{}) (interface{}, error)

Get a value from redis.

func (*RedisCache) Keys added in v0.2.0

func (r *RedisCache) Keys() ([]interface{}, error)

Keys return all keys that maintained by this RedisCache instance.

func (*RedisCache) Remove added in v0.2.0

func (r *RedisCache) Remove(key interface{}) error

Remove a value from redis.

func (*RedisCache) Replace added in v0.2.0

func (r *RedisCache) Replace(key, val interface{}) error

Replace an existing value in redis.

func (*RedisCache) ReplaceWithExpiration added in v0.2.0

func (r *RedisCache) ReplaceWithExpiration(key, val interface{}, ttl time.Duration) error

ReplaceWithExpiration replaces a key-value pair in redis for limited time.

func (*RedisCache) Store added in v0.2.0

func (r *RedisCache) Store(key, val interface{}) error

Store permanent value in redis.

func (*RedisCache) StoreWithExpiration added in v0.2.0

func (r *RedisCache) StoreWithExpiration(key, val interface{}, ttl time.Duration) error

StoreWithExpiration stores a key-value pair in redis for limited time.

type UpdatingCache added in v0.1.13

type UpdatingCache interface {
	Cache

	// Stores a value and repeatedly updates it.
	StoreWithUpdate(key, initialValue interface{},
		updateFunc func(currValue interface{}) interface{},
		period time.Duration) error

	// Replaces a value and repeatedly updates it.
	ReplaceWithUpdate(key, initialValue interface{},
		updateFunc func(currValue interface{}) interface{},
		period time.Duration) error
}

type UpdatingExpiringCache added in v0.1.13

type UpdatingExpiringCache interface {
	UpdatingCache
	ExpiringCache
}

Jump to

Keyboard shortcuts

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