### Benchmark Cache Get Operations Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/advanced-topics.md Use Go's testing package to benchmark the performance of the Get operation. This example shows how to benchmark retrieving items from the cache. ```go import "testing" func BenchmarkGet(b *testing.B) { c := cache.New(time.Hour, 10*time.Minute) c.Set("key", "value", cache.NoExpiration) b.ResetTimer() for i := 0; i < b.N; i++ { c.Get("key") } } // Run: go test -bench=. -benchmem ``` -------------------------------- ### Persistent Cache Setup (Save/Load) Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/configuration.md Configure a cache for persistence by registering types with gob, creating the cache, saving its items to a file, and later restoring them. ```go import "encoding/gob" // Register all types that will be cached gob.Register(MyStruct{}) gob.Register([]MyStruct{})) // Create cache c := cache.New(time.Hour, 10*time.Minute) // Later: save to file items := c.Items() f, _ := os.Create("cache.dat") enc := gob.NewEncoder(f) enc.Encode(items) f.Close() // Later: restore f, _ := os.Open("cache.dat") var items map[string]cache.Item dec := gob.NewDecoder(f) dec.Decode(&items) f.Close() c = cache.NewFrom(time.Hour, 10*time.Minute, items) ``` -------------------------------- ### Example Eviction Callback Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/configuration.md Demonstrates setting up and triggering an eviction callback. The callback is invoked for items deleted via Delete() or DeleteExpired(), but not when overwritten. ```go c := cache.New(5*time.Minute, 10*time.Minute) c.OnEvicted(func(key string, value interface{}) { log.Printf("Evicted: %s = %v", key, value) }) // Callback is called when items expire and are deleted c.Set("session", "token123", time.Minute) time.Sleep(2 * time.Minute) c.DeleteExpired() // Triggers callback // Disable callback c.OnEvicted(nil) ``` -------------------------------- ### Item Object Field Examples Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/Item-type-reference.md Demonstrates how to initialize an `Item` with various data types for the `Object` field, including primitives, pointers, collections, and custom types. ```go // Primitives item := cache.Item{Object: "string_value", Expiration: 0} item := cache.Item{Object: 42, Expiration: 0} item := cache.Item{Object: 3.14, Expiration: 0} item := cache.Item{Object: true, Expiration: 0} ``` ```go // Pointers (recommended for large types) item := cache.Item{Object: &MyStruct{}, Expiration: 0} ``` ```go // Collections item := cache.Item{Object: []string{"a", "b"}, Expiration: 0} item := cache.Item{Object: map[string]int{"x": 1}, Expiration: 0} ``` ```go // Custom types type User struct { ID int Name string } item := cache.Item{Object: &User{ID: 1, Name: "Alice"}, Expiration: 0} ``` -------------------------------- ### Set Item with No Expiration Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/types.md Example of creating a cache and setting an item with `cache.NoExpiration`, ensuring it persists indefinitely. ```go c := cache.New(5*time.Minute, 10*time.Minute) c.Set("permanent_key", "never_expires", cache.NoExpiration) ``` -------------------------------- ### Benchmark Cache Set Operations Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/advanced-topics.md Use Go's testing package to benchmark the performance of the Set operation. This example demonstrates how to set up a benchmark function for adding items to the cache. ```go import "testing" func BenchmarkSet(b *testing.B) { c := cache.New(time.Hour, 10*time.Minute) b.ResetTimer() for i := 0; i < b.N; i++ { c.Set(fmt.Sprintf("key_%d", i), i, cache.NoExpiration) } } ``` -------------------------------- ### Example Usage of Item and Expired Method Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/types.md Demonstrates how to create `Item` instances, set expiration times using `time.Now().Add().UnixNano()`, and check for expiration using the `Expired()` method. It also shows how to handle items that are set to never expire. ```go import ( "github.com/patrickmn/go-cache" "time" ) item := cache.Item{ Object: "data", Expiration: time.Now().Add(-time.Hour).UnixNano(), // Expired 1 hour ago } if item.Expired() { fmt.Println("Item has expired") } noExpireItem := cache.Item{ Object: "permanent", Expiration: 0, } if !noExpireItem.Expired() { fmt.Println("Item will never expire") } ``` -------------------------------- ### Inspect Cache State Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/advanced-topics.md Use ItemCount() to get the number of items, Items() to get a snapshot of non-expired items, and GetWithExpiration() to check a specific item's value, expiration time, and existence. ```go // Get item count count := c.ItemCount() fmt.Printf("Items in cache: %d\n", count) // Get snapshot of non-expired items items := c.Items() for k, item := range items { expTime := time.Unix(0, item.Expiration) fmt.Printf("%s: expires at %v\n", k, expTime) } // Check specific item if val, exp, found := c.GetWithExpiration("key"); found { timeLeft := time.Until(exp) fmt.Printf("Item: %v, expires in: %v\n", val, timeLeft) } else { fmt.Println("Item not found or expired") } ``` -------------------------------- ### Example Usage of Item.Expired() Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/Item-type-reference.md Demonstrates how to use the `Expired` method with items that never expire, have expired, or will expire in the future. This helps in understanding the method's behavior. ```go now := time.Now() // Non-expiring item item1 := cache.Item{ Object: "data", Expiration: 0, } fmt.Println(item1.Expired()) // false // Item expired 1 hour ago item2 := cache.Item{ Object: "old", Expiration: now.Add(-time.Hour).UnixNano(), } fmt.Println(item2.Expired()) // true // Item expires in 1 hour item3 := cache.Item{ Object: "fresh", Expiration: now.Add(time.Hour).UnixNano(), } fmt.Println(item3.Expired()) // false ``` -------------------------------- ### Item Expiration Field Examples Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/Item-type-reference.md Illustrates how to set the `Expiration` field for an `Item` to control its lifetime, including never expiring, expiring at a specific time, or expiring after a duration. ```go // Item never expires item := cache.Item{ Object: "permanent", Expiration: 0, } ``` ```go // Item expires in 1 hour from now item := cache.Item{ Object: "temp", Expiration: time.Now().Add(time.Hour).UnixNano(), } ``` ```go // Item expires in 30 seconds from now item := cache.Item{ Object: "session", Expiration: time.Now().Add(30 * time.Second).UnixNano(), } ``` -------------------------------- ### Batch Cache Lookups Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/advanced-topics.md For multiple cache lookups, use the Items() method to acquire a single lock and retrieve all items at once, which is faster than individual Get() calls. ```go // Slow: Multiple lock acquisitions v1, _ := c.Get("key1") v2, _ := c.Get("key2") // Faster: Single lock acquisition for all items items := c.Items() v1 := items["key1"].Object v2 := items["key2"].Object ``` -------------------------------- ### Filter Active Items from Cache Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/Item-type-reference.md This example shows how to iterate through all items in a cache and filter out the expired ones using the `Expired` method, creating a slice of only active items. ```go items := c.Items() var activeItems []cache.Item for _, item := range items { if !item.Expired() { activeItems = append(activeItems, item) } } ``` -------------------------------- ### Handle Increment Item Not Found Error Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/errors.md Illustrates handling the 'Item not found' error for increment operations. This occurs when the key does not exist or has expired. The example shows initializing the key with a zero value before incrementing. ```go c := cache.New(5*time.Minute, 10*time.Minute) err := c.Increment("counter", 1) if err != nil { fmt.Println(err) // Output: "Item counter not found" } // Solution: Initialize first c.Set("counter", int64(0), cache.NoExpiration) c.Increment("counter", 1) // Now succeeds ``` ```go err := c.Increment("key", 1) if err != nil && strings.Contains(err.Error(), "not found") { // Initialize with zero value c.Set("key", 0, cache.NoExpiration) c.Increment("key", 1) } ``` -------------------------------- ### Thread-Safe Cache Operations in Go Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/README.md Demonstrates concurrent usage of Set, Get, and Delete methods on a cache instance. These operations are safe to call from multiple goroutines without external locking. ```go // Safe: Multiple goroutines go func() { c.Set("key", "value", duration) }() go func() { c.Get("key") }() go func() { c.Delete("key") }() ``` -------------------------------- ### Create and Use a New Cache Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/api-cache.md Demonstrates creating a cache with default expiration and cleanup intervals, setting items with different expiration policies, and retrieving an item. ```go package main import ( "fmt" "github.com/patrickmn/go-cache" "time" ) func main() { // Create a cache with 5-minute default expiration and 10-minute cleanup c := cache.New(5*time.Minute, 10*time.Minute) c.Set("key1", "value1", cache.DefaultExpiration) c.Set("key2", "value2", cache.NoExpiration) if val, found := c.Get("key1"); found { fmt.Println(val) } } ``` -------------------------------- ### Initialize and Use go-cache Source: https://github.com/patrickmn/go-cache/blob/master/README.md Demonstrates creating a cache with default and no expiration, setting and retrieving values, and handling type assertions for retrieved interface{} values. Use type assertions carefully when retrieving values. ```go import ( "fmt" "github.com/patrickmn/go-cache" "time" ) func main() { // Create a cache with a default expiration time of 5 minutes, and which // purges expired items every 10 minutes c := cache.New(5*time.Minute, 10*time.Minute) // Set the value of the key "foo" to "bar", with the default expiration time c.Set("foo", "bar", cache.DefaultExpiration) // Set the value of the key "baz" to 42, with no expiration time // (the item won't be removed until it is re-set, or removed using // c.Delete("baz") c.Set("baz", 42, cache.NoExpiration) // Get the string associated with the key "foo" from the cache foo, found := c.Get("foo") if found { fmt.Println(foo) } // Since Go is statically typed, and cache values can be anything, type // assertion is needed when values are being passed to functions that don't // take arbitrary types, (i.e. interface{}). The simplest way to do this for // values which will only be used once--e.g. for passing to another // function--is: foo, found := c.Get("foo") if found { MyFunction(foo.(string)) } // This gets tedious if the value is used several times in the same function. // You might do either of the following instead: if x, found := c.Get("foo"); found { foo := x.(string) // ... } // or var foo string if x, found := c.Get("foo"); found { foo = x.(string) } // ... // foo can then be passed around freely as a string // Want performance? Store pointers! c.Set("foo", &MyStruct, cache.DefaultExpiration) if x, found := c.Get("foo"); found { foo := x.(*MyStruct) // ... } } ``` -------------------------------- ### Cache Item Management Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/MANIFEST.txt Methods for setting, getting, deleting, and managing items within the cache. ```APIDOC ## Set() ### Description Adds an item to the cache, replacing it if it already exists. An item is added to the cache with a `defaultExpiration`. ### Signature `func (c *Cache) Set(key string, value interface{})` ### Parameters - `key` (string) - The key under which to store the item. - `value` (interface{}) - The item to store in the cache. ## SetWithExpiration() ### Description Adds an item to the cache, replacing it if it already exists. An item is added to the cache with the specified expiration time. ### Signature `func (c *Cache) SetWithExpiration(key string, value interface{}, ttl time.Duration)` ### Parameters - `key` (string) - The key under which to store the item. - `value` (interface{}) - The item to store in the cache. - `ttl` (time.Duration) - The time-to-live for this specific item. ## Get() ### Description Retrieves an item from the cache. Returns the item (if found) and a boolean indicating whether the item was found. ### Signature `func (c *Cache) Get(key string) (interface{}, bool)` ### Returns - `interface{}` - The retrieved item's value. - `bool` - `true` if the item was found in the cache, `false` otherwise. ## Delete() ### Description Removes and returns an item from the cache. Returns the item (if found) and a boolean indicating whether the item was found. ### Signature `func (c *Cache) Delete(key string) (interface{}, bool)` ### Returns - `interface{}` - The deleted item's value. - `bool` - `true` if the item was found and deleted, `false` otherwise. ## Increment() ### Description Increments a non-negative integer item in the cache. If the item is not found, it is added with a value of 1. If the item is not an integer or is negative, it is not modified. ### Signature `func (c *Cache) Increment(key string, delta int64) (int64, error)` ### Parameters - `key` (string) - The key of the integer item to increment. - `delta` (int64) - The amount to increment the item by. ### Returns - `int64` - The new value of the item after incrementing. - `error` - An error if the item is not a non-negative integer or if the operation fails. ## Decrement() ### Description Decrements a non-negative integer item in the cache. If the item is not found, it is added with a value of -1. If the item is not an integer or is negative, it is not modified. ### Signature `func (c *Cache) Decrement(key string, delta int64) (int64, error)` ### Parameters - `key` (string) - The key of the integer item to decrement. - `delta` (int64) - The amount to decrement the item by. ### Returns - `int64` - The new value of the item after decrementing. - `error` - An error if the item is not a non-negative integer or if the operation fails. ``` -------------------------------- ### Create Cache from Existing Items Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/api-cache.md Shows how to initialize a new cache with a pre-existing map of items, useful for restoring cache state. It also demonstrates pre-allocating a map for performance. ```go package main import ( "github.com/patrickmn/go-cache" "time" ) func main() { // Restore a cache from previously saved items savedItems := cache.Items{ "user1": {Object: "alice", Expiration: 0}, "user2": {Object: "bob", Expiration: time.Now().Add(time.Hour).UnixNano()}, } c := cache.NewFrom(5*time.Minute, 10*time.Minute, savedItems) // Or pre-allocate a map for better performance preAllocated := make(map[string]cache.Item, 1000) c = cache.NewFrom(5*time.Minute, 10*time.Minute, preAllocated) } ``` -------------------------------- ### Get Snapshot of Non-Expired Items Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/README.md Returns a map containing a snapshot of all non-expired items currently in the cache. ```go items := cache.Items() ``` -------------------------------- ### Get Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/api-cache.md Retrieves an item from the cache by its key. It returns the stored value and a boolean indicating if the key was found and is not expired. ```APIDOC ## Get ### Description Retrieves an item from the cache by key. Returns the value and a boolean indicating if the key exists and is not expired. ### Method Signature ```go func (c *Cache) Get(k string) (interface{}, bool) ``` ### Parameters #### Path Parameters - **k** (string) - Required - Cache key to retrieve. ### Returns #### Success Response - **value** (interface{}) - The stored value if found and not expired, otherwise `nil`. - **found** (bool) - `true` if the key exists and is not expired, `false` otherwise. ### Behavior - Returns `(nil, false)` if the key does not exist. - Returns `(nil, false)` if the key exists but has expired. - Does not remove expired items; use `DeleteExpired()` to clean them up. ### Example ```go c := cache.New(5*time.Minute, 10*time.Minute) c.Set("username", "alice", cache.NoExpiration) if val, found := c.Get("username"); found { username := val.(string) fmt.Println("Username:", username) } else { fmt.Println("Key not found or expired") } // Type assertion for structured types c.Set("config", map[string]interface{}{"debug": true}, cache.NoExpiration) if val, found := c.Get("config"); found { cfg := val.(map[string]interface{}) if cfg["debug"].(bool) { fmt.Println("Debug mode enabled") } } ``` ``` -------------------------------- ### Get Count of All Items in Cache Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/README.md Returns the total number of items currently stored in the cache, including expired ones. ```go count := cache.ItemCount() ``` -------------------------------- ### Basic Cache Operations Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/quick-start.md Demonstrates how to create a cache, set values with default or no expiration, and retrieve values. Type assertions are shown for non-string types. ```go package main import ( "fmt" "github.com/patrickmn/go-cache" "time" ) func main() { // Create a cache with 5-minute default expiration and 10-minute cleanup c := cache.New(5*time.Minute, 10*time.Minute) // Set a value with default expiration c.Set("foo", "bar", cache.DefaultExpiration) // Set a value that never expires c.Set("baz", 42, cache.NoExpiration) // Get a value if val, found := c.Get("foo"); found { fmt.Println(val) // "bar" } // Type assertion for non-string values if val, found := c.Get("baz"); found { count := val.(int) fmt.Println(count) // 42 } } ``` -------------------------------- ### Get Item Count Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/api-cache.md Returns the total number of items in the cache, including those that have expired but not yet been cleaned up. This operation has O(1) performance. ```go func (c *Cache) ItemCount() int { // ... implementation details ... } ``` ```go c := cache.New(5*time.Minute, 10*time.Minute) c.Set("key1", "val1", cache.NoExpiration) c.Set("key2", "val2", time.Millisecond) fmt.Println(c.ItemCount()) // 2 time.Sleep(10 * time.Millisecond) fmt.Println(c.ItemCount()) // Still 2 (expired item not cleaned) c.DeleteExpired() fmt.Println(c.ItemCount()) // Now 1 ``` -------------------------------- ### Concurrent Cache Operations Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/quick-start.md Demonstrates the thread-safe nature of go-cache. Multiple goroutines can safely perform Set, Get, and Increment operations concurrently. ```go c := cache.New(5*time.Minute, 10*time.Minute) // Multiple goroutines can safely access go func() { for i := 0; i < 1000; i++ { c.Set(fmt.Sprintf("key_%d", i), i, cache.NoExpiration) } }() go func() { for i := 0; i < 1000; i++ { c.Get(fmt.Sprintf("key_%d", i)) } }() go func() { for i := 0; i < 1000; i++ { c.Increment(fmt.Sprintf("counter_%d", i%10), 1) } }() ``` -------------------------------- ### Cache Counter Pattern Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/quick-start.md Illustrates how to use the cache to implement a counter. It shows initialization, incrementing, and retrieving the current value. ```go c := cache.New(time.Hour, 10*time.Minute) // Initialize counter c.Set("page_views", int64(0), cache.NoExpiration) // Increment c.Increment("page_views", 1) // Get current value if val, found := c.Get("page_views"); found { fmt.Println("Views:", val.(int64)) } ``` -------------------------------- ### User Session Storage with go-cache Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/use-cases.md Demonstrates creating a cache for user sessions, setting session data with an expiration, retrieving it, checking remaining time, and deleting it on logout. ```go package main import ( "fmt" "github.com/patrickmn/go-cache" time "time" ) type Session struct { UserID int Username string Email string LoggedInAt time.Time } func main() { // Create cache with 30-minute session timeout sessions := cache.New(30*time.Minute, 10*time.Minute) // Create session on login sessionID := "session_abc123" session := &Session{ UserID: 42, Username: "alice", Email: "alice@example.com", LoggedInAt: time.Now(), } sessions.Set(sessionID, session, 30*time.Minute) // Verify session exists on request if s, found := sessions.Get(sessionID); found { userSession := s.(*Session) fmt.Printf("Welcome, %s!\n", userSession.Username) } else { fmt.Println("Session expired or invalid") } // Check time remaining before expiration if s, exp, found := sessions.GetWithExpiration(sessionID); found { remaining := time.Until(exp) fmt.Printf("Session expires in: %v\n", remaining) } // Clean up on logout sessions.Delete(sessionID) } ``` -------------------------------- ### Handle Increment or Get Item Error Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/README.md Use this pattern to check for errors when incrementing an item or retrieving its value, such as when the item is not found or has the wrong type. ```go val, err := c.IncrementInt64("key", 1) if err != nil { // Item not found or not the right type } ``` -------------------------------- ### Monitor Cache Size with Go-Cache Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/quick-start.md Get the current item count, including expired items, and optionally trigger cleanup if the count exceeds a threshold. ```go c := cache.New(5*time.Minute, 10*time.Minute) // Get current item count (includes expired items) count := c.ItemCount() fmt.Printf("Items in cache: %d\n", count) // Force cleanup if too many items if count > 100000 { c.DeleteExpired() fmt.Println("Cleanup completed, items:", c.ItemCount()) } ``` -------------------------------- ### Counter Pattern Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/README.md Shows how to implement a simple counter using the cache. It initializes a counter to zero with no expiration and then increments it. ```go c.Set("counter", int64(0), cache.NoExpiration) c.Increment("counter", 1) val, _ := c.Get("counter") // Current count ``` -------------------------------- ### Lazy Initialization Pattern Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/quick-start.md Shows how to lazily initialize a configuration value. If the configuration is not in the cache, it's loaded from a source and then cached. ```go func getConfig(c *cache.Cache, key string) map[string]string { if val, found := c.Get(key); found { return val.(map[string]string) } // Load from database or file config := loadConfigFromDB(key) // Cache for 1 hour c.Set(key, config, time.Hour) return config } ``` -------------------------------- ### Type Assertion in Go-Cache Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/README.md Demonstrates how to perform a type assertion when retrieving values from the cache using Get(). Requires a type assertion to access the underlying value. ```go if val, found := c.Get("key"); found { value := val.(MyType) // Type assertion } ``` -------------------------------- ### Create Cache from Existing Items Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/README.md Use this constructor to create a new cache instance initialized with a set of existing items. ```go sessions := cache.NewFrom(30*time.Minute, 10*time.Minute, items) ``` -------------------------------- ### Development/Testing Cache Configuration Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/configuration.md Set up a cache with short expiration times for testing TTL behavior, or disable automatic cleanup for deterministic testing. ```go // Short expiration for testing TTL behavior c := cache.New(time.Millisecond*100, time.Millisecond*50) // Or no automatic cleanup for deterministic testing c := cache.New(time.Second, 0) ``` -------------------------------- ### Cache with Fallback Pattern Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/quick-start.md Illustrates a pattern where the cache is checked first, and if the item is not found, it's fetched from an expensive source and then cached. ```go func getValue(c *cache.Cache, key string) (interface{}, error) { // Try cache first if val, found := c.Get(key); found { return val, nil } // Not in cache; fetch from expensive source val, err := fetchFromDatabase(key) if err != nil { return nil, err } // Cache for 5 minutes c.Set(key, val, 5*time.Minute) return val, nil } ``` -------------------------------- ### Session Storage Pattern Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/quick-start.md Demonstrates using the cache for session storage. It covers setting session data, retrieving it, and checking expiration times. ```go c := cache.New(30*time.Minute, 10*time.Minute) // Create session sessionID := "user_123" sessionData := map[string]interface{}{ "user_id": 123, "name": "Alice", "logged_in": true, } c.Set(sessionID, sessionData, 30*time.Minute) // Retrieve session if session, found := c.Get(sessionID); found { data := session.(map[string]interface{}) fmt.Println("User:", data["name"]) } // Check expiration before use if session, expiration, found := c.GetWithExpiration(sessionID); found { timeLeft := time.Until(expiration) fmt.Printf("Session expires in %v\n", timeLeft) } ``` -------------------------------- ### Get All Unexpired Items Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/api-cache.md Returns a copy of all unexpired items currently in the cache as a map. This map is independent of the cache, meaning modifications to it do not affect the cache itself. Useful for serialization. ```go func (c *Cache) Items() map[string]Item { // ... implementation details ... } ``` ```go import ( "encoding/gob" "github.com/patrickmn/go-cache" "os" ) c := cache.New(5*time.Minute, 10*time.Minute) c.Set("key1", "value1", cache.NoExpiration) c.Set("key2", 42, cache.NoExpiration) // Get snapshot of cache items := c.Items() for k, item := range items { fmt.Printf("%s: %v (expires: %v)\n", k, item.Object, item.Expiration) } // Save to file f, _ := os.Create("cache.dat") defer f.Close() for _, v := range items { gob.Register(v.Object) } enc := gob.NewEncoder(f) enc.Encode(items) ``` -------------------------------- ### Cache Constructors Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/MANIFEST.txt Details on how to create new cache instances. ```APIDOC ## Cache Constructors This section documents the available constructors for creating `Cache` instances. ### NewCache() Creates a new cache with default settings. #### Returns - `*Cache` - A pointer to the newly created cache instance. ### NewCacheWithEviction(eviction int) (*Cache, error) Creates a new cache with a specified eviction limit. #### Parameters - **eviction** (int) - Required - The maximum number of items the cache can hold before eviction. #### Returns - `*Cache` - A pointer to the newly created cache instance. - `error` - An error if the eviction limit is invalid. ``` -------------------------------- ### Retrieve Item from Cache Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/api-cache.md Use Get to retrieve an item by its key. It returns the value and a boolean indicating if the item was found and is not expired. Expired items are not removed automatically. ```go func (c *Cache) Get(k string) (interface{}, bool) ``` ```go c := cache.New(5*time.Minute, 10*time.Minute) c.Set("username", "alice", cache.NoExpiration) if val, found := c.Get("username"); found { username := val.(string) fmt.Println("Username:", username) } else { fmt.Println("Key not found or expired") } // Type assertion for structured types c.Set("config", map[string]interface{}{"debug": true}, cache.NoExpiration) if val, found := c.Get("config"); found { cfg := val.(map[string]interface{}) if cfg["debug"].(bool) { fmt.Println("Debug mode enabled") } } ``` -------------------------------- ### Registering Eviction Callbacks Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/module-overview.md Shows how to register a function to be called when an item is evicted from the cache. This is useful for performing cleanup tasks. ```go c.OnEvicted(func(k string, v interface{}) { // Log, update database, notify systems, etc. }) ``` -------------------------------- ### Constructors Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/README.md Functions to create new cache instances with specified configurations. ```APIDOC ## Constructors ### `New(defaultExpiration, cleanupInterval)` #### Description Creates a new cache instance with a default expiration duration and a cleanup interval. ### `NewFrom(defaultExpiration, cleanupInterval, items)` #### Description Creates a new cache instance from a map of existing items, with a default expiration duration and a cleanup interval. ``` -------------------------------- ### New Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/api-cache.md Creates a new cache instance with specified default expiration and background cleanup intervals. Use `NoExpiration` or `DefaultExpiration` for default item behavior. ```APIDOC ## New ### Description Creates a new cache with the specified default expiration duration and cleanup interval. ### Parameters - **defaultExpiration** (time.Duration) - Default expiration time for items added without explicit expiration. Use `NoExpiration` (-1) for items that never expire by default, or `DefaultExpiration` (0) to use cache's default. - **cleanupInterval** (time.Duration) - Interval at which the background janitor runs to delete expired items. If less than 1 nanosecond, the janitor is disabled and `DeleteExpired()` must be called manually. ### Returns - **`*Cache`** - A new cache instance ready for use. ### Example ```go package main import ( "fmt" "github.com/patrickmn/go-cache" time "time" ) func main() { // Create a cache with 5-minute default expiration and 10-minute cleanup c := cache.New(5*time.Minute, 10*time.Minute) c.Set("key1", "value1", cache.DefaultExpiration) c.Set("key2", "value2", cache.NoExpiration) if val, found := c.Get("key1"); found { fmt.Println(val) } } ``` ``` -------------------------------- ### Get Snapshot of All Cache Items Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/Item-type-reference.md Retrieve a snapshot of all items currently in the cache. This method is useful for iterating over cache contents or performing batch operations. Note that the returned map is a copy and modifications to it will not affect the cache. ```go c := cache.New(time.Hour, 10*time.Minute) c.Set("key1", "value1", cache.NoExpiration) c.Set("key2", &MyStruct{}, time.Hour) // Get items snapshot items := c.Items() for key, item := range items { // item is cache.Item fmt.Printf("Key: %s\n", key) fmt.Printf("Value: %v (%T)\n", item.Object, item.Object) if item.Expiration > 0 { expiresAt := time.Unix(0, item.Expiration) fmt.Printf("Expires: %v\n", expiresAt) } else { fmt.Println("Never expires") } } ``` -------------------------------- ### Create Cache with New() Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/configuration.md Use `New()` to create a cache instance. Specify default expiration and cleanup intervals. Set default expiration to `cache.DefaultExpiration` (0) for no default or `cache.NoExpiration` (-1) for items that never expire. A cleanup interval less than 1 nanosecond disables the janitor, requiring manual `DeleteExpired()` calls. ```go import ( "github.com/patrickmn/go-cache" "time" ) // Cache with 5-minute default expiration and 10-minute cleanup c := cache.New(5*time.Minute, 10*time.Minute) // Cache with no default expiration (items never expire unless specified) c := cache.New(cache.NoExpiration, 10*time.Minute) // Cache with manual cleanup only (no background janitor) c := cache.New(5*time.Minute, 0) ``` -------------------------------- ### Cache Warming on Startup Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/use-cases.md Loads frequently accessed data, such as active users, into the cache during application startup to improve initial response times. ```go func (qc *QueryCache) WarmCache() error { // Load frequently accessed data into cache on startup users, err := database.GetAllActiveUsers() if err != nil { return err } for _, user := range users { cacheKey := fmt.Sprintf("user_%d", user.ID) qc.cache.Set(cacheKey, user, 5*time.Minute) } fmt.Printf("Warmed cache with %d users\n", len(users)) return nil } ``` -------------------------------- ### Create Cache Items Programmatically Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/Item-type-reference.md Initialize a map of cache items, including permanent and temporary ones, before creating a cache instance. ```go items := make(map[string]cache.Item) // Add permanent items items["config_1"] = cache.Item{ Object: map[string]string{"env": "prod"}, Expiration: 0, } // Add temporary items items["session_123"] = cache.Item{ Object: "session_data", Expiration: time.Now().Add(30 * time.Minute).UnixNano(), } // Create cache from items c := cache.NewFrom(5*time.Minute, 10*time.Minute, items) ``` -------------------------------- ### Atomic Operations in Go-Cache Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/advanced-topics.md Demonstrates the use of atomic increment operations in go-cache, which are safe for concurrent access from multiple goroutines. The example shows multiple goroutines incrementing a counter, guaranteeing the final value is accurate due to internal locking. ```go // Safe to call from multiple goroutines go func() { c.Increment("counter", 1) }() go func() { c.Increment("counter", 1) }() go func() { c.Increment("counter", 1) }() time.Sleep(time.Millisecond) val, _ := c.Get("counter") // Guaranteed to be 3 (all increments serialized by write lock) ``` -------------------------------- ### Conditional Add Pattern Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/quick-start.md Shows how to use `Add` to set a key only if it does not already exist, useful for implementing locks or ensuring a value is set only once. ```go c := cache.New(5*time.Minute, 10*time.Minute) // Try to add; if exists, use existing err := c.Add("lock", "owner1", 30*time.Second) if err != nil { // Key already exists; someone else has the lock fmt.Println("Lock already held") } else { // We got the lock defer c.Delete("lock") // Do protected work } ``` -------------------------------- ### Request Deduplication with Go-Cache Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/use-cases.md Prevent duplicate requests by using go-cache to track request IDs. The `Add` method returns `nil` if the request ID is new, indicating it's the first request. This example shows integration within an HTTP handler. ```go type RequestDeduplicator struct { cache *cache.Cache } func (rd *RequestDeduplicator) IsFirstRequest(requestID string) bool { // Try to record this request ID err := rd.cache.Add(requestID, true, time.Hour) // Returns nil if successfully added (first request) return err == nil } // Usage in API handler dedup := &RequestDeduplicator{cache: cache.New(time.Hour, 10*time.Minute)} http.HandleFunc("/api/process", func(w http.ResponseWriter, r *http.Request) { requestID := r.Header.Get("X-Request-ID") if !dedup.IsFirstRequest(requestID) { // Duplicate request; return cached response w.WriteHeader(http.StatusConflict) w.Write([]byte("Request already processed")) return } // Process request result := processRequest(r) w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(result) }) ``` -------------------------------- ### Handle Increment Value Not Integer Error Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/errors.md Demonstrates handling the 'The value for is not an integer' error. This error occurs when attempting to increment or decrement a value that is not a supported numeric type. The example shows retrieving and checking the type of the stored value. ```go c := cache.New(5*time.Minute, 10*time.Minute) c.Set("name", "alice", cache.NoExpiration) err := c.Increment("name", 1) if err != nil { fmt.Println(err) // Output: "The value for name is not an integer" } ``` ```go err := c.Increment("key", 1) if err != nil && strings.Contains(err.Error(), "not an integer") { // Value is not numeric. Retrieve and check type first if val, found := c.Get("key"); found { fmt.Printf("Stored type: %T\n", val) } } ``` -------------------------------- ### Persisting and Restoring Cache with Gob Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/module-overview.md Demonstrates how to use encoding/gob to serialize and deserialize cache items. Ensure to register custom types with gob before encoding. ```go items := c.Items() gob.Register(item.Object) // Register types enc.Encode(items) // Serialize c = cache.NewFrom(..., items) // Restore ``` -------------------------------- ### Per-User Rate Limiter in Go Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/use-cases.md Implement per-user rate limiting by tracking request counts within a sliding window. Initialize with the maximum requests and the time window. The Allow method increments the count for a user and returns false if the limit is exceeded. ```go type RateLimiter struct { cache *cache.Cache maxCount int64 window time.Duration } func NewRateLimiter(maxRequests int64, window time.Duration) *RateLimiter { return &RateLimiter{ cache: cache.New(window, window), maxCount: maxRequests, window: window, } } func (rl *RateLimiter) Allow(userID string) bool { key := fmt.Sprintf("ratelimit_%s", userID) count, err := rl.cache.IncrementInt64(key, 1) if err != nil { // Key doesn't exist; first request in window rl.cache.Set(key, int64(1), rl.window) return true } return count <= rl.maxCount } // Usage rateLimiter := NewRateLimiter(100, time.Minute) if !rateLimiter.Allow("user_123") { return fmt.Errorf("rate limit exceeded: 100 requests per minute") } ``` -------------------------------- ### Handle IncrementFloat Value Not Numeric Error Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/errors.md Shows how to handle the 'The value for does not have type float32 or float64' error from IncrementFloat(). This error is returned when the cached value is not a float32 or float64. The example suggests checking the current type or using type-specific increments. ```go c := cache.New(5*time.Minute, 10*time.Minute) c.Set("age", 30, cache.NoExpiration) // Stores as int err := c.IncrementFloat("age", 0.5) if err != nil { fmt.Println(err) // Output: "The value for age does not have type float32 or float64" } ``` ```go err := c.IncrementFloat("key", 1.5) if err != nil && strings.Contains(err.Error(), "does not have type float") { // Use type-specific increment for the actual type, or convert val, _ := c.Get("key") fmt.Printf("Current type: %T\n", val) } ``` -------------------------------- ### Create New Cache Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/README.md Use this constructor to create a new cache instance with a default item expiration and a cache cleanup interval. ```go sessions := cache.New(30*time.Minute, 10*time.Minute) ``` -------------------------------- ### Pre-allocate Cache Memory in Go Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/quick-start.md Initialize a cache with a pre-allocated map to optimize performance when the approximate number of items is known. ```go items := make(map[string]cache.Item, 50000) c := cache.NewFrom(5*time.Minute, 10*time.Minute, items) // Cache is pre-allocated for 50k items ``` -------------------------------- ### Combined Cleanup Strategies Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/advanced-topics.md Combine automatic background cleanup with manual, aggressive cleanup during specific times, like off-peak hours, for optimized resource management. ```go c := cache.New(5*time.Minute, 30*time.Minute) // Light background cleanup // Additional aggressive cleanup during off-peak hours go func() { ticker := time.NewTicker(time.Hour) defer ticker.Stop() for range ticker.C { midnight := time.Now().Hour() == 2 if midnight { c.DeleteExpired() } } }() ``` -------------------------------- ### Go Real-time Statistics with Cache Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/use-cases.md Track event durations and calculate averages using a cache. Store durations in milliseconds for simpler arithmetic and handle potential errors during increment operations. ```go type Stats struct { cache *cache.Cache } func (s *Stats) RecordEventDuration(eventName string, duration time.Duration) { key := fmt.Sprintf("event_duration_%s", eventName) // Store as milliseconds for simpler arithmetic durationMs := int64(duration.Milliseconds()) val, err := s.cache.IncrementInt64(key, durationMs) if err != nil { s.cache.Set(key, durationMs, time.Hour) } } func (s *Stats) GetAverageDuration(eventName string) time.Duration { durKey := fmt.Sprintf("event_duration_%s", eventName) countKey := fmt.Sprintf("event_count_%s", eventName) totalMs, _ := s.cache.Get(durKey) count, _ := s.cache.Get(countKey) if count == nil || totalMs == nil { return 0 } avg := totalMs.(int64) / count.(int64) return time.Duration(avg) * time.Millisecond } ``` -------------------------------- ### Storing and Retrieving Different Data Types Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/Item-type-reference.md Demonstrates how to store various data types (string, int, struct pointer) and retrieve them using type assertions. Includes safe type checking with a switch statement. ```go c.Set("str", "hello", cache.NoExpiration) c.Set("int", 42, cache.NoExpiration) c.Set("ptr", &MyStruct{}, cache.NoExpiration) // Retrieve with assertion if s, found := c.Get("str"); found { str := s.(string) // Type assertion } // Safe type checking if i, found := c.Get("int"); found { switch v := i.(type) { case int: fmt.Println("Integer:", v) case int64: fmt.Println("Int64:", v) default: fmt.Println("Unknown type:", v) } } ``` -------------------------------- ### NewFrom Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/api-cache.md Initializes a new cache with an existing map of items. This is useful for restoring cache state or pre-populating the cache. ```APIDOC ## NewFrom ### Description Creates a new cache initialized with an existing items map. Useful for restoring a cache from serialized state or pre-populating with known items. ### Parameters - **defaultExpiration** (time.Duration) - Default expiration time for new items added after initialization. - **cleanupInterval** (time.Duration) - Interval for background cleanup of expired items. - **items** (map[string]Item) - Initial items map. No copy is made; this map becomes the cache's internal storage. Do not retain references to this map after passing it. ### Returns - **`*Cache`** - A new cache instance initialized with the provided items. ### Notes - The provided items map is used directly as the cache's internal storage. It is not copied. - When serializing and deserializing, ensure all types stored in the cache are registered with `gob.Register()` before encoding and decoding. - After passing a map to `NewFrom()`, only access it through the cache's methods to maintain synchronization guarantees. ### Example ```go package main import ( "github.com/patrickmn/go-cache" time "time" ) func main() { // Restore a cache from previously saved items savedItems := cache.Items{ "user1": {Object: "alice", Expiration: 0}, "user2": {Object: "bob", Expiration: time.Now().Add(time.Hour).UnixNano()}, } c := cache.NewFrom(5*time.Minute, 10*time.Minute, savedItems) // Or pre-allocate a map for better performance preAllocated := make(map[string]cache.Item, 1000) c = cache.NewFrom(5*time.Minute, 10*time.Minute, preAllocated) } ``` ``` -------------------------------- ### Create Cache with NewFrom() Source: https://github.com/patrickmn/go-cache/blob/master/_autodocs/configuration.md Use `NewFrom()` to create a cache from an existing map of items. This is useful for restoring serialized cache states or pre-allocating cache capacity. The provided map is used directly, so avoid retaining external references to it. ```go import ( "github.com/patrickmn/go-cache" "time" ) // Restore from serialized state savedItems := make(map[string]cache.Item) // ... deserialize into savedItems ... c := cache.NewFrom(5*time.Minute, 10*time.Minute, savedItems) // Pre-allocate for known size items := make(map[string]cache.Item, 10000) c := cache.NewFrom(5*time.Minute, 10*time.Minute, items) ```