Documentation
¶
Index ¶
- func IsLive(expiration time.Time) bool
- func IsLiveAt(expiration, now time.Time) bool
- type Cache
- func (c *Cache[S, T]) Clear()
- func (c *Cache[S, T]) Count() int
- func (c *Cache[S, T]) Delete(key S) bool
- func (c *Cache[S, T]) DeleteMany(keys []S) []S
- func (c *Cache[S, T]) Flush() int
- func (c *Cache[S, T]) Get(key S) (T, bool)
- func (c *Cache[S, T]) Has(key S) bool
- func (c *Cache[S, T]) Put(key S, value T)
- func (c *Cache[S, T]) PutWithExpiration(key S, value T, expiration time.Time)
- func (c *Cache[S, T]) PutWithTTL(key S, value T, ttl time.Duration)
- func (c *Cache[S, T]) Range(fn func(key S, value T, expiration time.Time) bool)
- func (c *Cache[S, T]) SetOnEvict(fn func(S))
- func (c *Cache[S, T]) SetOnEvictMany(fn func([]S))
- func (c *Cache[S, T]) UpsertWithExpiration(key S, value T, expiration time.Time) (physicallyExisted bool)
- func (c *Cache[S, T]) Watch(ctx context.Context, interval time.Duration)
- type LoadingCache
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsLive ¶ added in v0.1.1
IsLive is the IsLiveAt shorthand that samples time.Now() once per call.
func IsLiveAt ¶ added in v0.1.1
IsLiveAt reports whether an expiration deadline is still in the future relative to now. It centralises the "no expiration" sentinel handling shared across the vertex cache, the edge cache, and any future expiring store. Two values are treated as "never expires":
- Go zero time (`time.Time{}`, year 1) — the documented sentinel for "no expiration" used by service.validateExpiration and the proto contract (`Vertex.expiration` / `Edge.expiration` are optional).
- Unix epoch or earlier (`expiration.Unix() <= 0`) — `(*timestamppb. Timestamp)(nil).AsTime()` returns `time.Unix(0,0).UTC()`, NOT Go zero, so the cache used to silently treat every PutVertex without an expiration as already-expired (issue #250).
Any positive future deadline behaves as before: live until now passes it.
Types ¶
type Cache ¶
type Cache[S comparable, T any] struct { // contains filtered or unexported fields }
func (*Cache[S, T]) Clear ¶
func (c *Cache[S, T]) Clear()
Clear removes every entry. When an eviction callback is installed it is invoked once after c.mu has been released — the batch hook with all removed keys, else the per-key hook once per key. Keys are reported in unspecified order.
func (*Cache[S, T]) Delete ¶
Delete removes the entry for key. It returns true if the key was present (and therefore removed by this call), false otherwise. When the key was present and an eviction callback is installed, it fires once after c.mu is released (the batch hook with a one-element slice, else the per-key hook).
func (*Cache[S, T]) DeleteMany ¶ added in v0.11.0
func (c *Cache[S, T]) DeleteMany(keys []S) []S
DeleteMany removes every supplied key that is present, under a single c.mu critical section, and returns the keys actually removed (those present at call time) in unspecified order. Absent keys are skipped and not reported; duplicate keys are reported at most once. The eviction callback fires once after c.mu is released — the batch hook with the whole evicted slice when installed, else the per-key hook once per removed key — so a layered cache amortizes its index cleanup over one pass (#738).
func (*Cache[S, T]) Flush ¶
Flush evicts every entry whose TTL has passed. It returns the number of entries removed so callers (e.g. server-side TTL metrics) can record expiration counts without scanning the cache again. When an eviction callback is installed it is invoked once after c.mu has been released — the batch hook with the whole expired set, else the per-key hook once per key — so a layered cache cleans its side indexes in one pass (#738).
func (*Cache[S, T]) PutWithExpiration ¶
func (*Cache[S, T]) PutWithTTL ¶
func (*Cache[S, T]) Range ¶ added in v0.1.1
Range invokes fn for every live (non-expired) entry. fn returns false to stop iteration early; the boolean return mirrors the iter.Seq2 contract callers may already be wired against. Range takes c.mu.RLock for the duration of the walk, so fn MUST NOT call back into the same Cache (which would acquire c.mu.Lock and deadlock with the reader-priority blockage described in #202). The intended consumer is the replication snapshot path (#184), which iterates under the GraphCache write lock where this constraint is trivially satisfied.
func (*Cache[S, T]) SetOnEvict ¶ added in v0.1.1
func (c *Cache[S, T]) SetOnEvict(fn func(S))
SetOnEvict installs (or clears, when nil) a callback invoked once per key removed by Delete, Clear, or Flush. The callback fires after c.mu has been released, so it may re-enter the same Cache without deadlocking. It is invoked inline on the caller's goroutine, so it must not block.
Eviction notifications enable layered caches (e.g. GraphCache wiring a shared vertex-id dictionary) to release per-entry resources without scanning the cache each tick.
func (*Cache[S, T]) SetOnEvictMany ¶ added in v0.11.0
func (c *Cache[S, T]) SetOnEvictMany(fn func([]S))
SetOnEvictMany installs (or clears, when nil) a batch eviction callback invoked once with the full slice of keys removed by a Delete, DeleteMany, Clear, or Flush call. When installed it takes precedence over the per-key SetOnEvict hook (the per-key hook is not also called), so install exactly one of the two. Like the per-key hook it fires after c.mu has been released, so it may re-enter the same Cache without deadlocking, and it must not block. The slice is owned by the callback for the duration of the call only.
func (*Cache[S, T]) UpsertWithExpiration ¶ added in v0.11.0
func (c *Cache[S, T]) UpsertWithExpiration(key S, value T, expiration time.Time) (physicallyExisted bool)
UpsertWithExpiration stores value for key like PutWithExpiration and reports whether an entry for key was PHYSICALLY present beforehand, regardless of whether that entry had already expired. It exists so layered callers can detect a true first insert in a single lock cycle (vs. a Has()+Put pair, two cycles) AND so an expired-but-not-yet-flushed slot is correctly treated as "already present" — Has() reports such a slot as absent, which would make a caller re-run first-insert side effects (e.g. interning the key again) on a slot that was never released, inflating bookkeeping (#739).
type LoadingCache ¶
type LoadingCache[S comparable, T any] struct { // contains filtered or unexported fields }
func NewLoadingCache ¶
func NewLoadingCache[S comparable, T any](ctx context.Context, loader function.Loader[S, T], defaultTTL time.Duration) *LoadingCache[S, T]
func (*LoadingCache[S, T]) Get ¶
func (c *LoadingCache[S, T]) Get(key S) (T, bool)
func (*LoadingCache[S, T]) Set ¶
func (c *LoadingCache[S, T]) Set(key S, value T)
func (*LoadingCache[S, T]) SetWithTTL ¶
func (c *LoadingCache[S, T]) SetWithTTL(key S, value T, ttl time.Duration)