Skip to content

Tree-Mendous 1.2.0

Latest

Choose a tag to compare

@josephjohncox josephjohncox released this 22 Jul 23:43
5ddd6ff

Tree-Mendous 1.2.0

A compatible feature release. It adds a faster native RangeSet mutation
surface with a caller-selectable locking level, plus behavior-preserving
snapshot and lease caching. The stable 1.0.0, 1.1.0, and 1.1.1 APIs are
unchanged and existing applications require no migration.

Selectable locking level

RangeSet, create_range_set, and BackendRegistry.create accept a new
synchronized keyword.

  • synchronized=True (the default) keeps the reentrant internal lock and full
    thread-safety, including snapshot/mutation consistency.
  • synchronized=False performs no internal synchronization: the reentrancy
    guard still functions, but the caller alone owns cross-thread safety and
    snapshot/mutation consistency. Choose it only under a caller-owned locking
    discipline or confirmed single-threaded use. RangeSet.synchronized reports
    the selected level.

Fully-native scalar mutators

RangeSet gains two geometry-only scalar mutators that build no
MutationResult:

  • release(span) -> int — free semantics, the scalar counterpart of add.
  • reserve(span, *, require_covered=False) -> int — occupy semantics, the
    scalar counterpart of discard; a not-fully-covered strict reserve is a 0
    no-op.

Both return only the changed length and are exactly geometry-consistent with
add/discard. They require an authoritative geometry-only range set without a
payload policy and raise ValueError rather than falling back silently.

Faster add/discard

On the authoritative cpp_boundary path, add/discard now build their
MutationResult through validation-free native constructors for coordinates the
backend has already validated, and call cached bound native mutators directly,
removing the adapter wrapper frame and a per-operation isinstance check. The
returned MutationResult, Span, and IntervalResult values are unchanged.

Scoped hot-path evidence on cpp_boundary (Apple M5 Max, macOS 26.5.1, CPython
3.12.7, timing public mutation calls only): add/discard about 1.5–1.7M
ops/s, the scalar release/reserve about 4.3M ops/s synchronized and about
5.0M ops/s unsynchronized, against a raw-native floor near 7.9M ops/s. See
docs/performance.md; this is scoped evidence for one
interface family and workload, not a universal claim.

Backend, protocol, and native surface

  • BackendAdapter exposes supports_scalar_delta, release_delta_length, and
    reserve_delta_length.
  • RangeSetProtocol gains release and reserve.
  • The C++ IntervalManager exposes release_delta_length and
    reserve_delta_length returning the changed length, and builds its delta
    results without re-validating already-validated int64 geometry. A
    construction-time probe verifies an authoritative backend's delta contract and
    fails closed otherwise.

Behavior-preserving performance

  • Geometry-only RangeSet.snapshot() reuses one immutable snapshot while the
    geometry is unchanged and re-materializes after any changed mutation.
    Payload-bearing snapshots keep their clone-and-detach behavior.
  • The shared lease pool caches lazy immutable lease/availability projections and
    validates fences through an O(1) token lookup, removing repeated free-state
    rebuilds and public-snapshot scans in the leasing engines.

Compatibility

Every addition is compatible. add, discard, MutationResult, Span, and
IntervalResult retain their exact semantics and types. synchronized=False is
opt-in with a documented single-threaded or externally-synchronized contract.
The treemendous.exact_batch module and the experimental multidimensional
indexes are unchanged.