Skip to content

Latest commit

 

History

History
83 lines (57 loc) · 2.8 KB

readme.md

File metadata and controls

83 lines (57 loc) · 2.8 KB

go-memoize

There wasn't a decent memoizer for Golang out there, so I lashed two nice libraries together and made one.

Dead-simple. Safe for concurrent use.

Reference Linter Build status

Project status

Complete. Latest commit timestamp might be old - that's okay.

Go-memoize has been in production for a few years, and has yet to burn the house down.

Usage

Cache expensive function calls in memory, with a configurable timeout and purge interval:

import (
	"time"

	"github.com/kofalt/go-memoize"
)

// Any expensive call that you wish to cache
expensive := func() (any, error) {
	time.Sleep(3 * time.Second)
	return "some data", nil
}

// Cache expensive calls in memory for 90 seconds, purging old entries every 10 minutes.
cache := memoize.NewMemoizer(90*time.Second, 10*time.Minute)

// This will call the expensive func
result, err, cached := cache.Memoize("key1", expensive)

// This will be cached
result, err, cached = cache.Memoize("key1", expensive)

// This uses a new cache key, so expensive is called again
result, err, cached = cache.Memoize("key2", expensive)

In the example above, result is:

  1. the return value from your function if cached is false, or
  2. a previously stored value if cached is true.

All the hard stuff is punted to go-cache and sync/singleflight, I just lashed them together.
Note that cache.Storage is exported, so you can use underlying features such as Flush or SaveFile.

Type safety

The default usage stores and returns an any type.
If you wants to store & retrieve a specific type, use Call instead:

import (
	"time"

	"github.com/kofalt/go-memoize"
)

// Same example as above, but this func returns a string!
expensive := func() (string, error) {
	time.Sleep(3 * time.Second)
	return "some data", nil
}

// Same as before
cache := memoize.NewMemoizer(90*time.Second, 10*time.Minute)

// This will call the expensive func, and return a string.
result, err, cached := memoize.Call(cache, "key1", expensive)

// This will be cached
result, err, cached = memoize.Call(cache, "key1", expensive)

// This uses a new cache key, so expensive is called again
result, err, cached = memoize.Call(cache, "key2", expensive)