Skip to content

Releases: ShaneDolphin/gorapide

v0.2.4

Choose a tag to compare

@ShaneDolphin ShaneDolphin released this 24 Aug 01:51

GoRapide v0.2.4.

Performance fix on the poset query path: the causal-equivalence quotient
introduced in v0.2.0 made causalClassSuccessorsLocked /
causalClassPredecessorsLocked (and the class-introspection helpers) scan the
entire poset on every call, turning every O(V+E) reachability walk —
IsCausallyBefore, IsCausallyIndependent, CausalAncestors /
CausalDescendants, and every pattern.Seq / ImmSeq / Join /
Independent / Within causal check — into O(V²).

A new incremental classMembers index (the inverse of the existing
causalClass map) makes those lookups O(class size x degree) instead of
O(poset size). Observable behavior is unchanged: identical result sets, in
identical canonical EventID order, with identical B/op and allocs/op.

Measured on an Apple M3, -benchtime=200x -count=3:

  • BenchmarkIsCausallyBeforeDeepChain: ~227-235ms/op -> ~0.89-1.72ms/op
    (~130-260x faster)
  • BenchmarkIsCausallyBeforeWithEquivalenceClasses: ~197-213ms/op ->
    ~0.91-1.51ms/op (~130-220x faster)

Full details, plus the v0.2.1-v0.2.3 performance rounds that preceded this
one, are in CHANGELOG.md.

v0.2.3

Choose a tag to compare

@ShaneDolphin ShaneDolphin released this 24 Aug 02:03

GoRapide v0.2.3.

Performance fix on the query path: EventsByName (and the observation-view
path it shares with ObservationViews / AddObservationWithTimings) was
rewritten in v0.2.0 to test observation names by cloning and sorting every
observation of every scanned event, matching or not, then building each
returned view through a clone helper that computed a full Params /
Observations copy it immediately discarded and recomputed.

  • A new unexported (*Event).observationsNamed scans stored observations
    directly with no copying or sorting; only actual matches reach eventView.
  • eventView builds the view directly instead of routing through
    cloneEvent, and no longer deep-copies the matched observation's Params
    map twice.
  • Which (event, observation) pairs match, their values, and their sort order
    are unchanged. Pinned by TestEventsByNameContract.

Two disclosed aliasing changes — read these before upgrading if you mutate
returned events:

  • Within one returned view, view.Params and the matched
    view.Observations[i].Params are now the same map object rather than two
    independent copies. Confined to that one returned view; it never reaches the
    poset's stored state or any other view.
  • A legacy (non-deterministic) event matched via its own primary
    Name/Source role now returns the shared, frozen stored *Event pointer
    instead of a cloned view — the same aliasing norm Event() and Events()
    already use. Callers must not mutate such a match. Secondary observation
    roles and all matches on deterministic events are unchanged and still return
    isolated, defensively-copied views.

Measured on an Apple M3, no -race; B/op and allocs/op were exactly
reproducible and are the reliable signal (ns/op was noisy):

  • BenchmarkEventsByName: ~2.50MB/op and 23,261 allocs/op ->
    164,528 B/op and 1,511 allocs/op.
  • BenchmarkEventsByNameLegacyPrimary: 244,528 B/op and 1,761 allocs/op ->
    16,528 B/op and 261 allocs/op (~93% fewer bytes, ~85% fewer allocations).

Full details in CHANGELOG.md.

v0.2.2

Choose a tag to compare

@ShaneDolphin ShaneDolphin released this 24 Aug 02:03

GoRapide v0.2.2.

Performance fix on the causal-insert path: v0.2.0's timing-closure validation
on AddEventWithCause and addCausalLocked rode helpers that scanned the
entire event store per call, turning insertion of a long causal chain into
O(n^2) work even when no event in the poset carried any EventTiming.

  • AddEventWithCause skips predecessor collection and the conflict check
    entirely when the incoming event carries no timing.
  • addCausalLocked tracks a poset-wide count of stored occurrences carrying a
    Rapide interval and skips the O(closure) timing-closure scan while it is
    zero. The count is kept exact through a single storage chokepoint used by
    every path that writes an occurrence into the store, including
    AddObservationWithTimings and Poset.UnmarshalJSON.
  • Behavior for any poset containing at least one timing is unchanged:
    validation still runs the full closure scan exactly as before.

Measured on an Apple M3, no -race — BenchmarkLinearChainInsertUntimed
(1,000-event untimed linear chain): ~17.8-20.6s per chain build ->
~46-49ms, roughly 380-440x faster, scaling close to linearly instead of
quadratically in chain length.

Full details in CHANGELOG.md.

v0.2.1

Choose a tag to compare

@ShaneDolphin ShaneDolphin released this 24 Aug 02:03

GoRapide v0.2.1.

Distribution-only release: the engineering documentation corpus is no longer
part of the repository or the module distribution. It is maintained privately
by the authors.

No code changes.

0.1.0

Choose a tag to compare

@ShaneDolphin ShaneDolphin released this 05 Apr 12:15

The initial release of GoRapide. This version is stable, and production ready. GoRapide is a module that mirrors the syntax, primitives, and functionality of RAPIDE, developed at Stanford University from 1992 to 1998.