kumulant

Concurrency

User-facing concurrency contract for stats. Each stat translates the chosen level into a cell-encoding and lock strategy that honours it for that stat's mathematical structure.

Bare-stat construction defaults to None. To configure a coherent bag of stats with one contract, declare them inside a com.eignex.kumulant.schema.StatSchema with the desired concurrency; the schema propagates the choice to every registered stat at delegate registration.

Picking a mode

  • A single-threaded producer should pick None.

  • Many writers on an additive stat (sum, count, Bernoulli sum) should pick HighWrite on the JVM and Relaxed elsewhere.

  • Many writers that can tolerate ULP-level drift on coupled state in exchange for not blocking should pick Relaxed.

  • Many writers that need exact arithmetic should pick Strict.

  • Many writers on a sketch should also pick Strict: sketches self-serialise and the other modes degrade to it anyway.

Per-stat concurrency clauses

Each stat's KDoc has a **Concurrency:** section naming the mechanism and per-level behaviour. Recurring patterns:

  • A single atomic add per update: exact under every level; swapped for a striped adder under HighWrite.

  • A single-cell CAS min or max loop: exact under every level; the retry serialises racing writers naturally.

  • Independent striped cells with deterministic bucket assignment: exact under every level (used by additive histograms, BernoulliSumStat, and friends).

  • Welford-coupled cells without a lock: exact under None, Strict, and HighWrite; Relaxed drifts a small amount without throwing.

  • A body locked under any concurrent level: exact under every level with throughput bounded by lock contention.

Bandits inherit the concurrency of their per-arm stat.

Snapshot consistency

A read() call is best-effort across cells. A reader that races with a writer on a Relaxed Welford stat may see the count incremented before the mean is. The drift is the same as the writer-on-writer case: small in magnitude, no exceptions, no corruption. For a strictly atomic snapshot use Strict; the per-stat lock will serialise readers behind the writer.

Samples

val hits = SumStat(concurrency = Concurrency.HighWrite)
val ols = UnivariateRegressionStat(concurrency = Concurrency.Strict)
hits.update(1.0)
ols.update(x = 1.0, y = 2.0)

Entries

Link copied to clipboard

Single-threaded. No atomics, no locks. The default and cheapest path; it is correct when one thread owns the accumulator.

Link copied to clipboard

Lock-free atomic cells. Many writers, no blocking.

Link copied to clipboard

Multi-threaded with whatever synchronisation each stat needs to stay exact across coupled state. For Welford-style stats this is a lock around the body of update. For sketches that already self-serialise (DDSketch, t-digest, HDR, and so on) Strict is the natural mode and adds no extra overhead.

Link copied to clipboard

JVM-only striped adders for additive stats. On a heavily-loaded com.eignex.kumulant.stat.summary.SumStat or com.eignex.kumulant.stat.summary.CountStat this scales linearly with the writer count.

Properties

Link copied to clipboard

Returns a representation of an immutable list of all enum entries, in the order they're declared.

Link copied to clipboard
expect val name: String
Link copied to clipboard
expect val ordinal: Int

Functions

Link copied to clipboard

Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)

Link copied to clipboard

Returns an array containing the constants of this enum type, in the order they're declared.

entries

Returns a representation of an immutable list of all enum entries, in the order they're declared.

This method may be used to iterate over the enum entries.

valueOf

Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)

Throws

if this enum type has no constant with the specified name

values

Returns an array containing the constants of this enum type, in the order they're declared.

This method may be used to iterate over the constants.