# README
LFU
This is a Least Frequently Used cache backed by a generic doubly linked list with O(1) time complexity.
When to use
You would typically use an LFU cache when:
- Capacity of cache is far lower than data available.
- Entries being used are high frequency compared to others over time.
Both above will prevent the most frequently use data from flapping in and out of the cache.
Usage
No Locking
package main
import (
"fmt"
"github.com/go-playground/cache/lfu"
"time"
)
func main() {
// No guarding
cache := lfu.New[string, string](100).MaxAge(time.Hour).Build()
cache.Set("a", "b")
cache.Set("c", "d")
option := cache.Get("a")
if option.IsNone() {
return
}
fmt.Println("result:", option.Unwrap())
stats := cache.Stats()
// do things with stats
fmt.Printf("%#v\n", stats)
}
Auto Locking
package main
import (
"context"
"fmt"
"github.com/go-playground/cache/lfu"
"time"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// ThreadSafe cache with one operation per interaction semantics.
cache := lfu.New[string, string](100).MaxAge(time.Hour).BuildThreadSafe()
// example of collecting/emitting stats for cache
go func(ctx context.Context) {
var ticker = time.NewTicker(time.Minute)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
stats := cache.Stats()
// do things with stats
fmt.Printf("%#v\n", stats)
}
}
}(ctx)
cache.Set("a", "b")
cache.Set("c", "d")
option := cache.Get("a")
if option.IsNone() {
return
}
fmt.Println("result:", option.Unwrap())
// Have the ability to perform multiple operations at once by grabbing the LockGuard.
guard := cache.LockGuard()
guard.T.Set("c", "c")
guard.T.Set("d", "d")
guard.T.Remove("a")
guard.Unlock()
}
Custom Locking
package main
import (
"context"
"fmt"
"github.com/go-playground/cache/lfu"
syncext "github.com/go-playground/pkg/v5/sync"
"time"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// wrapping with a Mutex, if not needed omit.
cache := syncext.NewMutex2(lfu.New[string, string](100).MaxAge(time.Hour).Build())
// example of collecting/emitting stats for cache
go func(ctx context.Context) {
var ticker = time.NewTicker(time.Minute)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
guard := cache.Lock()
stats := guard.T.Stats()
guard.Unlock()
// do things with stats
fmt.Printf("%#v\n", stats)
}
}
}(ctx)
guard := cache.Lock()
guard.T.Set("a", "b")
guard.T.Set("c", "d")
option := guard.T.Get("a")
guard.Unlock()
if option.IsNone() {
return
}
fmt.Println("result:", option.Unwrap())
}
# Functions
New initializes a builder to create an LFU cache.
# Structs
Cache is a configured least frequently used cache ready for use.
Stats represents the cache statistics.
ThreadSafeCache is a drop in replacement for Cache which automatically handles locking all cache interactions.