counter

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: 8 Imported by: 0

Documentation

Overview

Package counter implements counter CRDT primitives.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidReplicaID indicates that a counter or delta contains an invalid
	// logical replica identifier.
	ErrInvalidReplicaID = errors.New("counter: invalid replica ID")
	// ErrNilCounter indicates an operation received a nil counter.
	ErrNilCounter = errors.New("counter: nil G-Counter")
	// ErrCounterOverflow indicates a local component, aggregate, or fixed-width
	// counter value would overflow.
	ErrCounterOverflow = errors.New("counter: value overflows uint64")
)
View Source
var (
	// ErrNilPNCounter indicates an operation received a nil PN-Counter.
	ErrNilPNCounter = errors.New("counter: nil PN-Counter")
)

Functions

This section is empty.

Types

type GCounter

type GCounter struct {
	// contains filtered or unexported fields
}

GCounter is a grow-only, state-based counter. Each replica owns one map entry, and Merge takes the maximum value for every replica ID.

func NewGCounter

func NewGCounter(replicaID string) (*GCounter, error)

NewGCounter creates a G-Counter owned by replicaID.

func (*GCounter) ApplyDelta

func (c *GCounter) ApplyDelta(delta GCounterDelta) error

ApplyDelta joins delta into c.

Example

ExampleGCounter_ApplyDelta shows the local-mutation and bounded-receive split. Authenticate and apply the transport body limit before handing bytes to the decoder.

writer, err := NewGCounter("warehouse-a")
if err != nil {
	panic(err)
}
reader, err := NewGCounter("warehouse-b")
if err != nil {
	panic(err)
}

delta, err := writer.Increment(2)
if err != nil {
	panic(err)
}
encoded, err := delta.MarshalBinary()
if err != nil {
	panic(err)
}

limits := frame.DecoderLimits{
	MaxFrameBytes:  4 << 10,
	MaxPayload:     3 << 10,
	MaxCodecID:     128,
	MaxElements:    64,
	MaxTags:        64,
	MaxStringBytes: 256,
}
received, err := UnmarshalGCounterDeltaWithLimits(encoded, limits)
if err != nil {
	panic(err)
}
if err := reader.ApplyDelta(received); err != nil {
	panic(err)
}
if err := reader.ApplyDelta(received); err != nil { // A retry is idempotent.
	panic(err)
}

value, err := reader.Value()
if err != nil {
	panic(err)
}
fmt.Println(value)
Output:
2

func (*GCounter) ApplyDeltaChanged added in v1.0.36

func (c *GCounter) ApplyDeltaChanged(delta GCounterDelta) (bool, error)

ApplyDeltaChanged joins delta into c and reports whether it extended the retained counter state. Callers that bridge a counter to a local observer can use the result to avoid publishing a duplicate network delivery as a new UI revision.

func (*GCounter) Counts

func (c *GCounter) Counts() map[string]uint64

Counts returns a copy of the per-replica components.

func (*GCounter) Increment

func (c *GCounter) Increment(amount uint64) (GCounterDelta, error)

Increment adds amount to this counter's local component and returns a delta that represents the new component value.

func (*GCounter) MarshalBinary

func (c *GCounter) MarshalBinary() ([]byte, error)

MarshalBinary returns a deterministic framed representation of c.

func (*GCounter) MarshalJSON added in v1.0.5

func (c *GCounter) MarshalJSON() ([]byte, error)

MarshalJSON returns a diagnostic summary for structured logs. It omits per-replica components and cannot be used to restore counter state.

func (*GCounter) Merge

func (c *GCounter) Merge(other *GCounter) error

Merge joins other into c. It copies other before taking c's write lock so concurrent cross-merges cannot deadlock.

func (*GCounter) State

func (c *GCounter) State() crdt.StateSnapshot

State returns an immutable diagnostic summary.

func (*GCounter) UnmarshalBinary

func (c *GCounter) UnmarshalBinary(data []byte) error

UnmarshalBinary validates data completely before atomically replacing c's state.

func (*GCounter) UnmarshalBinaryWithLimits

func (c *GCounter) UnmarshalBinaryWithLimits(data []byte, limits frame.DecoderLimits) error

UnmarshalBinaryWithLimits validates data completely before atomically replacing c's state using caller-supplied decoder limits.

func (*GCounter) Value

func (c *GCounter) Value() (uint64, error)

Value returns the sum of all replica components.

type GCounterDelta

type GCounterDelta struct {
	// contains filtered or unexported fields
}

GCounterDelta is a joinable partial GCounter state. Its contents are opaque; Counts returns a copy for diagnostics or a future transport encoder.

func UnmarshalGCounterDelta

func UnmarshalGCounterDelta(data []byte) (GCounterDelta, error)

UnmarshalGCounterDelta validates and returns one G-Counter delta frame.

func UnmarshalGCounterDeltaWithLimits

func UnmarshalGCounterDeltaWithLimits(data []byte, limits frame.DecoderLimits) (GCounterDelta, error)

UnmarshalGCounterDeltaWithLimits validates and returns one G-Counter delta frame using caller-supplied decoder limits.

func (GCounterDelta) Counts

func (d GCounterDelta) Counts() map[string]uint64

Counts returns a copy of the components represented by d.

func (GCounterDelta) MarshalBinary

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

MarshalBinary returns a deterministic framed representation of d.

func (GCounterDelta) MarshalJSON added in v1.0.5

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

MarshalJSON returns a diagnostic summary for structured logs. It omits per-replica components and cannot be applied as a delta from JSON.

func (GCounterDelta) Merge

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

Merge joins other into d and returns a new delta without modifying either input delta.

type PNCounter

type PNCounter struct {
	// contains filtered or unexported fields
}

PNCounter is a state-based positive-negative counter. Each component is a per-replica G-Counter: positive records increments and negative records decrements. Merge takes the maximum component value in both maps.

func NewPNCounter

func NewPNCounter(replicaID string) (*PNCounter, error)

NewPNCounter creates a PN-Counter owned by replicaID.

func (*PNCounter) ApplyDelta

func (c *PNCounter) ApplyDelta(delta PNCounterDelta) error

ApplyDelta joins delta into c.

func (*PNCounter) ApplyDeltaChanged added in v1.0.36

func (c *PNCounter) ApplyDeltaChanged(delta PNCounterDelta) (bool, error)

ApplyDeltaChanged joins delta into c and reports whether it extended either retained component map. It makes duplicate remote delivery observable to a caller without weakening the counter's idempotent join semantics.

func (*PNCounter) Decrement

func (c *PNCounter) Decrement(amount uint64) (PNCounterDelta, error)

Decrement adds amount to this replica's negative component and returns the resulting component as a delta.

func (*PNCounter) Increment

func (c *PNCounter) Increment(amount uint64) (PNCounterDelta, error)

Increment adds amount to this replica's positive component and returns the resulting component as a delta.

func (*PNCounter) MarshalBinary

func (c *PNCounter) MarshalBinary() ([]byte, error)

MarshalBinary returns a deterministic framed representation of c.

func (*PNCounter) MarshalJSON added in v1.0.5

func (c *PNCounter) MarshalJSON() ([]byte, error)

MarshalJSON returns a diagnostic summary for structured logs. It omits per-replica components and cannot be used to restore counter state.

func (*PNCounter) Merge

func (c *PNCounter) Merge(other *PNCounter) error

Merge joins other into c. It snapshots other before taking c's write lock so concurrent cross-merges cannot deadlock.

func (*PNCounter) NegativeCounts

func (c *PNCounter) NegativeCounts() map[string]uint64

NegativeCounts returns a copy of the per-replica decrement components.

func (*PNCounter) PositiveCounts

func (c *PNCounter) PositiveCounts() map[string]uint64

PositiveCounts returns a copy of the per-replica increment components.

func (*PNCounter) State

func (c *PNCounter) State() crdt.StateSnapshot

State returns an immutable diagnostic summary.

func (*PNCounter) UnmarshalBinary

func (c *PNCounter) UnmarshalBinary(data []byte) error

UnmarshalBinary validates data completely before atomically replacing c's state.

func (*PNCounter) UnmarshalBinaryWithLimits

func (c *PNCounter) UnmarshalBinaryWithLimits(data []byte, limits frame.DecoderLimits) error

UnmarshalBinaryWithLimits validates data completely before atomically replacing c's state using caller-supplied decoder limits.

func (*PNCounter) Value

func (c *PNCounter) Value() (*big.Int, error)

Value returns the exact signed counter value as a newly allocated integer. It uses big.Int so every valid uint64 component state remains representable.

func (*PNCounter) ValueInt64

func (c *PNCounter) ValueInt64() (int64, error)

ValueInt64 returns the signed value when it fits in int64.

type PNCounterDelta

type PNCounterDelta struct {
	// contains filtered or unexported fields
}

PNCounterDelta is a joinable partial PN-Counter state. Its contents are opaque; the count accessors return copies for diagnostics and transport.

func UnmarshalPNCounterDelta

func UnmarshalPNCounterDelta(data []byte) (PNCounterDelta, error)

UnmarshalPNCounterDelta validates and returns one PN-Counter delta frame.

func UnmarshalPNCounterDeltaWithLimits

func UnmarshalPNCounterDeltaWithLimits(data []byte, limits frame.DecoderLimits) (PNCounterDelta, error)

UnmarshalPNCounterDeltaWithLimits validates and returns one PN-Counter delta frame using caller-supplied decoder limits.

func (PNCounterDelta) MarshalBinary

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

MarshalBinary returns a deterministic framed representation of d.

func (PNCounterDelta) MarshalJSON added in v1.0.5

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

MarshalJSON returns a diagnostic summary for structured logs. It omits per-replica components and cannot be applied as a delta from JSON.

func (PNCounterDelta) Merge

Merge joins other into d and returns a new delta without modifying either input delta.

func (PNCounterDelta) NegativeCounts

func (d PNCounterDelta) NegativeCounts() map[string]uint64

NegativeCounts returns a copy of the decrement components represented by d.

func (PNCounterDelta) PositiveCounts

func (d PNCounterDelta) PositiveCounts() map[string]uint64

PositiveCounts returns a copy of the increment components represented by d.

Jump to

Keyboard shortcuts

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