lww

package
v1.0.36 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 3, 2026 License: MIT Imports: 13 Imported by: 0

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

View Source
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

View Source
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

func MapFrameType() crdt.FrameType

MapFrameType returns the stable LWW-Map v1 state/delta pair.

func SetFrameType added in v1.0.25

func SetFrameType() crdt.FrameType

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 NewMap

func NewMap(replicaID string) (*Map, error)

func NewMapFromClock

func NewMapFromClock(state clock.State) (*Map, error)

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

func NewMapFromSnapshot(saved snapshot.Snapshot) (*Map, error)

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

func (m *Map) ApplyDelta(delta MapDelta) error

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 (m *Map) ClockState() clock.State

func (*Map) CompactTombstones added in v1.0.19

func (m *Map) CompactTombstones(tags []crdt.Tag) (int, error)

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) Delete

func (m *Map) Delete(key string) error

Delete removes key and preserves the original non-delta API.

func (*Map) DeleteWithDelta

func (m *Map) DeleteWithDelta(key string) (MapDelta, error)

DeleteWithDelta removes key and returns the joinable delete delta.

func (*Map) EntryCount added in v1.0.10

func (m *Map) EntryCount() int

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

func (m *Map) EntryKeys() []string

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

func (m *Map) Frontier() map[string]crdt.Tag

Frontier returns the greatest map-entry tag per replica. The returned map is owned by the caller and includes delete tombstones.

func (*Map) Get

func (m *Map) Get(key string) ([]byte, bool)

func (*Map) HasEntry added in v1.0.10

func (m *Map) HasEntry(key string) bool

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

func (m *Map) Keys() []string

Keys returns the visible keys in lexical order, which keeps callers from accidentally depending on Go's randomized map iteration order.

func (*Map) MarshalBinary

func (m *Map) MarshalBinary() ([]byte, error)

MarshalBinary returns the canonical framed LWW-Map state.

func (*Map) MarshalBinaryWithClockState

func (m *Map) MarshalBinaryWithClockState() ([]byte, clock.State, error)

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

func (m *Map) MarshalJSON() ([]byte, error)

MarshalJSON returns a diagnostic summary for structured logs. It omits map keys, values, tags, and clock state, and cannot restore the map.

func (*Map) Merge

func (m *Map) Merge(other *Map) error

func (*Map) Set

func (m *Map) Set(key string, value []byte) error

Set writes a value and preserves the original non-delta API.

func (*Map) SetWithDelta

func (m *Map) SetWithDelta(key string, value []byte) (MapDelta, error)

SetWithDelta writes a value and returns the joinable delta for this write.

func (*Map) Snapshot

func (m *Map) Snapshot(frontier map[string]crdt.Tag) (snapshot.Snapshot, error)

Snapshot creates an immutable map state snapshot with caller-supplied replication frontier and the local HLC state.

func (*Map) SnapshotCurrentState

func (m *Map) SnapshotCurrentState() (snapshot.Snapshot, error)

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

func (m *Map) TombstoneTags() []crdt.Tag

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

func (m *Map) UnmarshalBinary(data []byte) error

UnmarshalBinary atomically replaces m with a valid complete LWW-Map state.

func (*Map) UnmarshalBinaryWithLimits

func (m *Map) UnmarshalBinaryWithLimits(data []byte, limits frame.Limits) error

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

func (m *Map) ValidateValues(validate func(key string, value []byte) error) error

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

func UnmarshalMapDelta(data []byte) (MapDelta, error)

UnmarshalMapDelta decodes one bounded, canonical LWW-Map delta frame.

func UnmarshalMapDeltaWithLimits

func UnmarshalMapDeltaWithLimits(data []byte, limits frame.Limits) (MapDelta, error)

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

func (d MapDelta) Keys() []string

Keys returns all keys represented by d, including delete tombstones, in lexical order. The returned slice is owned by the caller.

func (MapDelta) MarshalBinary

func (d MapDelta) MarshalBinary() ([]byte, error)

MarshalBinary returns the canonical framed LWW-Map delta.

func (MapDelta) MarshalJSON added in v1.0.5

func (d MapDelta) MarshalJSON() ([]byte, error)

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) Merge

func (d MapDelta) Merge(other MapDelta) (MapDelta, error)

Merge joins two map deltas without modifying either input.

func (MapDelta) ValidateValues added in v1.0.10

func (d MapDelta) ValidateValues(validate func(key string, value []byte) error) error

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

type MapOptions struct {
	MaxEntries    int
	MaxKeyBytes   int
	MaxValueBytes int
}

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 NewSet

func NewSet[T comparable](replicaID string) (*Set[T], error)

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]) Add

func (s *Set[T]) Add(value T) error

Add inserts value and preserves the original non-delta API.

func (*Set[T]) AddWithDelta added in v1.0.10

func (s *Set[T]) AddWithDelta(value T) (SetDelta[T], error)

AddWithDelta inserts value and returns the joinable delta for this write.

func (*Set[T]) ApplyDelta added in v1.0.10

func (s *Set[T]) ApplyDelta(delta SetDelta[T]) error

ApplyDelta joins a validated partial LWW-Set state into s.

func (*Set[T]) ClockState

func (s *Set[T]) ClockState() clock.State

func (*Set[T]) CompactTombstones added in v1.0.19

func (s *Set[T]) CompactTombstones(tags []crdt.Tag) (int, error)

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]) Contains

func (s *Set[T]) Contains(value T) bool

func (*Set[T]) Elements

func (s *Set[T]) Elements() []T

func (*Set[T]) Frontier added in v1.0.10

func (s *Set[T]) Frontier() map[string]crdt.Tag

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

func (s *Set[T]) MarshalBinaryWithClockState(codec ElementCodec[T]) ([]byte, clock.State, error)

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

func (s *Set[T]) MarshalJSON() ([]byte, error)

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

func (s *Set[T]) Merge(other *Set[T]) error

Merge selects the highest tag for every element. It snapshots other before locking s, so reciprocal concurrent merges cannot deadlock.

func (*Set[T]) Remove

func (s *Set[T]) Remove(value T) error

Remove removes value and preserves the original non-delta API.

func (*Set[T]) RemoveWithDelta added in v1.0.10

func (s *Set[T]) RemoveWithDelta(value T) (SetDelta[T], error)

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

func (s *Set[T]) TombstoneTags() []crdt.Tag

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

func (d SetDelta[T]) MarshalJSON() ([]byte, error)

MarshalJSON returns a diagnostic summary for structured logs. It omits set elements and tags and cannot be applied as a delta from JSON.

func (SetDelta[T]) Merge added in v1.0.10

func (d SetDelta[T]) Merge(other SetDelta[T]) (SetDelta[T], error)

Merge joins two partial LWW-Set states without modifying either delta.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL