### Run HTTP Cache Example Source: https://github.com/jellydator/ttlcache/blob/v3/examples/httpcache/README.md Execute this command to start the HTTP server with caching enabled. The server will be available on port 8080. ```bash go run cmd/main.go ``` -------------------------------- ### Start and Stop Automatic Cleanup Goroutine Source: https://context7.com/jellydator/ttlcache/llms.txt The Start method initiates a background goroutine for automatic cleanup of expired items. It blocks and runs a timer loop, calling DeleteExpired periodically. Always launch Start in a separate goroutine. Stop signals the goroutine to exit and waits for it to terminate. Both methods are idempotent. ```go cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](30 * time.Second), ) go cache.Start() // ... application logic ... // Graceful shutdown cache.Stop() ``` -------------------------------- ### Install TTLCache Source: https://github.com/jellydator/ttlcache/blob/v3/README.md Use this command to add the TTLCache library to your Go project. Ensure you are using a compatible Go version. ```go go get github.com/jellydator/ttlcache/v3 ``` -------------------------------- ### Create TTLCache Instance Source: https://context7.com/jellydator/ttlcache/llms.txt Demonstrates creating a basic cache, a cache with a global TTL and capacity, and starting the cleanup goroutine. Remember to defer cache.Stop(). ```go package main import ( "fmt" "time" "github.com/jellydator/ttlcache/v3" ) func main() { // Minimal cache — items never expire unless given an explicit TTL bare := ttlcache.New[string, int]() _ = bare // Cache with a 5-minute global TTL and max 1000 items cache := ttlcache.New[string, int]( ttlcache.WithTTL[string, int](5*time.Minute), ttlcache.WithCapacity[string, int](1000), ) // Start the automatic expired-item cleanup goroutine go cache.Start() defer cache.Stop() fmt.Println("cache created") } ``` -------------------------------- ### Run DB Cache Example with Custom Expiry Source: https://github.com/jellydator/ttlcache/blob/v3/examples/dbcache/README.md Run the database cache example with a specified cache expiration time. This allows you to test the cache's performance under different caching durations. ```bash go run cmd/main.go -exp=200ms ``` ```bash go run cmd/main.go -exp=500ms ``` -------------------------------- ### Create Cache with TTL and Start Auto-Deletion Source: https://github.com/jellydator/ttlcache/blob/v3/README.md Create a cache instance with a default TTL of 30 minutes and start a background goroutine for automatic expired item deletion. ```go func main() { cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](30 * time.Minute), ) go cache.Start() // starts automatic expired item deletion } ``` -------------------------------- ### Set, Get, Check, and Delete Cache Items Source: https://github.com/jellydator/ttlcache/blob/v3/README.md Demonstrates basic cache operations: inserting items with specific TTLs, retrieving items, checking for their existence, and deleting them. Also shows GetOrSet and GetAndDelete. ```go func main() { cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](30 * time.Minute), ) // insert data cache.Set("first", "value1", ttlcache.DefaultTTL) cache.Set("second", "value2", ttlcache.NoTTL) cache.Set("third", "value3", ttlcache.DefaultTTL) // retrieve data item := cache.Get("first") fmt.Println(item.Value(), item.ExpiresAt()) // check key ok := cache.Has("third") // delete data cache.Delete("second") cache.DeleteExpired() cache.DeleteAll() // retrieve data if in cache otherwise insert data item, retrieved := cache.GetOrSet("fourth", "value4", WithTTL[string, string](ttlcache.DefaultTTL)) // retrieve and delete data item, present := cache.GetAndDelete("fourth") } ``` -------------------------------- ### Get Item with TTL Extension Options Source: https://context7.com/jellydator/ttlcache/llms.txt Demonstrates retrieving an item, which by default extends its expiration ('touch on hit'). Shows how to disable this behavior using `WithDisableTouchOnHit`. ```go cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](5 * time.Minute), ) go cache.Start() deffer cache.Stop() cache.Set("greeting", "hello", ttlcache.DefaultTTL) // Normal retrieval — also extends expiration item := cache.Get("greeting") if item == nil { fmt.Println("not found or expired") } else { fmt.Println(item.Key(), item.Value(), item.ExpiresAt()) // greeting hello } // Retrieve WITHOUT extending expiration item2 := cache.Get("greeting", ttlcache.WithDisableTouchOnHit[string, string]()) fmt.Println(item2.Value()) // hello ``` -------------------------------- ### Enable Item Version Tracking in TTLCache Source: https://context7.com/jellydator/ttlcache/llms.txt Use the `WithVersion` option to enable a per-item monotonic version counter. The counter increments on each update, starting at 0 on insertion. ```go cache := ttlcache.New[string, string]( ttlcache.WithVersion[string, string](true), ) cache.Set("cfg", "v1", ttlcache.NoTTL) fmt.Println(cache.Get("cfg").Version()) // 0 cache.Set("cfg", "v2", ttlcache.NoTTL) fmt.Println(cache.Get("cfg").Version()) // 1 cache.Set("cfg", "v3", ttlcache.NoTTL) fmt.Println(cache.Get("cfg").Version()) // 2 ``` -------------------------------- ### ttlcache.New Source: https://context7.com/jellydator/ttlcache/llms.txt Creates a new Cache instance. Options can be provided to configure TTL, capacity, and other behaviors. By default, items do not expire and no cleanup goroutine is started. ```APIDOC ## ttlcache.New — Create a cache instance ### Description Creates a new `Cache[K, V]` instance. Accepts zero or more `Option` values to configure TTL, capacity, loader, and other behaviours. By default no items expire and no cleanup goroutine is started. ### Method `New` ### Parameters #### Options - `ttlcache.WithTTL[K, V](duration time.Duration)`: Sets the default time-to-live for items in the cache. - `ttlcache.WithCapacity[K, V](capacity int)`: Sets the maximum number of items the cache can hold. ### Request Example ```go package main import ( "fmt" "time" "github.com/jellydator/ttlcache/v3" ) func main() { // Minimal cache — items never expire unless given an explicit TTL bare := ttlcache.New[string, int]() _ = bare // Cache with a 5-minute global TTL and max 1000 items cache := ttlcache.New[string, int]( ttlcache.WithTTL[string, int](5*time.Minute), ttlcache.WithCapacity[string, int](1000), ) // Start the automatic expired-item cleanup goroutine go cache.Start() defer cache.Stop() fmt.Println("cache created") } ``` ``` -------------------------------- ### Cache.Start, Cache.Stop Source: https://context7.com/jellydator/ttlcache/llms.txt Manages the cache's background cleanup goroutine. `Start` launches a timer loop that automatically calls `DeleteExpired` when items are due to expire. It should be run in a separate goroutine. `Stop` signals the goroutine to exit and waits for it to terminate. Both methods are idempotent. ```APIDOC ## Cache.Start / Cache.Stop ### Description Manages the cache's background cleanup goroutine. `Start` launches a timer loop that automatically calls `DeleteExpired` when items are due to expire. It should be run in a separate goroutine. `Stop` signals the goroutine to exit and waits for it to terminate. Both methods are idempotent. ### Methods - `Start()`: Starts the background cleanup timer loop. Should be called in a separate goroutine. - `Stop()`: Signals the background cleanup goroutine to stop and waits for its termination. ### Request Example ```go cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](30 * time.Second), ) go cache.Start() // ... application logic ... // Graceful shutdown cache.Stop() ``` ### Response These methods do not return a value. ``` -------------------------------- ### Limit Cache Capacity by Cost Source: https://github.com/jellydator/ttlcache/blob/v3/README.md Configure a maximum cost for the cache, such as memory usage, using a custom cost calculation function. This example limits the cache to approximately 5KiB. ```go import ( "github.com/jellydator/ttlcache" ) func main() { cache := ttlcache.New[string, string]( ttlcache.WithMaxCost[string, string](5120, func(item ttlcache.CostItem[string, string]) uint64 { // Note: The below line doesn't include memory used by internal // structures or string metadata for the key and the value. return uint64(len(item.Key) + len(item.Value)) }), ) cache.Set("first", "value1", ttlcache.DefaultTTL) } ``` -------------------------------- ### Lazy Loading with Loaders Source: https://context7.com/jellydator/ttlcache/llms.txt Implement lazy loading where a `Loader` is automatically called by `Get` for absent keys. `SuppressedLoader` deduplicates concurrent calls. ```APIDOC ## WithLoader / LoaderFunc / SuppressedLoader — Lazy loading A `Loader` is called automatically by `Get` when a key is absent. `LoaderFunc` adapts any function. `SuppressedLoader` wraps any loader with `singleflight` semantics so that concurrent cache misses for the same key result in only one backend call. ```go // Build a suppressed DB loader loader := ttlcache.NewSuppressedLoader[string, string]( ttlcache.LoaderFunc[string, string](func(c *ttlcache.Cache[string, string], key string) *ttlcache.Item[string, string] { // Simulate a database lookup val, err := db.Lookup(key) if err != nil || val == "" { return nil // cache miss — nothing stored } // Insert into cache and return the item return c.Set(key, val, 5*time.Minute) }), nil, // use a fresh singleflight.Group ) cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](5*time.Minute), ttlcache.WithLoader[string, string](loader), ) go cache.Start() def cache.Stop() // Cache miss triggers loader; concurrent misses for "user:1" deduplicated item := cache.Get("user:1") if item != nil { fmt.Println(item.Value()) // value from DB, now cached for 5 min } // Use an ephemeral per-call loader that overrides the default item = cache.Get("user:2", ttlcache.WithLoader[string, string]( ttlcache.LoaderFunc[string, string](func(c *ttlcache.Cache[string, string], key string) *ttlcache.Item[string, string] { return c.Set(key, "override-value", 1*time.Minute) }), ), ) fmt.Println(item.Value()) // override-value ``` ``` -------------------------------- ### Atomic Get or Set Operation Source: https://context7.com/jellydator/ttlcache/llms.txt Illustrates the `GetOrSet` method for atomically retrieving an item or inserting it if it doesn't exist. The boolean return value indicates if the item was found. ```go cache := ttlcache.New[string, int]( ttlcache.WithTTL[string, int](1 * time.Hour), ) // First call — item does not exist, it is created item, found := cache.GetOrSet("counter", 0, ttlcache.WithTTL[string, int](1*time.Hour)) fmt.Println(item.Value(), found) // 0 false // Second call — item exists, the existing one is returned item, found = cache.GetOrSet("counter", 99) fmt.Println(item.Value(), found) // 0 true ``` -------------------------------- ### Atomic Get and Delete Operation Source: https://context7.com/jellydator/ttlcache/llms.txt The GetAndDelete method atomically retrieves an item and removes it from the cache. It returns the item and true if found, otherwise (nil, false). This is useful for one-time tokens or processing tasks from a queue. ```go cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](5 * time.Minute), ) cache.Set("otp:user-7", "836492", 2*time.Minute) item, ok := cache.GetAndDelete("otp:user-7") if ok { fmt.Println("OTP:", item.Value()) // OTP: 836492 } // Key is now gone fmt.Println(cache.Has("otp:user-7")) // false ``` -------------------------------- ### Create a New Cache Instance Source: https://github.com/jellydator/ttlcache/blob/v3/README.md Instantiate a new ttlcache.Cache with default settings. No items will expire by default. ```go func main() { cache := ttlcache.New[string, string]() } ``` -------------------------------- ### Implementing Cost-Based Eviction Source: https://context7.com/jellydator/ttlcache/llms.txt Limit cache size by a total cost budget using `WithMaxCost`. A `CostFunc` calculates item cost, and LRU items are evicted when the budget is exceeded. ```go // Limit to ~5 KiB of combined key+value bytes cache := ttlcache.New[string, string]( ttlcache.WithMaxCost[string, string](5120, func(item ttlcache.CostItem[string, string]) uint64 { return uint64(len(item.Key) + len(item.Value)) }), ) cache.Set("small", "x", ttlcache.NoTTL) cache.Set("large", string(make([]byte, 4096)), ttlcache.NoTTL) // Inserting another large item will evict the LRU item to stay within 5120 bytes fmt.Printf("items=%d\n", cache.Len()) ``` -------------------------------- ### Subscribe to Cache Events Source: https://github.com/jellydator/ttlcache/blob/v3/README.md Configure event handlers for item insertion, update, and eviction. The eviction handler demonstrates filtering by eviction reason. ```go func main() { cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](30 * time.Minute), ttlcache.WithCapacity[string, string](300), ) cache.OnInsertion(func(ctx context.Context, item *ttlcache.Item[string, string]) { fmt.Println(item.Value(), item.ExpiresAt()) }) cache.OnUpdate(func(ctx context.Context, item *ttlcache.Item[string, string]) { fmt.Println(item.Value(), item.ExpiresAt()) }) cache.OnEviction(func(ctx context.Context, reason ttlcache.EvictionReason, item *ttlcache.Item[string, string]) { if reason == ttlcache.EvictionReasonCapacityReached { fmt.Println(item.Key(), item.Value()) } }) cache.Set("first", "value1", ttlcache.DefaultTTL) cache.DeleteAll() } ``` -------------------------------- ### Set Item with Specific TTL Options Source: https://context7.com/jellydator/ttlcache/llms.txt Shows how to insert or overwrite items using different TTL strategies: cache-level default, item-specific duration, permanent storage, and preserving existing TTL on update. ```go cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](10 * time.Minute), ) go cache.Start() deffer cache.Stop() // Use the cache-level TTL (10 min) item := cache.Set("session:abc", "user-42", ttlcache.DefaultTTL) fmt.Println(item.Value(), item.ExpiresAt()) // user-42 // Override with item-specific TTL cache.Set("token:xyz", "bearer-token", 30*time.Second) // Store permanently cache.Set("config:feature-flag", "enabled", ttlcache.NoTTL) // Update value but keep the existing TTL cache.Set("session:abc", "user-99", ttlcache.PreviousOrDefaultTTL) ``` -------------------------------- ### Implement a Custom Cache Loader Source: https://github.com/jellydator/ttlcache/blob/v3/README.md Define a custom loader function to populate the cache when a requested key is not found. The loader can fetch data from external sources. ```go func main() { loader := ttlcache.LoaderFunc[string, string]( func(c *ttlcache.Cache[string, string], key string) *ttlcache.Item[string, string] { // load from file/make an HTTP request item := c.Set("key from file", "value from file") return item }, ) cache := ttlcache.New[string, string]( ttlcache.WithLoader[string, string](loader), ) item := cache.Get("key from file") } ``` -------------------------------- ### Implementing Lazy Loading with Suppressed Loaders Source: https://context7.com/jellydator/ttlcache/llms.txt Use `WithLoader` to automatically fetch missing keys. `NewSuppressedLoader` with `singleflight` deduplicates concurrent misses for the same key. ```go // Build a suppressed DB loader loader := ttlcache.NewSuppressedLoader[string, string]( ttlcache.LoaderFunc[string, string](func(c *ttlcache.Cache[string, string], key string) *ttlcache.Item[string, string] { // Simulate a database lookup val, err := db.Lookup(key) if err != nil || val == "" { return nil // cache miss — nothing stored } // Insert into cache and return the item return c.Set(key, val, 5*time.Minute) }), nil, // use a fresh singleflight.Group ) cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](5*time.Minute), ttlcache.WithLoader[string, string](loader), ) go cache.Start() defer cache.Stop() // Cache miss triggers loader; concurrent misses for "user:1" deduplicated item := cache.Get("user:1") if item != nil { fmt.Println(item.Value()) // value from DB, now cached for 5 min } // Use an ephemeral per-call loader that overrides the default item = cache.Get("user:2", ttlcache.WithLoader[string, string]( ttlcache.LoaderFunc[string, string](func(c *ttlcache.Cache[string, string], key string) *ttlcache.Item[string, string] { return c.Set(key, "override-value", 1*time.Minute) }), ), ) fmt.Println(item.Value()) // override-value ``` -------------------------------- ### Create Cache and Manually Delete Expired Items Source: https://github.com/jellydator/ttlcache/blob/v3/README.md Create a cache instance with a default TTL and periodically call DeleteExpired() to remove stale items. This is useful when external systems control the deletion timing. ```go func main() { cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](30 * time.Minute), ) for { time.Sleep(4 * time. Hour) cache.DeleteExpired() } } ``` -------------------------------- ### Retrieving Cache Metrics Source: https://context7.com/jellydator/ttlcache/llms.txt Obtain a snapshot of lifetime counters for cache operations including insertions, updates, hits, misses, and evictions. ```go cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](1 * time.Minute), ) go cache.Start() defer cache.Stop() cache.Set("k1", "v1", ttlcache.DefaultTTL) cache.Set("k2", "v2", ttlcache.DefaultTTL) cache.Get("k1") // hit cache.Get("k1") // hit cache.Get("k3") // miss m := cache.Metrics() fmt.Printf("insertions=%d updates=%d hits=%d misses=%d evictions=%d\n", m.Insertions, m.Updates, m.Hits, m.Misses, m.Evictions) // insertions=2 updates=0 hits=2 misses=1 evictions=0 ``` -------------------------------- ### Registering Cache Event Hooks Source: https://context7.com/jellydator/ttlcache/llms.txt Register asynchronous callbacks for insertion, update, and eviction events. Each handler runs in its own goroutine and returns an unsubscribe function. ```go cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](5 * time.Minute), ttlcache.WithCapacity[string, string](500), ) stopInsert := cache.OnInsertion(func(ctx context.Context, item *ttlcache.Item[string, string]) { fmt.Printf("[INSERT] key=%s value=%s expires=%s\n", item.Key(), item.Value(), item.ExpiresAt().Format(time.RFC3339)) }) stopUpdate := cache.OnUpdate(func(ctx context.Context, item *ttlcache.Item[string, string]) { fmt.Printf("[UPDATE] key=%s new_value=%s\n", item.Key(), item.Value()) }) stopEvict := cache.OnEviction(func(ctx context.Context, reason ttlcache.EvictionReason, item *ttlcache.Item[string, string]) { switch reason { case ttlcache.EvictionReasonExpired: fmt.Printf("[EVICT] key=%s reason=expired\n", item.Key()) case ttlcache.EvictionReasonCapacityReached: fmt.Printf("[EVICT] key=%s reason=capacity\n", item.Key()) case ttlcache.EvictionReasonDeleted: fmt.Printf("[EVICT] key=%s reason=deleted\n", item.Key()) case ttlcache.EvictionReasonMaxCostExceeded: fmt.Printf("[EVICT] key=%s reason=max_cost\n", item.Key()) } }) go cache.Start() cache.Set("hello", "world", ttlcache.DefaultTTL) cache.Set("hello", "updated", ttlcache.DefaultTTL) cache.Delete("hello") // Unsubscribe all handlers stopInsert() stopUpdate() stopEvict() cache.Stop() ``` -------------------------------- ### Cost-Based Eviction Source: https://context7.com/jellydator/ttlcache/llms.txt Limit the cache by a total cost budget instead of item count. A `CostFunc` calculates the cost of each item, and items are evicted when the budget is exceeded. ```APIDOC ## WithMaxCost — Cost-based eviction Limits the cache by a total cost budget rather than item count. A `CostFunc` computes the cost for each item on insertion/update. When the total cost exceeds `maxCost`, the least-recently-used items are evicted until the budget is satisfied. ```go // Limit to ~5 KiB of combined key+value bytes cache := ttlcache.New[string, string]( ttlcache.WithMaxCost[string, string](5120, func(item ttlcache.CostItem[string, string]) uint64 { return uint64(len(item.Key) + len(item.Value)) }), ) cache.Set("small", "x", ttlcache.NoTTL) cache.Set("large", string(make([]byte, 4096)), ttlcache.NoTTL) // Inserting another large item will evict the LRU item to stay within 5120 bytes fmt.Printf("items=%d\n", cache.Len()) ``` ``` -------------------------------- ### Cache.Get Source: https://context7.com/jellydator/ttlcache/llms.txt Retrieves an item by key. By default, successful retrieval extends the item's expiration ('touch on hit'). Options can disable this behavior. ```APIDOC ## Cache.Get — Retrieve an item (with TTL extension) ### Description Retrieves an item by key. By default, a successful retrieval extends the item's expiration ("touch on hit"). Returns `nil` if the key does not exist or the item has expired. Accepts per-call `Option` overrides (e.g. `WithDisableTouchOnHit`). ### Method `Get(key K, opts ...ttlcache.Option[K, V])` ### Parameters - **key** (K): The key of the item to retrieve. - **opts** (...ttlcache.Option[K, V]): Optional configuration for the retrieval, such as `ttlcache.WithDisableTouchOnHit`. ### Response #### Success Response - **Item** (interface{ Key() K; Value() V; ExpiresAt() time.Time } | nil): The cached item if found and not expired, otherwise `nil`. ### Request Example ```go cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](5 * time.Minute), ) go cache.Start() def cache.Stop() cache.Set("greeting", "hello", ttlcache.DefaultTTL) // Normal retrieval — also extends expiration item := cache.Get("greeting") if item == nil { fmt.Println("not found or expired") } else { fmt.Println(item.Key(), item.Value(), item.ExpiresAt()) // greeting hello } // Retrieve WITHOUT extending expiration item2 := cache.Get("greeting", ttlcache.WithDisableTouchOnHit[string, string]()) fmt.Println(item2.Value()) // hello ``` ``` -------------------------------- ### Cache Event Hooks Source: https://context7.com/jellydator/ttlcache/llms.txt Register asynchronous callbacks for insertion, update, and eviction events. Handlers run in separate goroutines and return an unsubscribe function. ```APIDOC ## Cache.OnInsertion / OnUpdate / OnEviction — Event hooks Each method registers an async callback fired on the respective event. Handlers run in their own goroutine and do not block cache operations. Each returns an unsubscribe function that cancels the handler's context and waits for in-flight calls to finish. ```go cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](5 * time.Minute), ttlcache.WithCapacity[string, string](500), ) stopInsert := cache.OnInsertion(func(ctx context.Context, item *ttlcache.Item[string, string]) { fmt.Printf("[INSERT] key=%s value=%s expires=%s\n", item.Key(), item.Value(), item.ExpiresAt().Format(time.RFC3339)) }) stopUpdate := cache.OnUpdate(func(ctx context.Context, item *ttlcache.Item[string, string]) { fmt.Printf("[UPDATE] key=%s new_value=%s\n", item.Key(), item.Value()) }) stopEvict := cache.OnEviction(func(ctx context.Context, reason ttlcache.EvictionReason, item *ttlcache.Item[string, string]) { switch reason { case ttlcache.EvictionReasonExpired: fmt.Printf("[EVICT] key=%s reason=expired\n", item.Key()) case ttlcache.EvictionReasonCapacityReached: fmt.Printf("[EVICT] key=%s reason=capacity\n", item.Key()) case ttlcache.EvictionReasonDeleted: fmt.Printf("[EVICT] key=%s reason=deleted\n", item.Key()) case ttlcache.EvictionReasonMaxCostExceeded: fmt.Printf("[EVICT] key=%s reason=max_cost\n", item.Key()) } }) go cache.Start() cache.Set("hello", "world", ttlcache.DefaultTTL) cache.Set("hello", "updated", ttlcache.DefaultTTL) cache.Delete("hello") // Unsubscribe all handlers stopInsert() stopUpdate() stopEvict() cache.Stop() ``` ``` -------------------------------- ### Cache.Set Source: https://context7.com/jellydator/ttlcache/llms.txt Inserts a new item or overwrites an existing one. You can specify item-specific TTLs or use predefined constants for default, no, or previous TTL. ```APIDOC ## Cache.Set — Insert or overwrite an item ### Description Inserts a new item or overwrites an existing one. Use `ttlcache.DefaultTTL` (0) to inherit the cache-level TTL, `ttlcache.NoTTL` (-1) to make the item immortal, or `ttlcache.PreviousOrDefaultTTL` (-2) to keep the existing item's TTL on update. ### Method `Set(key K, value V, ttl ttlcache.TTL)` ### Parameters - **key** (K): The key of the item to set. - **value** (V): The value of the item. - **ttl** (ttlcache.TTL): The time-to-live for the item. Can be `ttlcache.DefaultTTL`, `ttlcache.NoTTL`, `ttlcache.PreviousOrDefaultTTL`, or a `time.Duration`. ### Request Example ```go cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](10 * time.Minute), ) go cache.Start() def cache.Stop() // Use the cache-level TTL (10 min) item := cache.Set("session:abc", "user-42", ttlcache.DefaultTTL) fmt.Println(item.Value(), item.ExpiresAt()) // user-42 // Override with item-specific TTL cache.Set("token:xyz", "bearer-token", 30*time.Second) // Store permanently cache.Set("config:feature-flag", "enabled", ttlcache.NoTTL) // Update value but keep the existing TTL cache.Set("session:abc", "user-99", ttlcache.PreviousOrDefaultTTL) ``` ``` -------------------------------- ### Cache.Len, Keys, Items, Range, RangeBackwards Source: https://context7.com/jellydator/ttlcache/llms.txt Provides methods for introspecting the cache's contents. `Len` returns the count of non-expired items. `Keys` returns a slice of all non-expired keys. `Items` returns a snapshot map of all non-expired items. `Range` and `RangeBackwards` allow iterating through items in LRU order. ```APIDOC ## Cache.Len, Keys, Items, Range, RangeBackwards ### Description Provides methods for introspecting the cache's contents. `Len` returns the count of non-expired items. `Keys` returns a slice of all non-expired keys. `Items` returns a snapshot map of all non-expired items. `Range` and `RangeBackwards` allow iterating through items in LRU order. ### Methods - `Len() int`: Returns the number of non-expired items in the cache. - `Keys() []K`: Returns a slice containing all non-expired keys in the cache. - `Items() map[K]*Item[K, V]`: Returns a map containing a snapshot of all non-expired items. - `Range(func(item *Item[K, V]) bool)`: Iterates over non-expired items in Most Recently Used (MRU) to Least Recently Used (LRU) order. The iteration stops if the provided function returns `false`. - `RangeBackwards(func(item *Item[K, V]) bool)`: Iterates over non-expired items in Least Recently Used (LRU) to Most Recently Used (MRU) order. The iteration stops if the provided function returns `false`. ### Request Example ```go cache := ttlcache.New[string, int]() cache.Set("a", 1, ttlcache.NoTTL) cache.Set("b", 2, ttlcache.NoTTL) cache.Set("c", 3, ttlcache.NoTTL) fmt.Println(cache.Len()) // 3 fmt.Println(cache.Keys()) // [c b a] (LRU order varies) // Snapshot for k, item := range cache.Items() { fmt.Printf("%s=%d\n", k, item.Value()) } // Iterate and stop early cache.Range(func(item *ttlcache.Item[string, int]) bool { fmt.Println(item.Key(), item.Value()) return item.Value() != 2 // stop when we find value 2 }) // Iterate from least-recently-used end cache.RangeBackwards(func(item *ttlcache.Item[string, int]) bool { fmt.Println("LRU end:", item.Key()) return true }) ``` ### Response - `Len()`: Returns an integer representing the count of items. - `Keys()`: Returns a slice of keys. - `Items()`: Returns a map of keys to `Item` pointers. - `Range()` and `RangeBackwards()`: Do not return a value directly, but execute the provided callback function for each item. ``` -------------------------------- ### Cache.Delete, DeleteAll, DeleteExpired Source: https://context7.com/jellydator/ttlcache/llms.txt Provides methods to remove items from the cache. `Delete` removes a single item by key. `DeleteAll` evicts all items and triggers eviction handlers. `DeleteExpired` removes only items whose TTL has elapsed. ```APIDOC ## Cache.Delete, DeleteAll, DeleteExpired ### Description Provides methods to remove items from the cache. `Delete` removes a single item by key. `DeleteAll` evicts all items and triggers eviction handlers. `DeleteExpired` removes only items whose TTL has elapsed. ### Methods - `Delete(key K)`: Removes a single item identified by the key. - `DeleteAll()`: Removes all items from the cache. - `DeleteExpired()`: Removes all items that have expired based on their TTL. ### Parameters - `key` (K): The key of the item to delete (for `Delete` method). ### Request Example ```go cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](100 * time.Millisecond), ) cache.Set("a", "1", ttlcache.DefaultTTL) cache.Set("b", "2", ttlcache.NoTTL) cache.Set("c", "3", ttlcache.DefaultTTL) cache.Delete("b") // remove one time.Sleep(200 * time.Millisecond) cache.DeleteExpired() // remove "a" and "c" (expired) fmt.Println(cache.Len()) // 0 cache.Set("d", "4", ttlcache.NoTTL) cache.DeleteAll() // remove everything fmt.Println(cache.Len()) // 0 ``` ### Response These methods do not return a value. ``` -------------------------------- ### Cache Metrics Source: https://context7.com/jellydator/ttlcache/llms.txt Retrieve a snapshot of lifetime counters for cache operations including insertions, updates, hits, misses, and evictions. ```APIDOC ## Cache.Metrics — Observability counters Returns a `Metrics` snapshot with lifetime counters for insertions, updates, hits, misses, and evictions. ```go cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](1 * time.Minute), ) go cache.Start() def cache.Stop() cache.Set("k1", "v1", ttlcache.DefaultTTL) cache.Set("k2", "v2", ttlcache.DefaultTTL) cache.Get("k1") // hit cache.Get("k1") // hit cache.Get("k3") // miss m := cache.Metrics() fmt.Printf("insertions=%d updates=%d hits=%d misses=%d evictions=%d\n", m.Insertions, m.Updates, m.Hits, m.Misses, m.Evictions) // insertions=2 updates=0 hits=2 misses=1 evictions=0 ``` ``` -------------------------------- ### Check Key Existence Source: https://context7.com/jellydator/ttlcache/llms.txt The Has method checks if a key exists in the cache and has not expired. It does not extend the item's TTL. It returns true if the key exists and is valid, false otherwise. ```go cache := ttlcache.New[string, int]() cache.Set("x", 1, ttlcache.NoTTL) fmt.Println(cache.Has("x")) // true fmt.Println(cache.Has("y")) // false ``` -------------------------------- ### Introspect Cache Contents Source: https://context7.com/jellydator/ttlcache/llms.txt Provides methods to inspect the cache's state. Len returns the count of non-expired items. Keys returns all non-expired keys. Items returns a snapshot map of all items. Range and RangeBackwards iterate through items in LRU order. ```go cache := ttlcache.New[string, int]() cache.Set("a", 1, ttlcache.NoTTL) cache.Set("b", 2, ttlcache.NoTTL) cache.Set("c", 3, ttlcache.NoTTL) fmt.Println(cache.Len()) // 3 fmt.Println(cache.Keys()) // [c b a] (LRU order varies) // Snapshot for k, item := range cache.Items() { fmt.Printf("%s=%d\n", k, item.Value()) } // Iterate and stop early cache.Range(func(item *ttlcache.Item[string, int]) bool { fmt.Println(item.Key(), item.Value()) return item.Value() != 2 // stop when we find value 2 }) // Iterate from least-recently-used end cache.RangeBackwards(func(item *ttlcache.Item[string, int]) bool { fmt.Println("LRU end:", item.Key()) return true }) ``` -------------------------------- ### Cache.GetOrSet Source: https://context7.com/jellydator/ttlcache/llms.txt Atomically retrieves an item if it exists, or inserts it with a given value and options if it does not. Returns a boolean indicating if the item already existed. ```APIDOC ## Cache.GetOrSet — Atomic get-or-insert ### Description Retrieves an item if present; otherwise inserts it with the provided value and options. The boolean return value is `true` when the item already existed. The operation is atomic — no separate Get + Set race condition. ### Method `GetOrSet(key K, value V, opts ...ttlcache.Option[K, V])` ### Parameters - **key** (K): The key of the item. - **value** (V): The value to set if the item does not exist. - **opts** (...ttlcache.Option[K, V]): Optional configuration for the item, such as `ttlcache.WithTTL`. ### Response #### Success Response - **Item** (interface{ Key() K; Value() V; ExpiresAt() time.Time }): The retrieved or newly set item. - **found** (bool): `true` if the item already existed, `false` otherwise. ### Request Example ```go cache := ttlcache.New[string, int]( ttlcache.WithTTL[string, int](1 * time.Hour), ) // First call — item does not exist, it is created item, found := cache.GetOrSet("counter", 0, ttlcache.WithTTL[string, int](1*time.Hour)) fmt.Println(item.Value(), found) // 0 false // Second call — item exists, the existing one is returned item, found = cache.GetOrSet("counter", 99) fmt.Println(item.Value(), found) // 0 true ``` ``` -------------------------------- ### Access Item Metadata in TTLCache Source: https://context7.com/jellydator/ttlcache/llms.txt Cache operations return `*Item[K, V]`, which provides thread-safe accessors for metadata like Key, Value, TTL, ExpiresAt, Version, Cost, and IsExpired. ```go cache := ttlcache.New[string, float64]( ttlcache.WithTTL[string, float64](10 * time.Minute), ttlcache.WithVersion[string, float64](true), ) item := cache.Set("temperature", 23.5, ttlcache.DefaultTTL) fmt.Println(item.Key()) // temperature fmt.Println(item.Value()) // 23.5 fmt.Println(item.TTL()) // 10m0s fmt.Println(item.ExpiresAt()) // fmt.Println(item.Version()) // 0 fmt.Println(item.Cost()) // 0 (cost tracking not configured) fmt.Println(item.IsExpired()) // false ``` -------------------------------- ### Cache.GetOrSetFunc Source: https://context7.com/jellydator/ttlcache/llms.txt Atomically retrieves an item from the cache or sets it using a provided factory function if it's not found. The factory function is only invoked when the item is absent, making it suitable for expensive value constructions. ```APIDOC ## Cache.GetOrSetFunc ### Description Atomically retrieves an item from the cache or sets it using a provided factory function if it's not found. The factory function is only invoked when the item is absent, making it suitable for expensive value constructions. ### Method `GetOrSetFunc(key, factoryFunc, ttl ...Option[K, V]) (item *Item[K, V], found bool)` ### Parameters - `key` (K): The key of the item to retrieve or set. - `factoryFunc` (func() V): A function that produces the value to be set if the key is not found. - `ttl` ([]Option[K, V]): Optional TTL options for the item. ### Request Example ```go cache := ttlcache.New[string, []byte]( ttlcache.WithTTL[string, []byte](30 * time.Minute), ) item, found := cache.GetOrSetFunc("image:logo", func() []byte { // expensive: read from disk / fetch from remote storage data, _ := os.ReadFile("/assets/logo.png") return data }, ttlcache.WithTTL[string, []byte](30*time.Minute)) fmt.Printf("found=%v size=%d\n", found, len(item.Value())) ``` ### Response #### Success Response - `item` (*Item[K, V]): The retrieved or newly set cache item. - `found` (bool): True if the item was found in the cache, false otherwise. #### Response Example ```go // Assuming item was found or successfully set fmt.Printf("found=%v size=%d\n", found, len(item.Value())) ``` ``` -------------------------------- ### Cache.Touch Source: https://context7.com/jellydator/ttlcache/llms.txt Extends the Time-To-Live (TTL) of an existing cache item without retrieving or modifying its value. This is useful for keeping items like sessions alive from a separate heartbeat mechanism. ```APIDOC ## Cache.Touch ### Description Extends the Time-To-Live (TTL) of an existing cache item without retrieving or modifying its value. This is useful for keeping items like sessions alive from a separate heartbeat mechanism. ### Method `Touch(key K)` ### Parameters - `key` (K): The key of the item whose TTL should be extended. ### Request Example ```go cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](10 * time.Minute), ) cache.Set("session:42", "data", ttlcache.DefaultTTL) // Heartbeat — keep session alive without deserialising the value cache.Touch("session:42") ``` ### Response This method does not return a value. ``` -------------------------------- ### Delete Cache Items Source: https://context7.com/jellydator/ttlcache/llms.txt Provides methods to remove items from the cache. Delete removes a single item, DeleteAll evicts all items, and DeleteExpired removes only items that have passed their TTL. DeleteExpired is also called automatically by the cache's background goroutine. ```go cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](100 * time.Millisecond), ) cache.Set("a", "1", ttlcache.DefaultTTL) cache.Set("b", "2", ttlcache.NoTTL) cache.Set("c", "3", ttlcache.DefaultTTL) cache.Delete("b") // remove one time.Sleep(200 * time.Millisecond) cache.DeleteExpired() // remove "a" and "c" (expired) fmt.Println(cache.Len()) // 0 cache.Set("d", "4", ttlcache.NoTTL) cache.DeleteAll() // remove everything fmt.Println(cache.Len()) // 0 ``` -------------------------------- ### Atomic Get-or-Set with Lazy Value Construction Source: https://context7.com/jellydator/ttlcache/llms.txt Use GetOrSetFunc for atomic retrieval or setting of a cache item. The value is constructed lazily by a provided function only when the item is absent, which is efficient for expensive value constructions. You can specify a TTL for the newly set item. ```go cache := ttlcache.New[string, []byte]( ttlcache.WithTTL[string, []byte](30 * time.Minute), ) item, found := cache.GetOrSetFunc("image:logo", func() []byte { // expensive: read from disk / fetch from remote storage data, _ := os.ReadFile("/assets/logo.png") return data }, ttlcache.WithTTL[string, []byte](30*time.Minute)) fmt.Printf("found=%v size=%d\n", found, len(item.Value())) ``` -------------------------------- ### Cache.Has Source: https://context7.com/jellydator/ttlcache/llms.txt Checks if a key exists in the cache and if the corresponding item has not expired. This operation does not extend the item's Time-To-Live (TTL). ```APIDOC ## Cache.Has ### Description Checks if a key exists in the cache and if the corresponding item has not expired. This operation does not extend the item's Time-To-Live (TTL). ### Method `Has(key K) bool` ### Parameters - `key` (K): The key to check for existence. ### Request Example ```go cache := ttlcache.New[string, int]() cache.Set("x", 1, ttlcache.NoTTL) fmt.Println(cache.Has("x")) // true fmt.Println(cache.Has("y")) // false ``` ### Response #### Success Response - `bool`: True if the key exists and the item is not expired, false otherwise. #### Response Example ```go fmt.Println(cache.Has("x")) // true ``` ``` -------------------------------- ### Cache.GetAndDelete Source: https://context7.com/jellydator/ttlcache/llms.txt Atomically retrieves an item from the cache and immediately removes it. Returns `(nil, false)` if the item is not found. This is useful for scenarios like one-time tokens or processing tasks from a queue. ```APIDOC ## Cache.GetAndDelete ### Description Atomically retrieves an item from the cache and immediately removes it. Returns `(nil, false)` if the item is not found. This is useful for scenarios like one-time tokens or processing tasks from a queue. ### Method `GetAndDelete(key K) (item *Item[K, V], ok bool)` ### Parameters - `key` (K): The key of the item to retrieve and delete. ### Request Example ```go cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](5 * time.Minute), ) cache.Set("otp:user-7", "836492", 2*time.Minute) item, ok := cache.GetAndDelete("otp:user-7") if ok { fmt.Println("OTP:", item.Value()) // OTP: 836492 } // Key is now gone fmt.Println(cache.Has("otp:user-7")) // false ``` ### Response #### Success Response - `item` (*Item[K, V]): The retrieved cache item. - `ok` (bool): True if the item was found and deleted, false otherwise. #### Response Example ```go // If item was found and deleted fmt.Println("OTP:", item.Value()) // OTP: 836492 ``` ``` -------------------------------- ### Call Cached Endpoint with Curl Source: https://github.com/jellydator/ttlcache/blob/v3/examples/httpcache/README.md Use this curl command to interact with the cached HTTP endpoint. The first call to a new report name will be slow, while subsequent calls within the cache duration will be fast. ```bash curl 127.0.0.1:8080/reports/hello ``` -------------------------------- ### Extend Item TTL Without Retrieving Value Source: https://context7.com/jellydator/ttlcache/llms.txt The Touch method resets the expiration timestamp of an existing cache item without fetching its value. This is useful for maintaining sessions alive through a separate heartbeat mechanism without the overhead of deserializing the item's value. ```go cache := ttlcache.New[string, string]( ttlcache.WithTTL[string, string](10 * time.Minute), ) cache.Set("session:42", "data", ttlcache.DefaultTTL) // Heartbeat — keep session alive without deserialising the value cache.Touch("session:42") ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.