Documentation
¶
Overview ¶
Package memstore provides a generic, thread-safe, keyed in-memory store with optional buffered write-behind persistence. The stored content type, its validation, and its persisted encoding (the "flavor") live with the module that manages the data — this package only owns concurrency, write policy, pruning, rehydration, and flush batching.
Index ¶
- type Persistence
- type Store
- func (s *Store[K, V]) Clear()
- func (s *Store[K, V]) Delete(key K)
- func (s *Store[K, V]) Entries() map[K]V
- func (s *Store[K, V]) Flush() error
- func (s *Store[K, V]) Get(key K) (V, bool)
- func (s *Store[K, V]) Has(key K) bool
- func (s *Store[K, V]) Len() int
- func (s *Store[K, V]) Prune(drop func(key K) bool) int
- func (s *Store[K, V]) Put(key K, value V) bool
- func (s *Store[K, V]) SetPersistence(ctx context.Context, p Persistence[K, V], log logrus.FieldLogger)
- func (s *Store[K, V]) Stop()
- func (s *Store[K, V]) Values() []V
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Persistence ¶
type Persistence[K comparable, V any] interface { Load() (map[K]V, error) PersistBatch(upserts map[K]V, deletes []K) error }
Persistence adapts a store to a backing table. Load is called once when the adapter is attached; PersistBatch is called from the store's flush loop with everything that changed since the last flush (upserts + deletions) and must apply the batch in a single transaction. Best-effort: on error the store logs and retries the same batch on the next flush.
type Store ¶
type Store[K comparable, V any] struct { // contains filtered or unexported fields }
Store is a generic, thread-safe, keyed in-memory store with a configurable write policy (last-write-wins or keep-existing) and optional buffered write-behind persistence. Writers never touch the persistence backend on their hot path; changes are tracked in dirty/deleted sets drained by the store's own flush loop.
func New ¶
func New[K comparable, V any]() *Store[K, V]
New creates a store with the last-write-wins policy: Put always replaces.
func NewKeepExisting ¶
func NewKeepExisting[K comparable, V any]() *Store[K, V]
NewKeepExisting creates a store with the first-write-wins policy: Put is rejected when the key is already present.
func (*Store[K, V]) Clear ¶
func (s *Store[K, V]) Clear()
Clear removes all entries, marking every deletion for the next flush.
func (*Store[K, V]) Delete ¶
func (s *Store[K, V]) Delete(key K)
Delete removes key from the store and marks the deletion for the next flush. No-op when the key is absent.
func (*Store[K, V]) Entries ¶
func (s *Store[K, V]) Entries() map[K]V
Entries returns a copy of the stored entries; mutating the returned map does not affect the store.
func (*Store[K, V]) Flush ¶
Flush synchronously persists all pending changes in one batch. On failure the batch is re-marked and retried on the next flush. No-op when no persistence is attached or nothing is pending.
func (*Store[K, V]) Prune ¶
Prune removes every key for which drop returns true, marking the deletions for the next flush, and returns the number of removed entries. The drop predicate is called with the store lock held and must not call back into the store.
func (*Store[K, V]) Put ¶
Put stores value under key. With the keep-existing policy it returns false and leaves the store untouched when the key is already present; otherwise it returns true.
func (*Store[K, V]) SetPersistence ¶
func (s *Store[K, V]) SetPersistence(ctx context.Context, p Persistence[K, V], log logrus.FieldLogger)
SetPersistence attaches the persistence adapter, rehydrates the store via Load() (loaded entries never overwrite in-memory ones written before attach), and starts the flush loop. Entries written before attach are marked dirty so they reach the backing table on the first flush. Attach at most once; a second call is ignored with a warning.