Documentation
¶
Overview ¶
Package lww implements last-write-wins CRDT collections.
The HLC tag is the complete conflict-resolution rule: a higher tag wins. Therefore callers that reuse a replica ID must persist ClockState before a restart, just as they do for OR-Set.
Index ¶
- Constants
- Variables
- func MapFrameType() crdt.FrameType
- func SetFrameType() crdt.FrameType
- type ElementCodec
- type Map
- func NewMap(replicaID string) (*Map, error)
- func NewMapFromClock(state clock.State) (*Map, error)
- func NewMapFromClockWithOptions(state clock.State, options MapOptions) (*Map, error)
- func NewMapFromSnapshot(saved snapshot.Snapshot) (*Map, error)
- func NewMapFromSnapshotWithOptions(saved snapshot.Snapshot, options MapOptions) (*Map, error)
- func NewMapWithOptions(replicaID string, options MapOptions) (*Map, error)
- func (m *Map) ApplyDelta(delta MapDelta) error
- func (m *Map) ClockState() clock.State
- func (m *Map) CompactTombstones(tags []crdt.Tag) (int, error)
- func (m *Map) Delete(key string) error
- func (m *Map) DeleteWithDelta(key string) (MapDelta, error)
- func (m *Map) EntryCount() int
- func (m *Map) EntryKeys() []string
- func (m *Map) Frontier() map[string]crdt.Tag
- func (m *Map) Get(key string) ([]byte, bool)
- func (m *Map) HasEntry(key string) bool
- func (m *Map) Keys() []string
- func (m *Map) MarshalBinary() ([]byte, error)
- func (m *Map) MarshalBinaryWithClockState() ([]byte, clock.State, error)
- func (m *Map) MarshalJSON() ([]byte, error)
- func (m *Map) Merge(other *Map) error
- func (m *Map) Set(key string, value []byte) error
- func (m *Map) SetWithDelta(key string, value []byte) (MapDelta, error)
- func (m *Map) Snapshot(frontier map[string]crdt.Tag) (snapshot.Snapshot, error)
- func (m *Map) SnapshotCurrentState() (snapshot.Snapshot, error)
- func (m *Map) State() crdt.StateSnapshot
- func (m *Map) TombstoneTags() []crdt.Tag
- func (m *Map) UnmarshalBinary(data []byte) error
- func (m *Map) UnmarshalBinaryWithLimits(data []byte, limits frame.Limits) error
- func (m *Map) ValidateValues(validate func(key string, value []byte) error) error
- type MapDelta
- type MapOptions
- type Set
- func NewSet[T comparable](replicaID string) (*Set[T], error)
- func NewSetFromClock[T comparable](state clock.State) (*Set[T], error)
- func NewSetFromClockWithOptions[T comparable](state clock.State, options SetOptions) (*Set[T], error)
- func NewSetFromSnapshot[T comparable](saved snapshot.Snapshot, codec ElementCodec[T]) (*Set[T], error)
- func NewSetFromSnapshotWithOptions[T comparable](saved snapshot.Snapshot, codec ElementCodec[T], options SetOptions) (*Set[T], error)
- func NewSetWithOptions[T comparable](replicaID string, options SetOptions) (*Set[T], error)
- func (s *Set[T]) Add(value T) error
- func (s *Set[T]) AddWithDelta(value T) (SetDelta[T], error)
- func (s *Set[T]) ApplyDelta(delta SetDelta[T]) error
- func (s *Set[T]) ClockState() clock.State
- func (s *Set[T]) CompactTombstones(tags []crdt.Tag) (int, error)
- func (s *Set[T]) Contains(value T) bool
- func (s *Set[T]) Elements() []T
- func (s *Set[T]) Frontier() map[string]crdt.Tag
- func (s *Set[T]) MarshalBinary(codec ElementCodec[T]) ([]byte, error)
- func (s *Set[T]) MarshalBinaryWithClockState(codec ElementCodec[T]) ([]byte, clock.State, error)
- func (s *Set[T]) MarshalJSON() ([]byte, error)
- func (s *Set[T]) Merge(other *Set[T]) error
- func (s *Set[T]) Remove(value T) error
- func (s *Set[T]) RemoveWithDelta(value T) (SetDelta[T], error)
- func (s *Set[T]) Snapshot(codec ElementCodec[T], frontier map[string]crdt.Tag) (snapshot.Snapshot, error)
- func (s *Set[T]) SnapshotCurrentState(codec ElementCodec[T]) (snapshot.Snapshot, error)
- func (s *Set[T]) State() crdt.StateSnapshot
- func (s *Set[T]) TombstoneTags() []crdt.Tag
- func (s *Set[T]) UnmarshalBinary(data []byte, codec ElementCodec[T]) error
- func (s *Set[T]) UnmarshalBinaryWithLimits(data []byte, codec ElementCodec[T], limits frame.DecoderLimits) error
- type SetDelta
- type SetOptions
Constants ¶
const SemanticsVersion uint64 = crdt.SemanticsVersionLWWSet
SemanticsVersion is the immutable LWW set/map v1 contract. It must match the value negotiated in a replica manifest for TypeIDs 7/8 or 9/10.
Variables ¶
var ( ErrInvalidCodec = errors.New("lww: invalid element codec") ErrInvalidReplicaID = errors.New("lww: invalid replica ID") ErrNilSet = errors.New("lww: nil set") ErrNilMap = errors.New("lww: nil map") ErrCodecMismatch = errors.New("lww: codec ID mismatch") ErrInvalidSetDelta = errors.New("lww: invalid LWW-Set delta") ErrInvalidSetSnap = errors.New("lww: invalid LWW-Set snapshot") ErrInvalidKey = errors.New("lww: invalid key") ErrInvalidDelta = errors.New("lww: invalid map delta") ErrInvalidSnapshot = errors.New("lww: invalid map snapshot") ErrTagConflict = errors.New("lww: conflicting values for one tag") ErrResourceLimit = errors.New("lww: resource limit exceeded") ErrUnsafeCompaction = errors.New("lww: unsafe tombstone compaction") )
Functions ¶
func MapFrameType ¶ added in v1.0.25
MapFrameType returns the stable LWW-Map v1 state/delta pair.
func SetFrameType ¶ added in v1.0.25
SetFrameType returns the stable LWW-Set v1 state/delta pair.
Types ¶
type ElementCodec ¶ added in v1.0.10
type ElementCodec[T comparable] interface { ID() string Marshal(T) ([]byte, error) Unmarshal([]byte) (T, error) }
ElementCodec identifies and encodes one LWW-Set element type. Its ID and encoded bytes must be stable across replicas that exchange frames. Codec implementations must be safe for concurrent calls and return errors rather than panicking for invalid input.
type Map ¶
type Map struct {
// contains filtered or unexported fields
}
Map is a byte-value LWW map. Returning and accepting copies prevents a caller from modifying replicated state through a shared slice. Values are deliberately opaque; applications may use a deterministic JSON, protobuf, or domain codec above this type.
func NewMapFromClockWithOptions ¶ added in v1.0.19
func NewMapFromClockWithOptions(state clock.State, options MapOptions) (*Map, error)
NewMapFromClockWithOptions restores a replica clock with explicit retained state limits. Persist the clock atomically with a complete snapshot before reusing its replica ID.
func NewMapFromSnapshot ¶
NewMapFromSnapshot restores a map and its HLC state. Snapshots without a clock state are rejected because they cannot safely reuse a replica ID.
func NewMapFromSnapshotWithOptions ¶ added in v1.0.19
func NewMapFromSnapshotWithOptions(saved snapshot.Snapshot, options MapOptions) (*Map, error)
NewMapFromSnapshotWithOptions restores a map and its HLC state while retaining the receiving replication group's local resource limits.
func NewMapWithOptions ¶ added in v1.0.19
func NewMapWithOptions(replicaID string, options MapOptions) (*Map, error)
NewMapWithOptions constructs a map with explicit retained-state limits.
func (*Map) ApplyDelta ¶
ApplyDelta joins a validated partial map state into m. It validates every entry and detects equal-tag conflicts before mutating the map or HLC.
func (*Map) ClockState ¶
func (*Map) CompactTombstones ¶ added in v1.0.19
CompactTombstones removes exactly requested deleted entries. For replicated state, call it only after every active member has acknowledged the exact tags in one authenticated membership epoch, a post-compaction snapshot is durable, and old deltas have been retired. tombstonegc.SimpleCollector may call it only for its documented local-only lifecycle. Unknown tags are ignored; attempting to remove a live entry or passing an invalid tag leaves the map unchanged.
func (*Map) DeleteWithDelta ¶
DeleteWithDelta removes key and returns the joinable delete delta.
func (*Map) EntryCount ¶ added in v1.0.10
EntryCount returns the total number of retained map entries, including tombstones. It is useful for callers that impose their own retention budget.
func (*Map) EntryKeys ¶ added in v1.0.10
EntryKeys returns every retained key, including delete tombstones, in lexical order. It is for resource accounting; use Keys when only visible application values are needed.
func (*Map) Frontier ¶
Frontier returns the greatest map-entry tag per replica. The returned map is owned by the caller and includes delete tombstones.
func (*Map) HasEntry ¶ added in v1.0.10
HasEntry reports whether m retains any metadata for key, including a delete tombstone. It is intended for bounded wrappers that must distinguish a new key from an idempotent replay without exposing the entry's tag or value.
func (*Map) Keys ¶
Keys returns the visible keys in lexical order, which keeps callers from accidentally depending on Go's randomized map iteration order.
func (*Map) MarshalBinary ¶
MarshalBinary returns the canonical framed LWW-Map state.
func (*Map) MarshalBinaryWithClockState ¶
MarshalBinaryWithClockState captures state and HLC state for atomic persistence before a replica ID is reused after restart.
func (*Map) MarshalJSON ¶ added in v1.0.5
MarshalJSON returns a diagnostic summary for structured logs. It omits map keys, values, tags, and clock state, and cannot restore the map.
func (*Map) SetWithDelta ¶
SetWithDelta writes a value and returns the joinable delta for this write.
func (*Map) Snapshot ¶
Snapshot creates an immutable map state snapshot with caller-supplied replication frontier and the local HLC state.
func (*Map) SnapshotCurrentState ¶
SnapshotCurrentState creates a snapshot whose frontier is derived from all visible and deleted map entries.
func (*Map) State ¶
func (m *Map) State() crdt.StateSnapshot
func (*Map) TombstoneTags ¶ added in v1.0.19
TombstoneTags returns retained delete tags in canonical order. The list is an input to an external exact-acknowledgement epoch; it is not proof that a tombstone may be removed by itself.
func (*Map) UnmarshalBinary ¶
UnmarshalBinary atomically replaces m with a valid complete LWW-Map state.
func (*Map) UnmarshalBinaryWithLimits ¶
UnmarshalBinaryWithLimits atomically replaces m with a bounded LWW-Map state. A malformed frame leaves both m and its HLC unchanged.
func (*Map) ValidateValues ¶ added in v1.0.10
ValidateValues validates every visible value in m without exposing its private entries. The callback receives a copy and is called without m's lock, so it may safely perform ordinary validation work.
type MapDelta ¶
type MapDelta struct {
// contains filtered or unexported fields
}
MapDelta is a joinable partial LWW-Map state. Its contents are deliberately opaque so callers cannot mutate an entry after it has been handed to a replica or coalescer.
func UnmarshalMapDelta ¶
UnmarshalMapDelta decodes one bounded, canonical LWW-Map delta frame.
func UnmarshalMapDeltaWithLimits ¶
UnmarshalMapDeltaWithLimits decodes one bounded, canonical LWW-Map delta.
func UnmarshalMapDeltaWithOptions ¶ added in v1.0.19
func UnmarshalMapDeltaWithOptions(data []byte, limits frame.Limits, options MapOptions) (MapDelta, error)
UnmarshalMapDeltaWithOptions decodes one bounded, canonical LWW-Map delta while enforcing the receiver's retained-state limits before allocating or copying entries beyond them. It is intended for bounded wrappers that must validate a delta before constructing a Map receiver.
func (MapDelta) Keys ¶ added in v1.0.10
Keys returns all keys represented by d, including delete tombstones, in lexical order. The returned slice is owned by the caller.
func (MapDelta) MarshalBinary ¶
MarshalBinary returns the canonical framed LWW-Map delta.
func (MapDelta) MarshalJSON ¶ added in v1.0.5
MarshalJSON returns a diagnostic summary for structured logs. It omits map keys, values, tags, and clock state and cannot be applied as a delta from JSON.
func (MapDelta) ValidateValues ¶ added in v1.0.10
ValidateValues validates every visible value in d without exposing its private tags or allowing callers to mutate the delta. A nil validator is an error so a wrapper cannot accidentally skip schema validation at a network boundary.
type MapOptions ¶ added in v1.0.19
MapOptions bounds retained LWW-Map state, including delete tombstones. MaxKeyBytes and MaxValueBytes apply to local writes and accepted deltas, so repeated small frames cannot grow one replica beyond its group budget.
func DefaultMapOptions ¶ added in v1.0.19
func DefaultMapOptions() MapOptions
DefaultMapOptions returns conservative defaults aligned with the default framed element and byte limits.
type Set ¶
type Set[T comparable] struct { // contains filtered or unexported fields }
Set is an LWW element set. Concurrent add/remove operations are resolved by the canonical Tag ordering, rather than by an implicit wall-clock tie rule.
func NewSetFromClock ¶
func NewSetFromClock[T comparable](state clock.State) (*Set[T], error)
func NewSetFromClockWithOptions ¶ added in v1.0.19
func NewSetFromClockWithOptions[T comparable](state clock.State, options SetOptions) (*Set[T], error)
NewSetFromClockWithOptions restores a replica clock with explicit retained entry limits. Persist the clock atomically with a complete snapshot before reusing its replica ID.
func NewSetFromSnapshot ¶ added in v1.0.10
func NewSetFromSnapshot[T comparable](saved snapshot.Snapshot, codec ElementCodec[T]) (*Set[T], error)
NewSetFromSnapshot restores a set and its persisted local HLC state. Snapshots without clock state are rejected because they cannot safely reuse a logical replica ID.
func NewSetFromSnapshotWithOptions ¶ added in v1.0.19
func NewSetFromSnapshotWithOptions[T comparable](saved snapshot.Snapshot, codec ElementCodec[T], options SetOptions) (*Set[T], error)
NewSetFromSnapshotWithOptions restores a set and its persisted HLC state while retaining the receiving replication group's local entry limit.
func NewSetWithOptions ¶ added in v1.0.19
func NewSetWithOptions[T comparable](replicaID string, options SetOptions) (*Set[T], error)
NewSetWithOptions constructs a set with explicit retained-entry limits.
func (*Set[T]) AddWithDelta ¶ added in v1.0.10
AddWithDelta inserts value and returns the joinable delta for this write.
func (*Set[T]) ApplyDelta ¶ added in v1.0.10
ApplyDelta joins a validated partial LWW-Set state into s.
func (*Set[T]) ClockState ¶
func (*Set[T]) CompactTombstones ¶ added in v1.0.19
CompactTombstones removes exactly requested deleted entries. For replicated state, call it only after every active member has acknowledged the exact tags in one authenticated membership epoch, a post-compaction snapshot is durable, and old deltas have been retired. tombstonegc.SimpleCollector may call it only for its documented local-only lifecycle. Unknown tags are ignored; attempting to remove a live entry or passing an invalid tag leaves the set unchanged.
func (*Set[T]) Frontier ¶ added in v1.0.10
Frontier returns the greatest set-entry tag per replica. The returned map is owned by the caller and includes removed entries.
func (*Set[T]) MarshalBinary ¶ added in v1.0.10
func (s *Set[T]) MarshalBinary(codec ElementCodec[T]) ([]byte, error)
MarshalBinary returns the canonical framed LWW-Set state using codec to identify and serialize its element type.
func (*Set[T]) MarshalBinaryWithClockState ¶ added in v1.0.10
MarshalBinaryWithClockState captures state and HLC state for atomic persistence before a replica ID is reused after restart.
func (*Set[T]) MarshalJSON ¶ added in v1.0.5
MarshalJSON returns a diagnostic summary for structured logs. It omits elements, keys, values, tags, and clock state, and cannot restore the set.
func (*Set[T]) Merge ¶
Merge selects the highest tag for every element. It snapshots other before locking s, so reciprocal concurrent merges cannot deadlock.
func (*Set[T]) RemoveWithDelta ¶ added in v1.0.10
RemoveWithDelta removes value and returns the joinable delta for this write.
func (*Set[T]) Snapshot ¶ added in v1.0.10
func (s *Set[T]) Snapshot(codec ElementCodec[T], frontier map[string]crdt.Tag) (snapshot.Snapshot, error)
Snapshot creates an immutable LWW-Set state snapshot with caller-supplied replication frontier and the local HLC state.
func (*Set[T]) SnapshotCurrentState ¶ added in v1.0.10
func (s *Set[T]) SnapshotCurrentState(codec ElementCodec[T]) (snapshot.Snapshot, error)
SnapshotCurrentState creates a snapshot whose frontier is derived from all visible and removed set entries.
func (*Set[T]) State ¶
func (s *Set[T]) State() crdt.StateSnapshot
func (*Set[T]) TombstoneTags ¶ added in v1.0.19
TombstoneTags returns retained delete tags in canonical order. The list is an input to an external exact-acknowledgement epoch; it is not proof that a tombstone may be removed by itself.
func (*Set[T]) UnmarshalBinary ¶ added in v1.0.10
func (s *Set[T]) UnmarshalBinary(data []byte, codec ElementCodec[T]) error
UnmarshalBinary atomically replaces s with a valid complete LWW-Set state.
func (*Set[T]) UnmarshalBinaryWithLimits ¶ added in v1.0.10
func (s *Set[T]) UnmarshalBinaryWithLimits(data []byte, codec ElementCodec[T], limits frame.DecoderLimits) error
UnmarshalBinaryWithLimits validates data before replacing state. A malformed frame leaves both s and its HLC unchanged.
type SetDelta ¶ added in v1.0.10
type SetDelta[T comparable] struct { // contains filtered or unexported fields }
SetDelta is a joinable partial LWW-Set state. Its entries are unexported so callers cannot alter a delta after handing it to replication code.
func UnmarshalSetDelta ¶ added in v1.0.10
func UnmarshalSetDelta[T comparable](data []byte, codec ElementCodec[T]) (SetDelta[T], error)
UnmarshalSetDelta decodes one bounded, canonical LWW-Set delta frame.
func UnmarshalSetDeltaWithLimits ¶ added in v1.0.10
func UnmarshalSetDeltaWithLimits[T comparable](data []byte, codec ElementCodec[T], limits frame.DecoderLimits) (SetDelta[T], error)
UnmarshalSetDeltaWithLimits decodes one bounded, canonical LWW-Set delta frame using caller-supplied decoder limits.
func (SetDelta[T]) MarshalBinary ¶ added in v1.0.10
func (d SetDelta[T]) MarshalBinary(codec ElementCodec[T]) ([]byte, error)
MarshalBinary returns the canonical framed LWW-Set delta using codec.
func (SetDelta[T]) MarshalJSON ¶ added in v1.0.10
MarshalJSON returns a diagnostic summary for structured logs. It omits set elements and tags and cannot be applied as a delta from JSON.
type SetOptions ¶ added in v1.0.19
type SetOptions struct {
MaxEntries int
}
SetOptions bounds retained LWW-Set entries, including delete tombstones. Applications accepting untrusted or long-lived replication streams should select a limit for each replication group instead of relying on process-wide memory availability.
func DefaultSetOptions ¶ added in v1.0.19
func DefaultSetOptions() SetOptions
DefaultSetOptions returns a conservative default aligned with the default framed element limit.