Documentation
¶
Overview ¶
Package data provides typed Redis hashes, sets, sorted sets and lists. Declare contracts once and bind them to an explicitly owned adapter. Constructors perform no I/O. These data structures are independent of cache invalidation and cache envelopes.
Index ¶
- Constants
- func IncrementField[K, F any](ctx context.Context, h Hash[K, F, int64], key K, field F, delta int64) (int64, error)
- func ValidateBatch(keys []Key) error
- func ValidateIndexRange(start, stop int64) error
- func ValidateScore(score float64) error
- type Backend
- type Config
- type End
- type Handle
- func (h Handle[K]) AdapterKey(ctx context.Context, input K) (Key, error)
- func (h Handle[K]) Count(ctx context.Context, key K) (uint64, error)
- func (h Handle[K]) Delete(ctx context.Context, key K) (bool, error)
- func (h Handle[K]) DeleteMany(ctx context.Context, keys ...K) (uint64, error)
- func (h Handle[K]) Exists(ctx context.Context, key K) (bool, error)
- func (h Handle[K]) Expire(ctx context.Context, key K, ttl cache.TTL) (bool, error)
- func (h Handle[K]) Name() Name
- func (h Handle[K]) Version() Version
- type Hash
- func (h Hash[K, F, V]) DeleteField(ctx context.Context, key K, field F) (bool, error)
- func (h Hash[K, F, V]) Get(ctx context.Context, key K, field F) (V, bool, error)
- func (h Hash[K, F, V]) GetAll(ctx context.Context, key K) ([]HashEntry[F, V], error)
- func (h Hash[K, F, V]) GetMany(ctx context.Context, key K, fields ...F) ([]value.Optional[V], error)
- func (h Hash[K, F, V]) Set(ctx context.Context, key K, field F, input V) (bool, error)
- type HashBackend
- type HashCounterBackend
- type HashDeclaration
- type HashEntry
- type HashReadBackend
- type Key
- type Kind
- type Limits
- type List
- func (l List[K, V]) PopBack(ctx context.Context, key K) (V, bool, error)
- func (l List[K, V]) PopFront(ctx context.Context, key K) (V, bool, error)
- func (l List[K, V]) Push(ctx context.Context, key K, values ...V) (uint64, error)
- func (l List[K, V]) PushFront(ctx context.Context, key K, values ...V) (uint64, error)
- func (l List[K, V]) Range(ctx context.Context, key K, start, stop int64) ([]V, error)
- func (l List[K, V]) Trim(ctx context.Context, key K, start, stop int64) error
- type ListBackend
- type ListDeclaration
- type Name
- type Order
- type ScoreRange
- type Scored
- type Set
- type SetBackend
- type SetDeclaration
- type SortedSet
- func (s SortedSet[K, V]) Add(ctx context.Context, key K, input V, score float64) (bool, error)
- func (s SortedSet[K, V]) CountByScore(ctx context.Context, key K, scores ScoreRange) (uint64, error)
- func (s SortedSet[K, V]) Increment(ctx context.Context, key K, input V, delta float64) (float64, error)
- func (s SortedSet[K, V]) Range(ctx context.Context, key K, window Window) ([]Scored[V], error)
- func (s SortedSet[K, V]) RangeByScore(ctx context.Context, key K, scores ScoreRange, window Window) ([]Scored[V], error)
- func (s SortedSet[K, V]) Rank(ctx context.Context, key K, input V, order Order) (uint64, bool, error)
- func (s SortedSet[K, V]) Remove(ctx context.Context, key K, input V) (bool, error)
- func (s SortedSet[K, V]) Score(ctx context.Context, key K, input V) (float64, bool, error)
- type SortedSetBackend
- type SortedSetDeclaration
- type Store
- type StoredField
- type StoredMember
- type Version
- type Window
Constants ¶
const ( MaxEntries = 4096 MaxReplyBytes = 16 << 20 MaxBatchKeys = 256 )
Variables ¶
This section is empty.
Functions ¶
func IncrementField ¶
func IncrementField[K, F any](ctx context.Context, h Hash[K, F, int64], key K, field F, delta int64) (int64, error)
IncrementField atomically adds a signed delta to an int64-valued hash field and returns the result. A missing field starts at zero; existing expiry is retained. A stored value that is not a canonical integer, or overflow, fails without mutation. It is a function because only int64 hashes support it.
func ValidateBatch ¶
ValidateBatch requires a canonical, bounded batch within one namespace.
func ValidateIndexRange ¶
ValidateIndexRange bounds list indices; negative values count from the tail.
func ValidateScore ¶
ValidateScore rejects NaN, which Redis cannot order.
Types ¶
type Backend ¶
type Backend interface {
// DataExists reports whether the declared data key exists.
DataExists(context.Context, Key) (bool, error)
// DataExpire changes an existing key's TTL without changing its contents.
DataExpire(context.Context, Key, cache.TTL) (bool, error)
// DataDeleteMany atomically deletes a canonical batch and returns the number of removed keys.
DataDeleteMany(context.Context, []Key) (uint64, error)
// DataCount returns collection cardinality within the supplied limits.
DataCount(context.Context, Key, Limits) (uint64, error)
}
Backend owns data entry operations. Validate every key and complete batch before mutation. DeleteMany is one atomic operation; error returns zero and may hide a completed remote write. Never retry uncertain mutations. The caller owns adapter lifecycle; stores borrow it. Expire preserves bytes, missing keys return false, and Forever returns true even for an already persistent key.
type Config ¶
type Config struct {
Namespace keyspace.Namespace
MaxDeclarations, MaxKeyBytes, MaxConcurrent, MaxBatchKeys int
Timeout time.Duration
Limits Limits
}
Config sets the namespace, operation admission, declaration capacity, and collection bounds.
func DefaultConfig ¶
DefaultConfig returns bounded store defaults for the supplied namespace.
type Handle ¶ added in v0.3.0
type Handle[K any] struct { // contains filtered or unexported fields }
Handle supplies shared operations for a bound Hash, Set, SortedSet or List. Declaration Bind methods construct the containers with an embedded Handle, promoting Name, Version, Exists, Expire, Count, Delete, DeleteMany and AdapterKey. Its zero value is unbound: Name and Version return zero values, and operations requiring a store return an error.
func (Handle[K]) AdapterKey ¶ added in v0.3.0
AdapterKey explicitly exports this declaration's resolved address for advanced Redis adapters. It preserves key typing and callback ownership; ordinary callers should prefer the typed Hash/Set operations.
func (Handle[K]) Count ¶ added in v0.3.0
Count returns the number of fields, members or elements at the resource key.
func (Handle[K]) Delete ¶ added in v0.3.0
Delete removes the resource key and reports whether it existed.
func (Handle[K]) DeleteMany ¶ added in v0.3.0
DeleteMany validates all encoded keys before one atomic batch. The input bound applies before deduplication; returned count excludes duplicates and missing keys.
func (Handle[K]) Exists ¶ added in v0.3.0
Exists checks the key's declared Redis type, without decoding payloads.
func (Handle[K]) Expire ¶ added in v0.3.0
Expire changes expiry without replacing data. New hash/set writes are persistent and later writes retain TTL. Setting expiry is a separate explicit operation; a write followed by Expire does not claim atomic initialization with expiry.
type Hash ¶
Hash is a typed collection of fields at each resource key. Point writes preserve expiry and return whether a field was newly inserted. Values are canonical JSON snapshots; use DTOs that explicitly select model getters for presentation data.
func (Hash[K, F, V]) DeleteField ¶
DeleteField removes a field and reports whether it existed.
func (Hash[K, F, V]) Get ¶
Get decodes a field value and distinguishes a missing field from a stored JSON null.
func (Hash[K, F, V]) GetAll ¶
GetAll returns every field of one resource, ordered by encoded field bytes. The declaration must supply WithFieldDecoder; each decoded field must encode back to its stored bytes. Cardinality and reply bounds are checked before the adapter transfers payloads. A missing hash returns an empty slice.
func (Hash[K, F, V]) GetMany ¶
func (h Hash[K, F, V]) GetMany(ctx context.Context, key K, fields ...F) ([]value.Optional[V], error)
GetMany reads several fields of one resource in one atomic operation. The result has one entry per requested field, in input order; missing fields are unset. Repeated fields repeat their value. The field count is bounded by Limits.Entries and the returned payload by Limits.ReplyBytes.
type HashBackend ¶
type HashBackend interface {
// HashGet returns an encoded field value and distinguishes a missing field.
HashGet(context.Context, Key, string, Limits) (string, bool, error)
// HashSet stores an encoded field value and reports whether the field was newly inserted.
HashSet(context.Context, Key, string, string, Limits) (bool, error)
// HashDelete removes a field and reports whether it existed.
HashDelete(context.Context, Key, string, Limits) (bool, error)
}
HashBackend supplies point operations. Get distinguishes missing from JSON null. Set returns true only for a new field. Writes retain existing key TTL; a newly created key is persistent. Deleting the last field removes the key. Adapters validate kind, cardinality and requested field/value sizes before I/O or mutation. Stored values are opaque bytes; typed handles validate their JSON.
type HashCounterBackend ¶
type HashCounterBackend interface {
// HashIncrement atomically adds delta to an integer field, starting a missing field at zero.
HashIncrement(context.Context, Key, string, int64, Limits) (int64, error)
}
HashCounterBackend optionally adds an exact signed delta to one integer field. A missing field starts at zero. Non-integer values, overflow and growth past the cardinality bound fail without mutation. Writes retain the key's expiry.
type HashDeclaration ¶
type HashDeclaration[K, F, V any] struct { // contains filtered or unexported fields }
HashDeclaration preserves the resource key, field identity and value types. Keep one declaration per name/version; increment version for schema changes.
func DefineHash ¶
func DefineHash[K, F, V any](name Name, version Version, keys keyspace.Codec[K], fields keyspace.Codec[F]) HashDeclaration[K, F, V]
DefineHash creates a typed hash declaration without validating or binding it.
func (HashDeclaration[K, F, V]) Bind ¶
func (d HashDeclaration[K, F, V]) Bind(s *Store) (Hash[K, F, V], error)
Bind validates the declaration and hash capability and claims its name and version without I/O.
func (HashDeclaration[K, F, V]) WithFieldDecoder ¶
func (d HashDeclaration[K, F, V]) WithFieldDecoder(parse func(string) (F, error)) HashDeclaration[K, F, V]
WithFieldDecoder adds the inverse of the field codec, which Hash.GetAll needs to return typed fields. Every decoded field must encode back to the exact stored bytes. The returned declaration keeps the same name/version identity.
type HashEntry ¶
type HashEntry[F, V any] struct { Field F Value V }
HashEntry is one typed field and value read by GetAll.
type HashReadBackend ¶
type HashReadBackend interface {
// HashGetMany returns optional encoded values in requested field order.
HashGetMany(context.Context, Key, []string, Limits) ([]value.Optional[string], error)
// HashGetAll returns every encoded field and value ordered by field bytes.
HashGetAll(context.Context, Key, Limits) ([]StoredField, error)
}
HashReadBackend optionally reads several fields in one operation. GetMany returns one entry per requested field, in order; a missing field is unset. GetAll returns every field sorted by field bytes after checking cardinality and the reply budget before transferring payloads.
type Key ¶
type Key struct {
// contains filtered or unexported fields
}
Key is an opaque adapter address, separate from cache and other feature keys. Application calls preserve their concrete resource types through Hash, Set, SortedSet or List. The kind is part of the address and matches Redis TYPE.
func NewKey ¶
func NewKey(namespace keyspace.Namespace, name Name, version Version, kind Kind, logical string) (Key, error)
NewKey constructs and validates a versioned collection address for adapter use.
type Kind ¶
type Kind string
Kind selects the native Redis collection type encoded into a data address.
type Limits ¶
type Limits struct{ Entries, FieldBytes, ValueBytes, ReplyBytes int }
Limits bound each collection and each encoded field/value. The cardinality times value bound must fit ReplyBytes, so every framework-written set can be enumerated within that reply budget. External writes must obey the same schema. Server allocations while inspecting externally oversized members are not bounded.
func DefaultLimits ¶
func DefaultLimits() Limits
DefaultLimits returns bounds for 1,024 entries, 1 KiB fields, 4 KiB values, and a 4 MiB reply.
func (Limits) Validate ¶
Validate checks positive collection bounds and ensures all maximum-sized values fit the reply budget.
func (Limits) ValidateField ¶
ValidateField returns fault.Invalid for an empty field or one exceeding FieldBytes.
func (Limits) ValidateValue ¶
ValidateValue returns fault.Invalid for an empty value or one exceeding ValueBytes.
type List ¶
List preserves resource/element types in insertion order. Its length is bounded by Limits.Entries: a push that would exceed it inserts nothing. New lists persist; writes retain TTL. Removing the last element removes it.
func (List[K, V]) PopBack ¶
PopBack removes and returns the tail element, or false for an empty list.
func (List[K, V]) PopFront ¶
PopFront removes and returns the head element, or false for an empty list.
func (List[K, V]) PushFront ¶
PushFront inserts values at the head one at a time, like Redis LPUSH, so the last argument becomes the first element. It returns the new length.
type ListBackend ¶
type ListBackend interface {
// ListPush inserts values at the selected end and returns the new length.
ListPush(context.Context, Key, []string, End, Limits) (uint64, error)
// ListPop removes a size-checked element from the selected end and distinguishes absence.
ListPop(context.Context, Key, End, Limits) (string, bool, error)
// ListRange returns elements from start through stop inclusive, with negative indices relative to the tail.
ListRange(context.Context, Key, int64, int64, Limits) ([]string, error)
// ListTrim retains elements from start through stop inclusive, with negative indices relative to the tail.
ListTrim(context.Context, Key, int64, int64, Limits) error
}
ListBackend supplies bounded list operations. Push checks the resulting length against Limits.Entries before inserting anything and returns the new length. Pop checks the element's size before removing it. Range/Trim use Redis index semantics (negative indices count from the tail). Writes preserve TTL, new lists are persistent and removing the last element removes the key.
type ListDeclaration ¶
type ListDeclaration[K, V any] struct { // contains filtered or unexported fields }
ListDeclaration preserves resource and element types. Elements are canonical JSON snapshots in insertion order; duplicates are allowed.
func DefineList ¶
DefineList creates a typed list declaration without validating or binding it.
type Order ¶
type Order uint8
Order selects ascending or descending score order for sorted-set reads.
type ScoreRange ¶
ScoreRange bounds sorted-set scores, inclusive unless excluded. Use math.Inf for an open end; AllScores selects every score. NaN is invalid.
func Between ¶
func Between(min, max float64) ScoreRange
Between selects scores from min through max inclusive.
func (ScoreRange) Validate ¶
func (r ScoreRange) Validate() error
Validate returns fault.Invalid for NaN bounds or a minimum above the maximum.
type Set ¶
Set preserves resource/member types and canonical JSON membership identity. Members returns an owned native slice ordered by encoded JSON bytes. This is deterministic, not numeric/domain sorting. New sets persist; writes retain TTL.
type SetBackend ¶
type SetBackend interface {
// SetAdd inserts an encoded member and reports whether it was new.
SetAdd(context.Context, Key, string, Limits) (bool, error)
// SetRemove removes an encoded member and reports whether it existed.
SetRemove(context.Context, Key, string, Limits) (bool, error)
// SetContains tests exact encoded member equality.
SetContains(context.Context, Key, string, Limits) (bool, error)
// SetMembers returns owned member strings in byte order within the reply limits.
SetMembers(context.Context, Key, Limits) ([]string, error)
}
SetBackend uses exact encoded member equality. Writes preserve TTL, new sets are persistent, and removing the last member removes the key. Members returns sorted, unique, owned strings within the bounds, including an empty slice for missing sets. Every method validates type and cardinality before mutation.
type SetDeclaration ¶
type SetDeclaration[K, V any] struct { // contains filtered or unexported fields }
SetDeclaration preserves resource and member types. Members use canonical JSON equality, rather than Go pointer identity or the spelling of numeric JSON.
type SortedSet ¶
SortedSet preserves resource/member types with a float64 score per member. Members use canonical JSON identity (as in Set). Reads order by score, then by encoded member bytes. New sorted sets persist; writes retain TTL.
func (SortedSet[K, V]) Add ¶
Add inserts or re-scores a member and reports whether it was newly added. A full sorted set can re-score existing members but rejects growth.
func (SortedSet[K, V]) CountByScore ¶
func (s SortedSet[K, V]) CountByScore(ctx context.Context, key K, scores ScoreRange) (uint64, error)
CountByScore counts members whose scores fall within scores.
func (SortedSet[K, V]) Increment ¶
func (s SortedSet[K, V]) Increment(ctx context.Context, key K, input V, delta float64) (float64, error)
Increment atomically adds delta to a member's score (a missing member starts at zero) and returns the new score. A NaN result fails without mutation.
func (SortedSet[K, V]) RangeByScore ¶
func (s SortedSet[K, V]) RangeByScore(ctx context.Context, key K, scores ScoreRange, window Window) ([]Scored[V], error)
RangeByScore returns members whose scores fall within scores, ordered and limited by window (Window.Offset skips matching members).
func (SortedSet[K, V]) Rank ¶
func (s SortedSet[K, V]) Rank(ctx context.Context, key K, input V, order Order) (uint64, bool, error)
Rank returns a member's zero-based position in order, or false when missing.
type SortedSetBackend ¶
type SortedSetBackend interface {
// SortedSetAdd inserts or re-scores a member and reports whether it was new.
SortedSetAdd(context.Context, Key, string, float64, Limits) (bool, error)
// SortedSetIncrement atomically adds delta to a member's score, starting a missing member at zero.
SortedSetIncrement(context.Context, Key, string, float64, Limits) (float64, error)
// SortedSetRemove removes a member and reports whether it existed.
SortedSetRemove(context.Context, Key, string, Limits) (bool, error)
// SortedSetScore returns a member's score and distinguishes absence.
SortedSetScore(context.Context, Key, string, Limits) (float64, bool, error)
// SortedSetRank returns a member's zero-based rank in the selected order and distinguishes absence.
SortedSetRank(context.Context, Key, string, Order, Limits) (uint64, bool, error)
// SortedSetRange returns members and scores within a bounded rank window.
SortedSetRange(context.Context, Key, Window, Limits) ([]StoredMember, error)
// SortedSetRangeByScore returns matching members and scores within a bounded window.
SortedSetRangeByScore(context.Context, Key, ScoreRange, Window, Limits) ([]StoredMember, error)
// SortedSetCountByScore counts members matching the score range.
SortedSetCountByScore(context.Context, Key, ScoreRange, Limits) (uint64, error)
}
SortedSetBackend orders members by float64 score, then by member bytes, as Redis does. Scores are never NaN. Writes preserve TTL, new sorted sets are persistent and removing the last member removes the key. Range replies are bounded by Window.Count, Limits.Entries and Limits.ReplyBytes before payloads are returned. Every method validates type and cardinality before mutation.
type SortedSetDeclaration ¶
type SortedSetDeclaration[K, V any] struct { // contains filtered or unexported fields }
SortedSetDeclaration preserves resource and member types. Members use canonical JSON identity, as in sets, and each carries a float64 score.
func DefineSortedSet ¶
func DefineSortedSet[K, V any](name Name, version Version, keys keyspace.Codec[K]) SortedSetDeclaration[K, V]
DefineSortedSet creates a typed sorted-set declaration without validating or binding it.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store borrows its adapter. Key/JSON/adapter callbacks retain an operation slot until they actually exit, including after cancellation. No detached retries or implicit fallback run. Inputs must stay unchanged until their operation returns.
type StoredField ¶
type StoredField struct{ Field, Value string }
StoredField is one adapter hash field and its encoded value.
type StoredMember ¶
StoredMember is one adapter sorted-set member with its score.