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 ¶
- Variables
- type ElementCodec
- type Map
- func (m *Map) ApplyDelta(delta MapDelta) error
- func (m *Map) ClockState() clock.State
- 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) 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 Set
- 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]) 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]) UnmarshalBinary(data []byte, codec ElementCodec[T]) error
- func (s *Set[T]) UnmarshalBinaryWithLimits(data []byte, codec ElementCodec[T], limits frame.DecoderLimits) error
- type SetDelta
Constants ¶
This section is empty.
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") )
Functions ¶
This section is empty.
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 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 (*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) 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) 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 (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 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 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 (*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]) 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]) 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.