GitHub - floatdrop/lru: Thread safe GoLang LRU cache (original) (raw)

lru

Go Reference CI Coverage Go Report Card

Thread safe GoLang LRU cache.

Example

import ( "fmt"

"github.com/floatdrop/lru"

)

func main() { cache := lru.Newstring, int

cache.Set("Hello", 5)

if e := cache.Get("Hello"); e != nil {
    fmt.Println(*e)
    // Output: 5
}

}

TTL

You can wrap values into Expiring[T any] struct to release memory on timer (or manually in Valid method).

Example implementation

import ( "fmt" "time"

"github.com/floatdrop/lru"

)

type Expiring[T any] struct { value *T }

func (E *Expiring[T]) Valid() *T { if E == nil { return nil }

return E.value

}

func WithTTL[T any](value T, ttl time.Duration) Expiring[T] { e := Expiring[T]{ value: &value, }

time.AfterFunc(ttl, func() {
    e.value = nil // Release memory
})

return e

}

func main() { l := lru.Newstring, Expiring[string]

l.Set("Hello", WithTTL("Bye", time.Hour))

if e := l.Get("Hello").Valid(); e != nil {
    fmt.Println(*e)
}

}

Note: Althou this short implementation frees memory after ttl duration, it will not erase entry for key in cache. It can be a problem, if you do not check nillnes after getting element from cache and call Set afterwards.

Benchmarks

floatdrop/lru:
    BenchmarkLRU_Rand-8   	 8802915	       131.7 ns/op	      24 B/op	       1 allocs/op
    BenchmarkLRU_Freq-8   	 9392769	       127.8 ns/op	      24 B/op	       1 allocs/op

hashicorp/golang-lru:
    BenchmarkLRU_Rand-8   	 5992782	       195.8 ns/op	      76 B/op	       3 allocs/op
    BenchmarkLRU_Freq-8   	 6355358	       186.1 ns/op	      71 B/op	       3 allocs/op

jellydator/ttlcache:
    BenchmarkLRU_Rand-8   	 4447654	       253.5 ns/op	     144 B/op	       2 allocs/op
    BenchmarkLRU_Freq-8   	 4837938	       240.9 ns/op	     137 B/op	       2 allocs/op