GCounterDouble

@Serializable
class GCounterDouble : Quilted<GCounterDouble>

A grow-only counter over Double — the exact-precision sibling of GCounter.

Same lattice as GCounter (a per-replica map, piece is elementwise max), but the slot values are Double. It exists so a monotonic OTLP DOUBLE_SUM metric folds into a grow-only counter without truncation or fixed-point scaling.

The one wrinkle: value determinism

value sums the per-replica slots, and floating-point + is not associative, so summing in map-iteration order could yield a slightly different value on two replicas that hold identical converged state. The merged state always converges (elementwise max is order-independent); only the derived value is order-sensitive. value therefore sums in canonical ReplicaId order so every replica computes the same number. (Very large magnitude differences can still lose low-order bits — the honest floating-point limit, analogous to HyperLogLog's estimation error.)

Samples

val phone = ReplicaId("phone")
val watch = ReplicaId("watch")

// Each device independently accumulates fractional seconds of CPU time.
var onPhone = GCounterDouble.ZERO
onPhone = onPhone.piece(onPhone.inc(phone, 0.75).delta)

var onWatch = GCounterDouble.ZERO
onWatch = onWatch.piece(onWatch.inc(watch, 0.5).delta)

// Merge either direction — the total is the same, to the bit.
val total = onPhone.piece(onWatch).value // 1.25
check(total == 1.25)

Types

Link copied to clipboard
object Companion

Properties

Link copied to clipboard

The counter's value: the sum of all per-replica counts, in canonical replica order.

Functions

Link copied to clipboard
open fun causalDots(): Set<Dot>

The causal Dots this state has delivered — (author, author-seq) per op.

Link copied to clipboard

The per-author high-water of dots this state delivered and has since compacted away without retaining their identities.

Link copied to clipboard
fun count(replica: ReplicaId): Double

This replica's current count (0.0 if it has never incremented).

Link copied to clipboard
open operator override fun equals(other: Any?): Boolean
Link copied to clipboard
open override fun hashCode(): Int
Link copied to clipboard
fun inc(replica: ReplicaId, by: Double = 1.0): Patch<GCounterDouble>

Increment replica's own slot by by (must be > 0). Returns the delta to merge in with piece; the receiver is unchanged.

Link copied to clipboard
open override fun piece(other: GCounterDouble): GCounterDouble

The join: elementwise max of the two count maps.

Link copied to clipboard
open override fun toString(): String