chronicle

package
v0.16.5 Latest Latest
Warning

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

Go to latest
Published: Jul 21, 2026 License: Apache-2.0 Imports: 2 Imported by: 0

Documentation

Overview

Package chronicle is the extracted cascade engine of the chronicle substrate (docs/proposals/chronicle-substrate.md, @C03/@C04): a generic rollup cascade parameterised by a monoid, over a time-grain hierarchy.

The theorem (@C03): the rollup cascade in ts, cal, and bal is one construction — a monoid homomorphism over a grain hierarchy. ts folds (number, +, 0) and (min/max with identities); cal's dayparts fold (bitset, OR, ∅); bal folds (int64, +, 0). This package implements the construction once, parameterised: an associative combine with an identity, cascading upward on append, invalidating on correction.

Sequencing (@C §5): incumbents do not migrate onto this engine merely because it exists — cal's rollups are stress-verified on real hardware and migrate opportunistically or never; ts likewise when next touched for its own reasons. New consumers (bal, wave 4) ride the engine natively. The instantiation tests in this package prove the incumbent monoids are expressible, which is the extraction's correctness bar.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BitsetOR

type BitsetOR struct{}

BitsetOR is cal's daypart occupancy fold: (uint8 bitset, OR, 0). One byte summarises a day at 3-hour-daypart granularity (@cal codec §4).

func (BitsetOR) Combine

func (BitsetOR) Combine(a, b uint8) uint8

func (BitsetOR) Identity

func (BitsetOR) Identity() uint8

type BucketKey

type BucketKey struct {
	Level int
	Start time.Time
}

BucketKey addresses one bucket: a hierarchy level and its grain-aligned start instant (UTC).

type BucketStore

type BucketStore[T any] interface {
	Get(k BucketKey) (T, bool)
	Put(k BucketKey, v T)
	Delete(k BucketKey)
}

BucketStore is the storage seam. The engine is storage-agnostic: an in-memory store ships here for tests and small consumers; bal brings a SQL-plane store (wave 4, guard-locality obliged — @C04a), and any Pebble-plane store arrives with its consumer.

Get returns the bucket's folded value and whether it exists. Put overwrites. Delete removes (used by invalidation). Implementations must be safe for the engine's single-writer discipline; concurrent writers are the consumer's concern (bal serialises under its own transaction; @C04a).

type Engine

type Engine[T any] struct {
	// contains filtered or unexported fields
}

Engine is the monoid-parameterised cascade over one hierarchy and one store. Append folds a value into the finest bucket and cascades the combine upward through every coarser grain. Invalidate removes every bucket covering an instant so a later Recompute (or the consumer's re-fold) rebuilds them — corrections must not silently keep stale coarse folds (the ts correction rule, generalised).

func NewEngine

func NewEngine[T any](m Monoid[T], h *Hierarchy, s BucketStore[T]) (*Engine[T], error)

NewEngine constructs an engine. All three parameters are required.

func (*Engine[T]) Append

func (e *Engine[T]) Append(v T, t time.Time)

Append folds v into the bucket containing t at every level of the hierarchy — the upward cascade. Because Combine is associative and every coarse bucket is an exact multiple of the fine grain, combining the increment directly into each level equals re-folding that level from its children: the homomorphism property, asserted by the engine's tests rather than trusted.

func (*Engine[T]) Bucket

func (e *Engine[T]) Bucket(level int, t time.Time) T

Bucket returns the folded value for the bucket containing t at the given level, or the identity if the bucket does not exist.

func (*Engine[T]) Invalidate

func (e *Engine[T]) Invalidate(t time.Time)

Invalidate removes every bucket, at every level, that covers t. A correction to underlying data makes every covering fold stale; the safe response is absence (forcing recompute), never a silently wrong value. Recompute rebuilds from a replay callback.

func (*Engine[T]) Recompute

func (e *Engine[T]) Recompute(t time.Time, replay func(from, to time.Time, emit func(v T, at time.Time)))

Recompute rebuilds every bucket, at every level, inside the coarsest bucket containing t, by re-folding source values supplied by replay. replay must yield every (value, instant) pair within the half-open window [from, to) — the consumer owns the authoritative record (the journal, the event store) and therefore owns replay; the engine owns only the fold.

The whole coarsest window is cleared, not just the chain covering t: replay refills every fine bucket in the window via Append, so any bucket left standing would double-count its replayed values.

type Grain

type Grain struct {
	Name  string        // e.g. "5m", "hour", "day" — diagnostic only
	Width time.Duration // bucket width; must be > 0
}

Grain is one level of the time hierarchy: a bucket width. Instants truncate onto grain-aligned bucket starts in UTC.

func (Grain) Truncate

func (g Grain) Truncate(t time.Time) time.Time

Truncate returns the bucket start containing t at this grain, in UTC.

type Hierarchy

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

Hierarchy is an ordered set of grains, finest first, each coarser grain an exact multiple of the previous. The multiple requirement is what makes the homomorphism exact: every coarse bucket is the fold of a whole number of fine buckets, so cascading combine loses nothing.

func NewHierarchy

func NewHierarchy(grains ...Grain) (*Hierarchy, error)

NewHierarchy validates and constructs a hierarchy. Grains must be ordered finest→coarsest, each width a positive exact multiple of the preceding width.

func (*Hierarchy) Grain

func (h *Hierarchy) Grain(i int) Grain

Grain returns the grain at level i (0 = finest).

func (*Hierarchy) Levels

func (h *Hierarchy) Levels() int

Levels returns the number of grains.

type MaxFloat64

type MaxFloat64 struct{}

MaxFloat64 is ts's maximum fold, same identity treatment.

func (MaxFloat64) Combine

func (MaxFloat64) Combine(a, b MinValue) MinValue

func (MaxFloat64) Identity

func (MaxFloat64) Identity() MinValue

type MemStore

type MemStore[T any] struct {
	// contains filtered or unexported fields
}

MemStore is the in-memory BucketStore: the test vehicle and the small-consumer default. Not safe for concurrent use — the engine's single-writer discipline is the consumer's to enforce (@C04a).

func NewMemStore

func NewMemStore[T any]() *MemStore[T]

NewMemStore constructs an empty in-memory store.

func (*MemStore[T]) Delete

func (s *MemStore[T]) Delete(k BucketKey)

func (*MemStore[T]) Get

func (s *MemStore[T]) Get(k BucketKey) (T, bool)

func (*MemStore[T]) Len

func (s *MemStore[T]) Len() int

Len reports the number of stored buckets (test support).

func (*MemStore[T]) Put

func (s *MemStore[T]) Put(k BucketKey, v T)

type MinFloat64

type MinFloat64 struct{}

func (MinFloat64) Combine

func (MinFloat64) Combine(a, b MinValue) MinValue

func (MinFloat64) Identity

func (MinFloat64) Identity() MinValue

type MinValue

type MinValue struct {
	Valid bool
	V     float64
}

MinFloat64 is ts's minimum fold, with +Inf-free identity handling via a validity flag: the identity is "no value yet".

type Monoid

type Monoid[T any] interface {
	// Identity returns the neutral element: Combine(Identity(), x) == x.
	Identity() T
	// Combine folds two values. Must be associative:
	// Combine(a, Combine(b, c)) == Combine(Combine(a, b), c).
	Combine(a, b T) T
}

Monoid is the algebraic parameter of the cascade: an associative Combine with an Identity element. Associativity and identity are laws the implementation must satisfy — they are property-tested per instantiation in this package, not assumed.

type SumFloat64

type SumFloat64 struct{}

SumFloat64 is ts's additive fold: (float64, +, 0).

func (SumFloat64) Combine

func (SumFloat64) Combine(a, b float64) float64

func (SumFloat64) Identity

func (SumFloat64) Identity() float64

type SumInt64

type SumInt64 struct{}

SumInt64 is bal's conservation fold: (int64, +, 0). Balance-as-of is this monoid chained across sealed checkpoints (@C03).

func (SumInt64) Combine

func (SumInt64) Combine(a, b int64) int64

func (SumInt64) Identity

func (SumInt64) Identity() int64

Jump to

Keyboard shortcuts

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