126 lines
6.2 KiB
Markdown
126 lines
6.2 KiB
Markdown
# API Reference
|
|
|
|
## Constructor
|
|
|
|
```go
|
|
hot.NewHotCache[K comparable, V any](algorithm hot.EvictionAlgorithm, capacity int) *HotCacheBuilder[K, V]
|
|
```
|
|
|
|
**Algorithm constants:**
|
|
|
|
| Constant | Algorithm |
|
|
| -------------- | -------------------------------------- |
|
|
| `hot.LRU` | Least Recently Used |
|
|
| `hot.LFU` | Least Frequently Used |
|
|
| `hot.TinyLFU` | TinyLFU with frequency decay |
|
|
| `hot.WTinyLFU` | Weighted TinyLFU (recommended default) |
|
|
| `hot.S3FIFO` | Segmented Small-Size FIFO |
|
|
| `hot.ARC` | Adaptive Replacement Cache |
|
|
| `hot.TwoQueue` | Two-Queue |
|
|
| `hot.SIEVE` | SIEVE eviction |
|
|
| `hot.FIFO` | First In, First Out |
|
|
|
|
## Builder Methods
|
|
|
|
Call these on the builder returned by `NewHotCache()`, then finalize with `.Build()`.
|
|
|
|
| Method | Description |
|
|
| --- | --- |
|
|
| `WithTTL(ttl time.Duration)` | Default expiration for all entries |
|
|
| `WithJitter(lambda float64, upperBound time.Duration)` | Randomize TTL by +/-lambda (capped at upperBound) to prevent thundering herd |
|
|
| `WithJanitor()` | Start background goroutine to evict expired entries. Mutually exclusive with `WithoutLocking()` |
|
|
| `WithLoaders(loaders ...Loader[K, V])` | Chain of loader functions for cache misses. Execute sequentially; later loaders receive only unmapped keys |
|
|
| `WithRevalidation(stale time.Duration, loaders ...Loader[K, V])` | Enable stale-while-revalidate. After TTL, entries become stale and trigger async refresh. Hard-expired after `stale` duration |
|
|
| `WithRevalidationErrorPolicy(policy)` | `hot.KeepOnError` (keep stale value) or `hot.DropOnError` (drop on refresh failure) |
|
|
| `WithMissingCache(algorithm, capacity)` | Dedicated cache for missing keys (independent eviction) |
|
|
| `WithMissingSharedCache()` | Store missing keys in the main cache |
|
|
| `WithSharding(shards uint64, hasher Hasher[K])` | Split into N shards to reduce lock contention. Use powers of 2 |
|
|
| `WithCopyOnRead(fn func(V) V)` | Clone values on retrieval to prevent external mutation |
|
|
| `WithCopyOnWrite(fn func(V) V)` | Clone values on storage to capture snapshots |
|
|
| `WithPrometheusMetrics(cacheName string)` | Enable Prometheus metrics collection |
|
|
| `WithEvictionCallback(fn func(K, V))` | Synchronous callback on eviction |
|
|
| `WithoutLocking()` | Disable mutexes. Single-goroutine access only. Mutually exclusive with `WithJanitor()` |
|
|
| `WithWarmUp(fn func() (map[K]V, []K, error))` | Pre-populate cache on build. Returns values + missing keys + error |
|
|
| `WithWarmUpWithTimeout(timeout, fn)` | Same as WarmUp with timeout protection |
|
|
| `Build()` | Finalize and return `*HotCache[K, V]` |
|
|
|
|
## Read Operations
|
|
|
|
| Method | Signature | Behavior |
|
|
| --- | --- | --- |
|
|
| `Get` | `(key K) (V, bool, error)` | Value, found, loader error. Triggers loaders on miss |
|
|
| `GetWithLoaders` | `(key K, loaders ...Loader[K, V]) (V, bool, error)` | Per-call loader override |
|
|
| `GetMany` | `(keys []K) (map[K]V, []K, error)` | Batch get. Returns found map + missing keys + error |
|
|
| `GetManyWithLoaders` | `(keys []K, loaders ...Loader[K, V]) (map[K]V, []K, error)` | Batch with loader override |
|
|
| `MustGet` | `(key K) (V, bool)` | Panics on loader error |
|
|
| `MustGetWithLoaders` | `(key K, loaders ...Loader[K, V]) (V, bool)` | Panics on loader error |
|
|
| `MustGetMany` | `(keys []K) (map[K]V, []K)` | Panics on error |
|
|
| `MustGetManyWithLoaders` | `(keys []K, loaders ...Loader[K, V]) (map[K]V, []K)` | Panics on error |
|
|
| `Peek` | `(key K) (V, bool)` | Read without side effects: no loaders, ignores expiration |
|
|
| `PeekMany` | `(keys []K) (map[K]V, []K)` | Batch peek |
|
|
| `Has` | `(key K) bool` | Key existence check without triggering loaders |
|
|
| `HasMany` | `(keys []K) map[K]bool` | Batch existence check |
|
|
| `Keys` | `() []K` | All keys with values (excludes missing entries) |
|
|
| `Values` | `() []V` | All values |
|
|
| `All` | `() map[K]V` | Key-value snapshot |
|
|
| `Range` | `(fn func(K, V) bool)` | Iterate. Return false to stop |
|
|
| `Len` | `() int` | Total item count |
|
|
| `Capacity` | `() (int, int)` | Main capacity, missing cache capacity |
|
|
| `Algorithm` | `() (string, string)` | Main algorithm name, missing algorithm name |
|
|
|
|
## Write Operations
|
|
|
|
| Method | Signature | Description |
|
|
| --- | --- | --- |
|
|
| `Set` | `(key K, value V)` | Set with default TTL |
|
|
| `SetWithTTL` | `(key K, value V, ttl time.Duration)` | Set with custom TTL |
|
|
| `SetMany` | `(items map[K]V)` | Batch set with default TTL |
|
|
| `SetManyWithTTL` | `(items map[K]V, ttl time.Duration)` | Batch set with custom TTL |
|
|
| `SetMissing` | `(key K)` | Mark key as non-existent. Requires `WithMissingCache()` or `WithMissingSharedCache()` |
|
|
| `SetMissingWithTTL` | `(key K, ttl time.Duration)` | Mark missing with custom TTL |
|
|
| `SetMissingMany` | `(keys []K)` | Batch mark as missing |
|
|
| `SetMissingManyWithTTL` | `(keys []K, ttl time.Duration)` | Batch mark missing with custom TTL |
|
|
|
|
## Maintenance Operations
|
|
|
|
| Method | Signature | Description |
|
|
| --- | --- | --- |
|
|
| `Delete` | `(key K) bool` | Remove single key. Returns true if existed |
|
|
| `DeleteMany` | `(keys []K) map[K]bool` | Batch delete. Returns existence map |
|
|
| `Purge` | `()` | Clear all entries |
|
|
| `WarmUp` | `(fn func() (map[K]V, []K, error)) error` | Pre-populate cache at runtime |
|
|
| `Janitor` | `()` | Start background expiration cleanup |
|
|
| `StopJanitor` | `()` | Stop background cleanup goroutine |
|
|
|
|
## Loader Type
|
|
|
|
```go
|
|
type Loader[K comparable, V any] func(keys []K) (found map[K]V, err error)
|
|
```
|
|
|
|
**Chain semantics:**
|
|
|
|
- Loaders execute sequentially in provided order
|
|
- Each loader receives only **unmapped keys** from previous loaders
|
|
- Later loader values **overwrite** earlier values for the same key
|
|
- Any loader error stops the chain and returns `(nil, err)`
|
|
- Built-in singleflight deduplication: concurrent `Get()` calls for the same key share one loader invocation
|
|
|
|
## Hasher Type (for Sharding)
|
|
|
|
```go
|
|
type Hasher[K any] func(key K) uint64
|
|
```
|
|
|
|
## Prometheus Integration
|
|
|
|
`*HotCache` implements `prometheus.Collector`. Register it to expose metrics:
|
|
|
|
```go
|
|
cache := hot.NewHotCache[string, *User](hot.WTinyLFU, 10_000).
|
|
WithPrometheusMetrics("user_cache").
|
|
Build()
|
|
|
|
prometheus.MustRegister(cache)
|
|
```
|