Categorygithub.com/apidome/cache
modulepackage
0.2.0
Repository: https://github.com/apidome/cache.git
Documentation: pkg.go.dev

# 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/[email protected]

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!

# Functions

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
Create a new Cache object that is backed up by a directory.
NewLfu creates a new lfuCache instance using mapCache.
NewLfuWithCustomCache creates a new lfuCache with custom cache.
NewLru creates a new lruCache instance using mapCache.
NewLruWithCustomCache creates a new lruCache with custom cache.
NewMapCache creates a new Cache object that is backed by a map.
NewRedisCache creates and returns a reference to a RedisCache instance.

# Structs

RedisCache is a client that implements Cache interface.

# Interfaces

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author