Documentation
¶
Index ¶
- Constants
- type Cache
- type LRU
- func (l *LRU[K, V]) Capacity() int
- func (l *LRU[K, V]) Compaction()
- func (l *LRU[K, V]) Contains(key K) bool
- func (l *LRU[K, V]) Flush()
- func (l *LRU[K, V]) Get(key K) (V, bool)
- func (l *LRU[K, V]) Peek(key K) (V, bool)
- func (l *LRU[K, V]) Put(key K, value V)
- func (l *LRU[K, V]) PutGrew(key K, value V) bool
- func (l *LRU[K, V]) Shards() int
- func (l *LRU[K, V]) Size() int
- type Option
Examples ¶
Constants ¶
const DefaultShards int = 128
DefaultShards represents the number of shards allocated to LRU if WithShards option is not configured.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Cache ¶
type Cache[K comparable, V any] interface { // Capacity returns the maximum allocated capacity of the LRU cache. Capacity() int // Compaction is an expensive O(N) operation to deal with memory fragmentation. Compaction() // Contains verifies if the key is present in the LRU Cache. // It does not update the key to recent status. Contains(key K) bool // Flush clears the LRU cache of all its keys and values. Flush() // Get retrieves the cache value using key. // It returns false if the key is not found. Get(key K) (V, bool) // Peek retrieves the cache value without updating it // to be the most recently used. // It returns false if the key is not found. Peek(key K) (V, bool) // Put adds a new value to the cache with the given key. Put(key K, value V) // PutGrew adds a new value to the cache with the given key. // It returns true if the size of the cache has grown, else returns false. PutGrew(key K, value V) bool // Size returns the current size of the LRU cache. Size() int }
Cache defines the general implementation of a 'Least Recently Used' cache. It has thread-safe operations.
As Items are Added to the Cache, The 'Least Recently Used' key is evicted from the Cache.
K represents the type of the key, whereas V represents the type of the Value in the cache
Example ¶
ExampleCache shows a small example of how to initialize a LRU instance and do basic operations like Put, Size, Contains and Capacity.
package main
import (
"fmt"
"github.com/justpranavrs/tlru"
)
// Member is the type of the value stored in the cache.
type Member struct {
Name string
Email string
}
func main() {
cache, err := tlru.New[int, Member](256) // create a lru instance
if err != nil {
fmt.Printf("[ERROR] could not initialize LRU instance: %v", err)
return
}
cache.Put(1, Member{ // insert in user data with user id 1
Name: "justpranavrs",
Email: "iliketlru@gmail.com",
})
fmt.Println(cache.Size()) // gets the current size of the cache
fmt.Println(cache.Contains(2))
fmt.Println(cache.Contains(1)) // reports whether key 1 is present in the cache
fmt.Println(cache.Capacity())
cache.Flush()
fmt.Println(cache.Size())
fmt.Println(cache.Capacity()) // capacity allocated for the cache
}
Output: 1 false true 256 0 256
type LRU ¶
type LRU[K comparable, V any] struct { // contains filtered or unexported fields }
LRU is the better implementation of lrucore.LRUCore. It is a 'Least Recently Used' cache with many instances of lrucore.LRUCore to prevent mutual extension locks on a single instance. It has thread-safe but not a completely lock free operations.
It doesn't work on the standard principle of LRU, rather when the mux routes it to a lrucore.LRUCore instance. LRU works on shard-local based eviction not on globally oldest item in the cache.
mux.Mux takes care of routing the shards to their containers consistently using its hashing algorithm. The default mux is mux.MuxX32.Get.
func New ¶
New creates a LRU instance with the given capacity and options. It creates the required lrucore.LRUCore instances, initiates the mux.Mux for shard routing. It defaults to the Mux with xxHash32 algorithm. Check `tlru/mux` package for alternatives.
Returns errs.ErrInvalidShards if shards is not greater than 0 and in [int32] range.
Returns errs.ErrInvalidCapacity if capacity is not in [int32] range and greater than number of shards.
func (*LRU[K, V]) Capacity ¶
Capacity returns the maximum allocated capacity of the LRU cache across all sharded instances of lrucore.LRUCore.
Example ¶
ExampleLRU_Capacity shows an example of how Capacity works.
package main
import (
"fmt"
"github.com/justpranavrs/tlru"
)
// Member is the type of the value stored in the cache.
type Member struct {
Name string
Email string
}
func main() {
cache, err := tlru.New[int, Member](256) // create a lru instance
if err != nil {
fmt.Printf("[ERROR] could not initialize LRU instance: %v", err)
return
}
fmt.Println(cache.Capacity())
}
Output: 256
func (*LRU[K, V]) Compaction ¶
func (l *LRU[K, V]) Compaction()
Compaction is an expensive O(N) operation to deal with memory fragmentation. It compacts all keys across the sharded architecture. For more details, refer lrucore.LRUCore.Compaction
func (*LRU[K, V]) Contains ¶
Contains verifies if the key is present in the LRU Cache by checking the correct sharded instance. It does not update the key to recent status.
Example ¶
ExampleLRU_Contains shows an example of how Contains works.
package main
import (
"fmt"
"github.com/justpranavrs/tlru"
)
// Member is the type of the value stored in the cache.
type Member struct {
Name string
Email string
}
func main() {
cache, err := tlru.New[int, Member](256) // create a lru instance
if err != nil {
fmt.Printf("[ERROR] could not initialize LRU instance: %v", err)
return
}
cache.Put(1, Member{ // insert in user data with user id 1
Name: "justpranavrs",
Email: "iliketlru@gmail.com",
})
fmt.Println(cache.Contains(1))
fmt.Println(cache.Contains(2))
}
Output: true false
func (*LRU[K, V]) Flush ¶
func (l *LRU[K, V]) Flush()
Flush clears the LRU cache of all its keys and values across all sharded instances.
func (*LRU[K, V]) Get ¶
Get retrieves the cache value using key. It returns false if the key is not found. It updates the key as 'recent' only in its respective shard.
Example ¶
ExampleLRU_Get shows an example of how Get works and how to handle when the key is not found in the cache.
package main
import (
"fmt"
"github.com/justpranavrs/tlru"
)
// Member is the type of the value stored in the cache.
type Member struct {
Name string
Email string
}
func main() {
cache, err := tlru.New[int, Member](256)
if err != nil {
fmt.Printf("[ERROR] could not initialize LRU instance: %v", err)
return
}
cache.Put(1, Member{
Name: "justpranavrs",
Email: "iliketlru@gmail.com",
})
val, ok := cache.Get(1)
if !ok {
fmt.Println("[GET] could not find the key in the cache.")
} else {
fmt.Printf("[GET] Name : %v | Email : %v\n", val.Name, val.Email)
}
val, ok = cache.Get(2)
if !ok {
fmt.Println("[GET] could not find the key in the cache.")
} else {
fmt.Printf("[GET] Name : %v | Email : %v\n", val.Name, val.Email)
}
}
Output: [GET] Name : justpranavrs | Email : iliketlru@gmail.com [GET] could not find the key in the cache.
func (*LRU[K, V]) Peek ¶ added in v0.3.0
Peek retrieves the cache value without updating it to be the most recently used. It returns false if the key is not found.
Example ¶
ExampleLRU_Peek shows an example of how Peek works. It doesn't disturb the internal state of the cache.
package main
import (
"fmt"
"github.com/justpranavrs/tlru"
)
// Member is the type of the value stored in the cache.
type Member struct {
Name string
Email string
}
func main() {
cache, err := tlru.New[int, Member](2, tlru.WithShards(1))
if err != nil {
fmt.Printf("[ERROR] could not initialize LRUCore instance: %v", err)
return
}
cache.Put(1, Member{
Name: "justpranavrs",
Email: "iliketlru@gmail.com",
})
cache.Put(3, Member{
Name: "welcometotlru",
Email: "welcometotlru@gmail.com",
})
val, ok := cache.Get(1)
if !ok {
fmt.Println("[GET] could not find the key in the cache.")
} else {
fmt.Printf("[GET] Name : %v | Email : %v\n", val.Name, val.Email)
}
val, ok = cache.Peek(3)
if !ok {
fmt.Println("[GET] could not find the key in the cache.")
} else {
fmt.Printf("[GET] Name : %v | Email : %v\n", val.Name, val.Email)
}
cache.Put(2, Member{
Name: "tlru",
Email: "tlruisthebest@gmail.com",
})
fmt.Println(cache.Contains(3))
}
Output: [GET] Name : justpranavrs | Email : iliketlru@gmail.com [GET] Name : welcometotlru | Email : welcometotlru@gmail.com false
func (*LRU[K, V]) Put ¶
func (l *LRU[K, V]) Put(key K, value V)
Put adds a new value to the cache with the given key. It updates the key as 'recent' only in its respective shard. It evicts the key only from the respective shard the key is linked to.
Example ¶
ExampleLRU_Put shows an example of how Put works and showcases the least recently used key getting evicted in a LRU cache.
package main
import (
"fmt"
"github.com/justpranavrs/tlru"
)
// Member is the type of the value stored in the cache.
type Member struct {
Name string
Email string
}
func main() {
cache, err := tlru.New[int, Member](256)
if err != nil {
fmt.Printf("[ERROR] could not initialize LRU instance: %v", err)
return
}
cache.Put(1, Member{
Name: "justpranavrs",
Email: "iliketlru@gmail.com",
})
fmt.Println(cache.Contains(2))
fmt.Println(cache.Contains(1))
cache.Put(2, Member{
Name: "welcometotlru",
Email: "welcometotlru@gmail.com",
})
fmt.Println(cache.Contains(2))
cache.Put(3, Member{
Name: "justpranavrs",
Email: "tlruiscool@gmail.com",
})
fmt.Println(cache.Contains(4))
fmt.Println(cache.Contains(3))
}
Output: false true true false true
func (*LRU[K, V]) PutGrew ¶ added in v0.3.0
PutGrew adds a new value to the cache with the given key. It returns true if the size of the cache has grown, else returns false. It evicts or updates locally on the shard, instead of global cache.
func (*LRU[K, V]) Shards ¶ added in v0.3.0
Shards returns the number of sharded instances in the LRU cache.
func (*LRU[K, V]) Size ¶
Size returns the current size of the LRU cache across all sharded instances.
Example ¶
ExampleLRU_Size shows an example on how Size works. It returns the current size of the LRU cache.
package main
import (
"fmt"
"github.com/justpranavrs/tlru"
)
// Member is the type of the value stored in the cache.
type Member struct {
Name string
Email string
}
func main() {
cache, err := tlru.New[int, Member](256)
if err != nil {
fmt.Printf("[ERROR] could not initialize LRU instance: %v", err)
return
}
fmt.Println(cache.Size())
cache.Put(1, Member{
Name: "justpranavrs",
Email: "iliketlru@gmail.com",
})
fmt.Println(cache.Size())
}
Output: 0 1
type Option ¶ added in v0.2.0
type Option func(c *config) error
Option is used to configure LRU when creating an instance using New constructor.
func WithMux ¶ added in v0.2.0
func WithMux[K comparable](cm mux.Mux[K]) Option
WithMux requires a custom mux.Mux type function. It is used with LRU to configure its mux, which is responsible for routing the shards.
func WithShards ¶
WithShards assigns the LRU instance with num shards. Shards are separate instances of lrucore.LRUCore to prevent mutex locks from slowing down the cache.
Returns errs.ErrInvalidShards if num is not in [int32] range or equals zero.