A generic, fixed-capacity LRU cache for Go, built on a generic doubly linked list.
lru— a fixed-capacity cache with a least recently used eviction policy, safe for concurrent use.list— the generic doubly linked list the cache is built on, usable on its own.
Go 1.22 or newer.
go get github.com/mrLexx/go-cachepackage main
import (
"fmt"
"github.com/mrLexx/go-cache/lru"
)
func main() {
cache := lru.MustNew[string, int](128)
cache.Set("a", 1)
cache.Set("b", 2)
value, ok := cache.Get("a")
fmt.Println(value, ok) // 1 true
value, ok = cache.Get("missing")
fmt.Println(value, ok) // 0 false
}MustNew panics on an invalid capacity, which suits package-level variables and tests. Elsewhere, use New and handle the error:
cache, err := lru.New[string, int](128)
if err != nil {
return fmt.Errorf("create cache: %w", err)
}The capacity must be in the range [1, 1024]. Outside it, New returns an error wrapping ErrInvalidCapacity:
_, err := lru.New[string, int](0)
fmt.Println(errors.Is(err, lru.ErrInvalidCapacity)) // trueOnce the cache is full, storing a new key drops the least recently used entry. Both Get and Set count as a use, so reading a key protects it from the next eviction:
cache := lru.MustNew[string, int](2)
cache.Set("a", 1)
cache.Set("b", 2)
cache.Get("a") // "a" is now the most recently used
cache.Set("c", 3) // evicts "b", not "a"Storing a key that is already present overwrites its value and evicts nothing. Set reports whether the key was there before, and Clear empties the cache while keeping it usable with its original capacity.
list is a plain generic doubly linked list and does not depend on the cache:
l := list.New[string]()
l.PushBack("b")
l.PushBack("c")
first := l.PushFront("a") // a, b, c
l.MoveToFront(l.Back()) // c, a, b
l.Remove(first) // c, b
for item := l.Front(); item != nil; item = item.Next {
fmt.Println(item.Value)
}Unlike Cache, a List is not safe for concurrent use; guard it yourself if several goroutines touch it.
Full API documentation lives in the doc comments, most of it backed by runnable examples:
go doc github.com/mrLexx/go-cache/lru
go doc github.com/mrLexx/go-cache/listThe project uses Task to automate building, testing and linting. It replaces the classic Makefile.
Install task on your machine before you begin.
The full list of installation methods is available in the official documentation.
To list every available command with its description, run this in the project root:
task --listMain development commands:
task bench— Runs benchmarkstask coverage:check— Checks coverage without running teststask coverage:html— Generates an HTML coverage reporttask deps:update— Updates dependenciestask docs— Updates the command list in README.mdtask fix:apply— Applies automatic fixes (go fix)task fix:diff— Previews automatic fixes as a diff (go fix -diff)task format— Formats the code (gofumpt + gci)task formatters:install— Installs gofumpt and gcitask golangci-lint:install— Installs golangci-linttask install— Installs all toolstask lint— Runs golangci-linttask test— Runs unit tests with the race detectortask test:coverage— Runs tests with coveragetask test:example— Runs Example tests