In-memory Thread Safe Caching Library in Golang with support for multiple eviction policies, Batch Processing, and Persistence Storage
- Eviction Policies: Supports FIFO, LRU, LIFO and allows user to define and integrate custom eviction policies.
- Thread Safe: Utilizes
sync.RWMutex
for concurrent read/write access safely. - Batch Processing: Supports setting and getting multiple key-value pairs at once.
- Persistence Storage: Save cache contents to a file and load from a file.
- Complex Data Type Support: Can store any type of value, including integers, strings, arrays, maps, and structs.
- Statistics: Tracks cache hits, misses, and expired items.
kuki-memcache/
├── cache/
│ └── cache.go
├── benchmark/
│ └── benchmark.go
├── eviction/
│ ├── policy.go
│ ├── fifo.go
│ ├── lifo.go
│ └── lru.go
├── persistence/
│ ├── file_persistence.go
│ └── persistable.go
├── test/
│ └── cache_test.go
├── sample/
│ └── main.go
└── README.md
- Golang installed on your machine
-
Clone the repository:
git clone https://github.com/ashuthe1/kuki-memcache cd kuki-memcache
-
Install dependencies:
go mod tidy
Import the library into your Go project:
import (
"time"
"fmt"
"github.com/ashuthe1/kuki-memcache/cache"
"github.com/ashuthe1/kuki-memcache/eviction"
)
Initialize a cache instance with your desired TTL (time-to-live), maximum size, and eviction policy:
func main() {
// Example: Create a cache with 20 minutes TTL, size of 10 items, and LRU eviction policy
c := cache.NewCache(20*time.Minute, 10, eviction.NewLRU(), nil)
// Set a key-value pair in the cache with a specific TTL (e.g., 5 minutes)
c.Set("key", "value", 5*time.Minute)
// Get a value from the cache
val, isExists := c.Get("key")
if !isExists {
fmt.Println("Key not found")
return
}
fmt.Println(val)
}
To create your own custom eviction policy, implement the EvictionPolicy
interface:
type EvictionPolicy interface {
Add(key string)
Remove(key string)
Evict() string
}
Here is an example of how to implement and use a custom eviction policy:
package main
import (
"fmt"
"time"
"github.com/ashuthe1/kuki-memcache/cache"
"github.com/ashuthe1/kuki-memcache/eviction"
)
type CustomEviction struct {
// Define your custom data structure and fields here
}
func NewCustom() eviction.EvictionPolicy {
return &CustomEviction{
// Initialize your custom data structure here
}
}
func (c *CustomEviction) Add(key string) {
// Implement your custom eviction policy logic for Add operation
}
func (c *CustomEviction) Remove(key string) {
// Implement your custom eviction policy logic for Remove operation
}
func (c *CustomEviction) Evict() string {
// Implement your custom eviction policy logic for Evict operation
return "" // Adjust the return value as per your implementation
}
type Student struct {
Name string
age int
}
func main() {
// Example: Create a cache with 2 seconds TTL, size of 2 items, and custom eviction policy
c := cache.NewCache(2*time.Second, 2, NewCustom(), nil)
totalRegisteredUsers := 100
c.Set("totalRegisteredUsers", totalRegisteredUsers)
value, found := c.Get("totalRegisteredUsers")
if found {
fmt.Println(value)
}
student1 := Student{Name: "Ashutosh", age: 22}
arr := []int{1, 2, 3, 4, 5}
c.Set("studentId:1", student1)
c.Set("arr", arr)
// Get the value from the cache
value, found = c.Get("studentId:1")
if found {
student := value.(Student)
fmt.Printf("%+v\n", student)
}
value, found = c.Get("arr")
if found {
fetchedArr := value.([]int)
for _, v := range fetchedArr {
print(v, " ")
}
println()
}
}
You can add and retrieve multiple key-value pairs at once using the BatchSet
and BatchGet
methods.
package main
import (
"fmt"
"time"
"github.com/ashuthe1/kuki-memcache/cache"
"github.com/ashuthe1/kuki-memcache/eviction"
)
func main() {
c := cache.NewCache(20*time.Minute, 10, eviction.NewLRU(), nil)
// Batch set key-value pairs
items := map[string]interface{}{
"key1": "value1",
"key2": 123,
"key3": []int{1, 2, 3},
}
c.BatchSet(items)
// Batch get values
keys := []string{"key1", "key2", "key3"}
values := c.BatchGet(keys)
for k, v := range values {
fmt.Printf("%s: %v\n", k, v)
}
}
-
NewCache(): Create a new cache instance with TTL, maximum size, and an eviction policy.
- Parameters:
ttl
(time.Duration): The default time-to-live duration for each cache entry.maxSize
(int): The maximum number of items the cache can hold.evictionPolicy
(EvictionPolicy): The eviction policy to use (e.g., FIFO, LRU, LIFO, or a custom policy).logger
(optional): A logger instance for logging cache operations (can be nil).
- Return Value: A new cache instance.
- Parameters:
-
Set(): Add a key-value pair to the cache with an optional TTL.
- Parameters:
key
(string): The key for the cache entry.value
(interface{}): The value to be stored in the cache.ttl
(optional, time.Duration): Time-to-live duration for the cache entry. If not provided, the default TTL is used.
- Return Value: None.
- Parameters:
-
Get(): Retrieve a value associated with a key from the cache.
- Parameters:
key
(string): The key for the cache entry.
- Return Value: A tuple containing:
value
(interface{}): The value associated with the key, ornil
if not found.isExists
(bool): A boolean indicating whether the key was found in the cache.
- Parameters:
-
BatchSet(): Add multiple key-value pairs to the cache with optional TTLs for each item.
- Parameters:
items
(map[string]interface{}): The key-value pairs to be stored in the cache.ttl
(optional, time.Duration): Time-to-live duration for the cache entry. If not provided, the default TTL is used.
- Return Value: None.
- Parameters:
-
BatchGet(): Retrieve multiple key-value pairs from the cache.
- Parameters:
keys
([]string): The keys for the cache entries to be retrieved.
- Return Value: A map containing the key-value pairs that were found in the cache.
- Parameters:
-
Delete(): Remove a key-value pair from the cache.
- Parameters:
key
(string): The key for the cache entry.
- Return Value: None.
- Parameters:
-
Hits(): Track cache hits.
- Parameters: None.
- Return Value: An integer representing the number of cache hits.
-
Misses(): Track cache misses.
- Parameters: None.
- Return Value: An integer representing the number of cache misses.
-
Expired(): Track expired items.
- Parameters: None.
- Return Value: An integer representing the number of expired cache items.
Run tests to ensure functionality:
go test ./tests -v
Contributions are welcome! Feel free to submit issues and pull requests.