API Reference
Every public OptiPine type, function, method and enum, with the library's own parameter names and defaults.
Import
//@version=6
indicator("My Script", overlay = false)
import Alien_Algorithms/OptiPine/1 as opWith the alias op, constructors, presets and free functions are called as op.name(), types are written op.TypeName, and methods are called on the object they belong to. Use the latest version number shown on the TradingView publication.
Families with identical methods are listed once: the five Memos under FloatMemo, the five typed stores under IntFloatStore, the two row rings under FloatRowRing, and the two double buffers under FloatDoubleBuffer. Methods that configure or write usually return their receiver, so calls chain.
Watch
| Type | What it is |
|---|---|
op.Watch | Remembers whether something changed since it last looked. |
changed() has one overload per source: int, float, bool, string, color, the five primitive arrays, FloatRowRing and IntRowRing.
| Call | Description |
|---|---|
op.watch() | Creates an exact dependency watch. Returns a new Watch with empty retained storage. |
watch.watchInts(array<int> values, NaCollectionPolicy naPolicy = NaCollectionPolicy.exact) | Adds one int collection dependency to the current pass. Returns the receiver, so calls chain. |
watch.watchFloats(array<float> values, NaCollectionPolicy naPolicy = NaCollectionPolicy.exact) | Adds one float collection dependency to the current pass. Returns the receiver, so calls chain. |
watch.watchColors(array<color> values, NaCollectionPolicy naPolicy = NaCollectionPolicy.exact) | Adds one color collection dependency to the current pass. Returns the receiver, so calls chain. |
watch.watchStrings(array<string> values, NaCollectionPolicy naPolicy = NaCollectionPolicy.exact) | Adds one string collection dependency to the current pass. Returns the receiver, so calls chain. |
watch.watchBools(array<bool> values) | Adds one bool collection dependency to the current pass. Returns the receiver, so calls chain. |
watch.begin() | Starts one dependency comparison pass. Returns the receiver, so calls chain. |
watch.watchInt(int value) | Adds one integer dependency to the current pass. Returns the receiver, so calls chain. |
watch.watchBool(bool value) | Adds one Boolean dependency, stored as 0 or 1. Pine v6 booleans are never na, so no na branch is needed here. Returns the receiver, so calls chain. |
watch.watchFloat(float value) | Adds one float dependency using exact na-aware equality. Returns the receiver, so calls chain. |
watch.watchString(string value) | Adds one string dependency using exact na-aware equality. Returns the receiver, so calls chain. |
watch.watchColor(color value) | Adds one color dependency using exact na-aware equality. Returns the receiver, so calls chain. |
watch.finish() | Completes the pass. Returns true when any dependency changed, when the dependency arity changed, when this is the first pass, or when invalidate() was called. |
watch.invalidate() | Forces the next observation to report a change, whichever API the caller uses. Returns the receiver, so calls chain. |
watch.isChanged() | Reports whether the pass in progress has already seen a change. Returns the current pass change flag. |
watch.reset() | Discards every stored dependency value and arity, retaining the array allocations. The next observation reports a change, through either finish() or any changed() overload. Returns the receiver, so calls chain. |
watch.arity() | Total number of dependencies recorded by the last completed pass. Returns the summed arity across every scalar type plus every watched collection. One collection counts as one dependency regardless of how many elements it holds. |
watch.changed(int value) | Reports whether this int differs from the one last observed, and adopts it as the new baseline. Complexity: O(1). No allocation. Returns true on the first observation and whenever value differs exactly from the previously observed one. |
watch.changed(float value) | Reports whether this float differs from the one last observed, and adopts it as the new baseline. Complexity: O(1). No allocation. Returns true on the first observation and whenever value differs exactly from the previously observed one. |
watch.changed(bool value) | Reports whether this bool differs from the one last observed, and adopts it as the new baseline. Complexity: O(1). No allocation. Returns true on the first observation and whenever value differs exactly from the previously observed one. |
watch.changed(string value) | Reports whether this string differs from the one last observed, and adopts it as the new baseline. Complexity: O(1). No allocation. Returns true on the first observation and whenever value differs exactly from the previously observed one. |
watch.changed(color value) | Reports whether this color differs from the one last observed, and adopts it as the new baseline. Complexity: O(1). No allocation. Returns true on the first observation and whenever value differs exactly from the previously observed one. |
watch.changed(array<int> values) | Reports whether this int collection differs from the one last observed, and adopts it as the new baseline. Complexity: O(N) to compare. The O(N) copy is paid only on the passes that report a change, so a steady collection costs one comparison per bar and no writes. Returns true on the first observation and whenever the contents differ. |
watch.changed(array<float> values) | Reports whether this float collection differs from the one last observed, and adopts it as the new baseline. Complexity: O(N) to compare. The O(N) copy is paid only on the passes that report a change, so a steady collection costs one comparison per bar and no writes. Returns true on the first observation and whenever the contents differ. |
watch.changed(array<bool> values) | Reports whether this bool collection differs from the one last observed, and adopts it as the new baseline. Complexity: O(N) to compare. The O(N) copy is paid only on the passes that report a change, so a steady collection costs one comparison per bar and no writes. Returns true on the first observation and whenever the contents differ. |
watch.changed(array<color> values) | Reports whether this color collection differs from the one last observed, and adopts it as the new baseline. Complexity: O(N) to compare. The O(N) copy is paid only on the passes that report a change, so a steady collection costs one comparison per bar and no writes. Returns true on the first observation and whenever the contents differ. |
watch.changed(array<string> values) | Reports whether this string collection differs from the one last observed, and adopts it as the new baseline. Complexity: O(N) to compare. The O(N) copy is paid only on the passes that report a change, so a steady collection costs one comparison per bar and no writes. Returns true on the first observation and whenever the contents differ. |
watch.changed(FloatRowRing source) | Reports whether the ring's contents changed since last observed, and adopts the current state as the new baseline. Complexity: O(1), whatever the ring's capacity and width. The backing array is never compared or copied. Returns true on the first observation and whenever the ring's content revision differs from the one last seen. |
watch.changed(IntRowRing source) | Reports whether the ring's contents changed since last observed, and adopts the current state as the new baseline. Complexity: O(1), whatever the ring's capacity and width. The backing array is never compared or copied. Returns true on the first observation and whenever the ring's content revision differs from the one last seen. |
NaCollectionPolicy
| Value | Meaning |
|---|---|
op.NaCollectionPolicy.exact | na equals na, using OptiPine's exact comparators. Two passes holding na in the same position report no change. |
op.NaCollectionPolicy.alwaysChanged | A collection containing any na element reports changed on every pass. Use this when na means "not computable yet" and a cached result derived from it must never be reused. |
op.NaCollectionPolicy.reject | Raise on the first na element. |
Memo
| Type | What it is |
|---|---|
op.FloatMemo | One cached float plus an exact dependency Watch. Complexity: O(number of dependencies) per pass. |
op.intMemo(), op.boolMemo(), op.stringMemo() and op.colorMemo() create IntMemo, BoolMemo, StringMemo and ColorMemo, with the same methods for an int, bool, string or color value. BoolMemo falls back to false; the others to na.
| Call | Description |
|---|---|
op.floatMemo() | Creates a memoized float holder. Returns a new FloatMemo. |
memo.begin() | Starts an explicit dependency pass. Returns the receiver, so calls chain. |
memo.miss() | Completes an explicit pass. Returns true when the value must be recomputed. |
memo.staleOn(float firstValue = na, float secondValue = na, float thirdValue = na, float fourthValue = na, int firstKey = na, int secondKey = na, bool flag = false, string tag = na) | One-call dependency check. The watched arity is fixed at eight slots regardless of how many arguments are supplied, so omitting trailing arguments does not register as a dependency change. Returns true when the value must be recomputed. |
memo.store(float value) | Stores a recomputed value and marks the memo valid. Returns the receiver, so calls chain. |
memo.get(float fallback = na) | Reads the cached value. Returns the cached value, or fallback. |
memo.isValid() | Reports whether a value has been stored. Returns true once store() has been called and not invalidated since. |
memo.invalidate() | Discards the cached value and forces the next check to miss. Returns the receiver, so calls chain. |
Revision
| Type | What it is |
|---|---|
op.Revision | Monotonic invalidation token for state OptiPine cannot observe. Producers call bump() after a meaningful state change; consumers store the last observed value and compare with changedSince() instead of rescanning the producer. Complexity: all operations O(1). No allocation. Limits: wraps to 0 after 2,000,000,000 bumps. A consumer holding a snapshot taken exactly one full wrap earlier would miss the change. That requires 2e9 bumps and is documented rather than guarded. |
| Call | Description |
|---|---|
op.revision(int initialValue = 0) | Creates a revision token. Returns a new Revision. |
revision.bump() | Advances the revision. Returns the new revision value. |
revision.current() | Reads the current revision without changing it. Returns the current revision value. |
revision.changedSince(int snapshot) | Tests a consumer snapshot against the current revision. Returns true when the snapshot is stale. |
revision.set(int value) | Assigns an explicit revision value. Returns the receiver, so calls chain. |
revision.reset() | Returns the revision to 0. Returns the receiver, so calls chain. |
CadenceGate
| Type | What it is |
|---|---|
op.CadenceGate | Stateful gate for work that should run at a minimum tick interval, and optionally only when its producer changed as well. Complexity: O(1). No allocation. |
| Call | Description |
|---|---|
op.cadenceGate() | Creates a cadence gate that is due on its first check. Returns a new CadenceGate. |
gate.peek(int tick, int interval = 1, bool force = false) | Tests whether the cadence is open, without consuming the gate. Returns true when a due() call with the same arguments would run. |
gate.due(int tick, int interval = 1, bool force = false) | Consumes the gate and reports whether work is due. Returns true when work should run now. The tick is recorded only when this returns true, so a gate that stays closed does not drift. |
gate.dueWhenChanged(int tick, int revision, int interval = 1, bool force = false) | Consumes the gate and reports whether work is due *and* the producer changed since the last run. Returns true when work should run now. The tick and revision are recorded only when this returns true. |
gate.runs() | Number of consumed runs. Returns the run counter. |
gate.reset() | Returns the gate to its initial state, so the next check is due. Returns the receiver, so calls chain. |
Rings
| Type | What it is |
|---|---|
op.RingConfig | Configuration for row rings. |
op.RingCursor | Ring-buffer layout independent of payload type. Complexity: every operation O(1). No allocation. |
op.FloatRowRing | Fixed-capacity ring of equal-width float rows in one flat array. Complexity: push() is O(width); pushValue() and every scalar accessor are O(1); revision() is O(1). Limits: capacity * width may not exceed 100,000. |
IntRowRing has the same methods with int values. watch.changed(ring) detects a change to either ring type in O(1).
| Call | Description |
|---|---|
op.ringConfig(int capacity = 1, int width = 1, bool preallocate = true) | Creates a row-ring configuration. Returns a new RingConfig with capacity and width clamped to at least 1. |
op.ringCursor(int capacity) | Creates a ring cursor. Returns a new empty RingCursor. |
op.floatRowRing(int capacity, int width, bool preallocate = true, float fillValue = 0.0) | Creates a flat float row ring. Returns a new FloatRowRing. |
op.floatRowRingFrom(RingConfig settings, float fillValue = 0.0) | Creates a flat float row ring from a configuration object. Returns a new FloatRowRing. |
op.intRowRing(int capacity, int width, bool preallocate = true, int fillValue = 0) | Creates a flat int row ring. Returns a new IntRowRing. |
op.intRowRingFrom(RingConfig settings, int fillValue = 0) | Creates a flat int row ring from a configuration object. Returns a new IntRowRing. |
cursor.reserve() | Reserves the physical slot for one new newest item and advances the ring. Once the ring is full this overwrites the oldest slot. Returns the physical slot to write. |
cursor.physical(int logicalIndex) | Maps a chronological logical index to a physical slot. Returns the physical slot, or -1 when the logical index is not occupied. |
cursor.logical(int physicalSlot) | Maps a physical slot back to its chronological logical index. Returns the logical index, or -1 when the slot is not occupied. |
cursor.newest(int offset = 0) | Physical slot at an offset back from the newest item. Returns the physical slot, or -1 when the offset is out of range. |
cursor.oldest(int offset = 0) | Physical slot at an offset forward from the oldest item. Returns the physical slot, or -1 when the offset is out of range. |
cursor.full() | Whether every physical slot is occupied. Returns true when size has reached capacity. |
cursor.count() | Number of occupied slots. Returns the occupied count. |
cursor.limit() | Physical slot count. Returns the capacity. |
cursor.clear() | Empties the ring without touching any payload storage. Returns the receiver, so calls chain. |
ring.push(array<float> row) | Appends one complete row as the newest row. revision: bump. Returns the physical slot written. |
ring.pushValue(float value) | Appends one scalar as the newest row of a width-1 ring without allocating a row array. revision: bump. Returns the physical slot written. |
ring.reserveRowUnchecked() | Advances the ring and returns the physical slot for the new newest row without writing anything. Precondition: write every column with writeUnchecked() before the reserved row is observed. revision: bump. Returns the physical slot to write. |
ring.writePhysical(int slot, array<float> row) | Writes a complete row into an existing physical slot without advancing the ring. revision: bump on a valid write. Returns true when the slot and row width were valid. |
ring.writeUnchecked(int slot, int column, float value) | Writes one value by physical address with no validation. revision: bump. Returns the receiver, so calls chain. |
ring.at(int logicalRow, int column) | Reads one value by chronological row and column. Returns the value, or na when the address is not occupied. |
ring.setAt(int logicalRow, int column, float value) | Writes one value by chronological row and column. revision: bump-if-changed. Returns true when the address was occupied. An identical value leaves the revision unchanged. |
ring.newestAt(int offset, int column) | Reads one value at an offset back from the newest row. Returns the value, or na when the address is not occupied. |
ring.gather(array<int> logicalRows, array<float> output = na) | Gathers selected chronological rows into one flat array. Returns the gathered rows concatenated in request order. Rows that are not occupied contribute width na values. |
ring.chronological(array<float> output = na) | Copies every occupied row in chronological order. Returns all occupied rows concatenated oldest to newest. |
ring.window(int startLogicalRow, int rowCount, array<float> output = na) | Copies a contiguous run of chronological rows. Returns the requested rows concatenated oldest to newest, rowCount * width elements long. Raises when the window is outside the retained range. |
ring.rowView(int logicalRow) | One chronological row, without copying it. Ownership: borrowed read-only slice of the backing array. Mutation: read-only by contract. Use setAt() or an edit scope. Lifetime: valid until the backing array is resized. Persistence: reacquire after that boundary. Returns the row's width values, or na when the row is not occupied. |
ring.rawView() | The flat backing array, in row-major physical order. Ownership: borrowed structure-owned view. Mutation: read-only by contract. Use an edit scope for writes. Lifetime: valid until the backing array is resized. Persistence: reacquire after that boundary. Returns the backing storage. |
ring.editBegin() | Opens a scope in which rawUnsafe() may be called. revision: caller-repairs. editFinish() performs the bump. Returns the receiver, so calls chain. |
ring.rawUnsafe() | The flat backing array, for direct mutation. Ownership: borrowed structure-owned mutable view. Mutation: overwrite elements only inside an open edit scope. Do not resize the array. Lifetime: do not retain it past editFinish(). Repair: editFinish() advances the content revision. revision: caller-repairs. Returns the backing storage, in row-major physical order. |
ring.editFinish() | Closes the edit scope and performs the invalidation the raw writes could not. revision: bump. Returns the receiver, so calls chain. |
ring.physicalRow(int logicalRow) | Physical slot for a chronological row. Returns the physical slot, or -1 when the row is not occupied. |
ring.rowCount() | Number of occupied rows. Returns the row count. |
ring.rowWidth() | Values per row. Returns the row width. |
ring.rowCapacity() | Maximum number of rows. Returns the ring capacity. |
ring.clear() | Empties the ring. Preallocated storage keeps its values until they are overwritten; on-demand storage is released. revision: bump-if-changed. Returns the receiver, so calls chain. |
ring.revision() | Current content revision. Complexity: O(1). Returns the current revision. Always >= 0. |
Ring and matrix helpers
For arrays you own laid out by a RingCursor, and for converting between flat arrays and matrices.
| Call | Description |
|---|---|
op.copyLogicalFloatRow(array<float> store, int width, RingCursor cursor, int logicalRow, array<float> output, int outputRow = 0) | Copies one logical row into output at row outputRow. Returns the output array. |
op.gatherLogicalFloatRows(array<float> store, int width, RingCursor cursor, array<int> logicalRows, array<float> output = na) | Copies the rows named in logicalRows, in request order, into one flat row-major array. Returns the caller-owned output array, logicalRows.size() * width long. |
op.copyLogicalFloatWindow(array<float> store, int width, RingCursor cursor, int startLogicalRow, int rowCount, array<float> output = na) | Copies rowCount consecutive logical rows starting at startLogicalRow into one flat row-major array. Returns the caller-owned output array, rowCount * width long. |
op.copyChronologicalFloatRows(array<float> store, int width, RingCursor cursor, array<float> output = na) | Copies every retained row, oldest first, into one flat row-major array. Returns the caller-owned output array, cursor.count() * width long. |
op.transposeFlatFloat(array<float> source, int rows, int columns, array<float> output = na) | Transposes a flat row-major matrix into a flat column-major one. Returns the caller-owned output array, rows * columns long, holding the transposed matrix in row-major order. |
op.copyLogicalIntRow(array<int> store, int width, RingCursor cursor, int logicalRow, array<int> output, int outputRow = 0) | Copies one logical row into output at row outputRow. Returns the output array. |
op.gatherLogicalIntRows(array<int> store, int width, RingCursor cursor, array<int> logicalRows, array<int> output = na) | Copies the rows named in logicalRows, in request order, into one flat row-major array. Returns the caller-owned output array, logicalRows.size() * width long. |
op.copyLogicalIntWindow(array<int> store, int width, RingCursor cursor, int startLogicalRow, int rowCount, array<int> output = na) | Copies rowCount consecutive logical rows starting at startLogicalRow into one flat row-major array. Returns the caller-owned output array, rowCount * width long. |
op.copyChronologicalIntRows(array<int> store, int width, RingCursor cursor, array<int> output = na) | Copies every retained row, oldest first, into one flat row-major array. Returns the caller-owned output array, cursor.count() * width long. |
op.transposeFlatInt(array<int> source, int rows, int columns, array<int> output = na) | Transposes a flat row-major matrix into a flat column-major one. Returns the caller-owned output array, rows * columns long, holding the transposed matrix in row-major order. |
op.matrixFromFlat(array<float> source, int rows, int columns, int startIndex = 0) | Converts a contiguous flat float range into a matrix by adding one native row and reshaping. Returns a newly allocated caller-owned matrix. When the requested range is not fully present in source, a zero-filled matrix of the requested shape is returned instead. |
op.flatFromFloatMatrix(matrix<float> source, array<float> output = na) | Copies a matrix into caller-owned flat row-major storage. Returns the matrix contents in row-major order. |
op.intMatrixFromFlat(array<int> source, int rows, int columns, int startIndex = 0) | Converts a contiguous flat int range into a matrix by adding one native row and reshaping. Returns a newly allocated caller-owned matrix. When the requested range is not fully present in source, a zero-filled matrix of the requested shape is returned instead. |
op.flatFromIntMatrix(matrix<int> source, array<int> output = na) | Copies a matrix into caller-owned flat row-major storage. Returns the matrix contents in row-major order. |
Slot pools
| Type | What it is |
|---|---|
op.SlotPoolConfig | Configuration for frame-scoped and explicitly managed slot pools. |
op.StablePool | Maps integer keys to stable, reusable slots with explicit lifetime. Complexity: acquire(), release(), find() are O(1); slots() is O(1) to obtain and O(live count) to traverse. Limits: 50,000 live keys, or SlotPoolConfig.maxSlots when lower. |
op.SlotCache | Maps integer keys to stable, reusable slots with frame-scoped lifetime. Complexity: acquire() O(1); finish() O(slots active in the previous frame). Limits: 50,000 live keys, or SlotPoolConfig.maxSlots when lower. |
| Call | Description |
|---|---|
op.slotPoolConfig(bool strictLifecycle = true, int maxSlots = 50000) | Creates a slot-pool configuration. Returns a new SlotPoolConfig. |
op.poolConfigFrameRetained() | Preset: slots live for exactly one frame unless re-acquired. Returns a SlotPoolConfig. |
op.poolConfigLenient() | Preset: lifecycle violations degrade instead of raising, for scripts that must never halt on a misuse. Returns a SlotPoolConfig. |
op.stablePool(SlotPoolConfig settings = na) | Creates an explicitly managed slot pool. Returns a new StablePool. |
op.slotCache(SlotPoolConfig settings = na) | Creates a frame-scoped slot cache. Returns a new SlotCache. |
pool.acquire(int key) | Gets or creates the stable slot for a key. Returns [slot, created]. A created slot may be recycled storage whose payload still holds the previous occupant's values. |
pool.release(int key) | Releases the slot owned by a key and returns it to the free list. Returns the released slot, or -1 when the key was not live. |
pool.releaseSlot(int slot) | Releases a slot by index rather than by key. Returns true when the slot was live and has been released. |
pool.find(int key) | Looks up a key. Returns the slot, or -1 on a miss. |
pool.contains(int key) | Tests whether a key is live. Returns true when the key currently owns a slot. |
pool.keyAt(int slot) | Reads the key currently assigned to a slot. Returns the key, or na when the slot does not exist. A released slot still reports its last key until it is recycled. |
pool.slots() | The slots currently live in the pool. Ownership: borrowed structure-owned view. Mutation: read-only by contract; mutation is unsupported. The pool releases in O(1) by swapping with the last element and mirrors each position in slotPosition, so reordering it desynchronizes both. Lifetime: valid until the next acquire(), release(), releaseSlot() or clear(). Persistence: do not retain it across that boundary; reacquire it. Order is unspecified, and a release() reorders the survivors. Returns the live slots, in unspecified order. |
pool.size() | Number of live keys. Returns the live count. |
pool.slotCount() | Total slots ever allocated, including released ones. Returns the slot count. |
pool.freeCount() | Number of slots available for reuse. Returns the free count. |
pool.clear() | Empties the pool, retaining every allocation. Returns the receiver, so calls chain. |
cache.begin() | Opens a frame. The slots active in the previous frame become the retirement candidates, and the retired list is emptied. Returns the receiver, so calls chain. |
cache.acquire(int key) | Gets or creates the stable slot for a key and marks it active. Returns [slot, created]. A created slot may be recycled storage whose payload still holds the previous occupant's values. |
cache.finish() | Closes the frame, retires every slot not acquired during it, and returns the retired list so the caller can reset those payloads. Ownership: borrowed structure-owned view. It is the same array retired() returns. Mutation: read-only by contract; mutation is unsupported. Lifetime: valid until the next begin() or clear(). Persistence: do not retain it across that boundary; use retiredCopy() when the result must outlive the frame. Returns the slots retired by this call, in the order they were acquired. Their payloads may be reset now or left intact for overwrite when the slots are recycled. |
cache.active() | The slots acquired during the frame in progress. Ownership: borrowed structure-owned view. Mutation: read-only by contract; mutation is unsupported. This is the array finish() reads to decide what survives the frame. Lifetime: valid until the next begin() or clear(). Persistence: do not retain it across that boundary; use activeCopy() for an owned snapshot. Returns the active slots, in acquisition order. |
cache.retired() | The slots retired by the most recent finish(). Ownership: borrowed structure-owned view. Mutation: read-only by contract; mutation is unsupported. Lifetime: valid until the next begin() or clear(). Persistence: do not retain it across that boundary; use retiredCopy() for an owned snapshot. Returns the retired slots, in retirement order. |
cache.activeCopy(array<int> output = na) | Copies the active slot list into caller-owned storage. Returns the active slots in acquisition order, owned by the caller. |
cache.retiredCopy(array<int> output = na) | Copies the retired slot list into caller-owned storage. Returns the retired slots in retirement order, owned by the caller. |
cache.find(int key) | Looks up a key without changing its active status. Returns the slot, or -1 on a miss. |
cache.contains(int key) | Tests whether a key is live. Returns true when the key currently owns a slot. |
cache.keyAt(int slot) | Reads the key currently assigned to a slot. Returns the key, or na when the slot does not exist. A retired slot still reports its last key until it is recycled. |
cache.slotCount() | Total slots ever allocated, including free ones. Returns the slot count. |
cache.size() | Number of live keys. Returns the live count. |
cache.freeCount() | Number of slots available for reuse. Returns the free count. |
cache.frame() | Current frame counter, mainly for diagnostics. Returns the generation. |
cache.clear() | Empties the cache, retaining every allocation. Returns the receiver, so calls chain. |
DirtySet
| Type | What it is |
|---|---|
op.DirtySet | Deduplicated sparse integer set using generation stamps and a compact discovery-order list. Complexity: begin() O(1) amortized (O(growth) when the universe grows, O(universe) once per two billion cycles at rollover); mark() O(1); markMany() O(batch); values() O(1) to obtain and O(dirty count) to traverse, never O(universe). Limits: the universe may not exceed 100,000 entries. |
| Call | Description |
|---|---|
op.dirtySet(int universeSize = 0) | Creates a sparse dirty set. Returns a new DirtySet with stamps preallocated. |
dirty.begin(int universeSize = na) | Starts a sparse-work cycle and optionally resizes the universe. Growing the universe keeps existing stamps; shrinking it only narrows the accepted index range and retains the allocation. Returns the receiver, so calls chain. |
dirty.mark(int index) | Marks one index for the current cycle. Returns true only for the first mark of this index in this cycle. |
dirty.markMany(array<int> indices) | Marks every index in an array. Duplicate and out-of-range indices are ignored. Complexity: O(batch), independent of the universe size. Returns the number of indices this call added to the dirty list, which is the count of first marks and so excludes duplicates and rejects. |
dirty.markUnchecked(int index) | Marks one index without bounds validation. Returns true only for the first mark of this index in this cycle. |
dirty.markRange(int first, int last) | Marks every index in an inclusive range, clipped to the universe. Returns the receiver, so calls chain. |
dirty.contains(int index) | Tests whether an index was marked in the current cycle. Returns true when the index carries the current generation stamp. |
dirty.values() | The indices marked in the current cycle, in discovery order. Ownership: borrowed structure-owned view. Mutation: read-only by contract; mutation is unsupported. The list and the generation stamps describe each other, so appending or clearing it corrupts both. Use valuesCopy() to own or modify it. Lifetime: valid until the next begin() or clear(). Persistence: do not retain it across that boundary; reacquire it. Returns the dirty indices in discovery order. |
dirty.valuesCopy(array<int> output = na) | Copies the dirty indices into caller-owned storage. Returns the dirty indices in discovery order, owned by the caller. |
dirty.size() | Number of distinct indices marked in the current cycle. Returns the dirty count. |
dirty.universe() | Current universe size. Returns the number of tracked indices. |
dirty.cycle() | Current cycle stamp, mainly for diagnostics. Named distinctly from the generation field so a method call is never mistaken for field access. Returns the generation counter. |
dirty.clear() | Discards all marks and stamps while retaining the allocations. The universe size is preserved. Returns the receiver, so calls chain. |
Typed stores
| Type | What it is |
|---|---|
op.IntFloatStore | Integer-keyed float store backed by an adaptive IntIndex. Complexity: inherited from IntIndex, plus O(1) per value access. build() is one index build plus one native payload refill. |
IntIntStore, IntBoolStore, IntStringStore and IntColorStore have the same methods for int, bool, string or color values.
| Call | Description |
|---|---|
op.intIntStore(IndexConfig settings = na) | Creates an integer-keyed int store. Returns a new IntIntStore. |
op.intFloatStore(IndexConfig settings = na) | Creates an integer-keyed float store. Returns a new IntFloatStore. |
op.intBoolStore(IndexConfig settings = na) | Creates an integer-keyed bool store. Returns a new IntBoolStore. |
op.intStringStore(IndexConfig settings = na) | Creates an integer-keyed string store. Returns a new IntStringStore. |
op.intColorStore(IndexConfig settings = na) | Creates an integer-keyed color store. Returns a new IntColorStore. |
store.build(array<int> keys, array<float> values, int expectedQueries = na) | Fills the store from parallel key and value arrays, replacing its previous contents. revision: bump. Returns the active representation the index selected. |
store.revision() | Current content revision. Complexity: O(1). Returns the current revision. Always >= 0. |
store.get(int key, float fallback = na) | Reads one value. Returns the stored value, or fallback. |
store.read(int key) | Reads one value and reports whether it was present. Returns [found, value]. value is na on a miss. |
store.set(int key, float value) | Overwrites the value of an existing key. Keys cannot be added after a build; only values may change. Call build() to change the key set. revision: bump-if-changed. Returns true when the key existed. An identical value leaves the revision unchanged. |
store.contains(int key) | Tests whether a key is present. Returns true when the key resolves to a slot. |
store.getMany(array<int> queryKeys, array<float> output = na) | Resolves a batch of keys into values with one representation dispatch. Returns the value for each query key, in query order. na marks a miss. |
store.size() | Number of stored entries. Returns the entry count. |
store.valuesView() | The stored values in slot order, without copying them. Ownership: borrowed structure-owned view. Mutation: read-only by contract. Use set() for writes. Lifetime: valid until the next build() or clear(). Persistence: do not retain it across that boundary; reacquire it. Returns the values, indexed by slot. |
store.clear() | Empties the store, retaining every allocation. revision: bump-if-changed. Returns the receiver, so calls chain. |
Index configuration
| Type | What it is |
|---|---|
op.IndexConfig | Configuration for IntIndex and every keyed store built on it. |
| Call | Description |
|---|---|
op.indexConfig(LookupPolicy policy = LookupPolicy.automatic, DuplicatePolicy duplicates = DuplicatePolicy.raiseError, float promoteQueryRatio = 0.10, int promoteMinQueries = 32, bool autoPromote = false, bool validateAscending = true, int maxDenseSpan = 100000, float autoDenseSpanRatio = 2.0, int autoDenseMaxSpan = 16384, int linearMaxEntries = 0, int duplicateScanLimit = 64, bool collectStats = false, bool strictLifecycle = true) | Creates a keyed-index configuration. Returns a new IndexConfig with every argument clamped to a valid range. |
op.indexConfigStaticSorted() | Preset: a directory built once and queried across many bars. Forces sorted binary search, which needs no extra storage for an ascending build and never allocates a map. Returns an IndexConfig. |
op.indexConfigDense() | Preset: direct addressing for validated dense integer keys. Raises when the key span exceeds maxDenseSpan. Returns an IndexConfig. |
op.indexConfigDictionary() | Preset: a persistent map-backed directory for lookup-heavy workloads. Returns an IndexConfig. |
op.indexConfigTiny() | Preset: a very small directory rebuilt far more often than it is queried. No build cost at all; queries use the native scan. Returns an IndexConfig. |
op.indexConfigDynamic() | Preset: automatic selection with online sorted-to-map promotion and counters enabled, for directories whose query volume is unknown until it happens. Returns an IndexConfig. |
LookupPolicy
| Value | Meaning |
|---|---|
op.LookupPolicy.automatic | Select a representation at buildFinish() from the observed key layout and, when supplied, the expected query horizon. |
op.LookupPolicy.linear | No build at all. Queries scan the insertion-order key array with the native indexof/lastindexof built-ins. Correct for any key layout and the cheapest choice when a directory is rebuilt far more often than it is queried. |
op.LookupPolicy.sorted | Native binary search. Strictly ascending builds search the key array directly with no extra storage; any other order builds a sorted key array plus a slot indirection array once. |
op.LookupPolicy.dictionary | Map-backed directory. Limited to 50,000 keys by Pine. |
op.LookupPolicy.dense | Direct addressing. A consecutive ascending run needs no table at all; any other layout allocates a span-sized slot table. |
DuplicatePolicy
| Value | Meaning |
|---|---|
op.DuplicatePolicy.raiseError | Always verify uniqueness at buildFinish() and stop with a descriptive error when a duplicate is present. Every representation checks; the method varies from a free adjacent scan to one native sort, but the guarantee does not. |
op.DuplicatePolicy.firstWins | Every lookup resolves to the slot of the first occurrence. |
op.DuplicatePolicy.lastWins | Every lookup resolves to the slot of the last occurrence. |
IntIndex
| Type | What it is |
|---|---|
op.IntIndex | Universal integer-key directory. Complexity: add() O(1). buildFinish() is O(entries) for dense, map and ordered sorted builds; O(entries log entries) for unordered sorted builds; and O(1) for permissive linear mode. Linear duplicate checking may add O(entries squared) below duplicateScanLimit or O(entries log entries) above it. find() is O(1) for dense and map, O(log entries) for sorted, and O(entries) for linear. Limits: 100,000 keys; 50,000 when the map representation is selected. |
| Call | Description |
|---|---|
op.intIndex(IndexConfig settings = na) | Creates an integer-key directory. Returns a new IntIndex in the empty state. |
index.buildBegin(bool expectedAscending = true) | Starts a build and clears prior key data, retaining every allocation. Calling it on a sealed index restarts the build. Returns the receiver, so calls chain. |
index.add(int key) | Adds one key and returns its payload slot. Slots are assigned in insertion order starting at 0. Returns the slot for this key. |
index.addMany(array<int> keyBatch) | Adds every key of an array in order. Returns the slot of the first added key, or -1 for an empty batch. |
index.buildFinish(int expectedQueries = na) | Completes construction and selects the lookup representation. Calling it again on a sealed index is a no-op. Returns the active representation. |
index.find(int key) | Finds one key using the active lookup representation. Returns the slot, or -1 on a miss. |
index.contains(int key) | Tests whether a key is present. Returns true when the key resolves to a slot. |
index.findMany(array<int> queryKeys, array<int> output = na) | Resolves a batch of keys into slots, dispatching once. Returns the slot for each query key, in query order. -1 marks a miss. |
index.keyAt(int slot) | Reads the key stored in a slot. Returns the key, or na when the slot does not exist. |
index.entryCount() | Number of keys added. Returns the entry count. |
index.mode() | Representation currently in use. Returns the active LookupPolicy. Never automatic. |
index.sealed() | Whether the index is sealed and ready for queries. Returns true after buildFinish(). |
index.keysView() | The insertion-order key array, indexed by slot. Ownership: borrowed structure-owned view. Mutation: read-only by contract. Rebuild to change the keys. Lifetime: valid until the next buildBegin(), clear() or reset(). Persistence: reacquire after that boundary. Returns the keys, in insertion order, so element slot is keyAt(slot). |
index.stats() | Snapshot of index telemetry. Returns a newly allocated IndexStats owned by the caller. |
index.clear() | Empties the index, retaining every allocation. The configuration and the cumulative build and promotion counters are preserved. Returns the receiver, so calls chain. |
index.reset(IndexConfig settings = na) | Replaces the configuration and empties the index. Returns the receiver, so calls chain. |
IntBuckets
| Type | What it is |
|---|---|
op.IntBuckets | One key to many integer values, in contiguous flat storage. Complexity: build is O(pairs) plus the IntIndex build. find() is the configured IntIndex lookup. rangeByKey() is that plus O(1). Limits: 100,000 associations and 50,000 distinct keys. |
| Call | Description |
|---|---|
op.intBuckets(IndexConfig settings = na, bool strictLifecycle = true) | Creates an empty bucket multimap. Returns a new IntBuckets. |
buckets.buildBegin() | Opens an explicit build. Returns the receiver, so calls chain. |
buckets.add(int key, int value) | Records one key/value pair. Returns the receiver, so calls chain. |
buckets.addMany(array<int> keyArray, array<int> valueArray) | Records a batch of key/value pairs. Returns the receiver, so calls chain. |
buckets.buildFinish(int expectedQueries = na) | Closes the build and packs every bucket into contiguous storage. Returns the receiver, so calls chain. |
buckets.buildFromPairs(array<int> keyArray, array<int> valueArray, int expectedQueries = na) | Builds every bucket from two parallel arrays in one call. Returns the receiver, so calls chain. |
buckets.find(int key) | Resolves a key to its bucket slot. Returns the bucket slot, or -1 when the key has no bucket. |
buckets.contains(int key) | Reports whether a key has a bucket. Returns true when the key was seen during the build. |
buckets.rangeBySlot(int slot) | Contiguous value range of one bucket slot. Returns [start, count] into the flat value array. [0, 0] for an invalid slot. A zero count still needs a guard before a counted loop. |
buckets.rangeByKey(int key) | Contiguous value range of one key. Returns [start, count] into the flat value array, or [-1, 0] on a miss. |
buckets.valueAt(int flatIndex) | Reads one value from the flat value array. Returns the value, or na when the index is outside the built range. |
buckets.bucketValueAt(int slot, int offset) | Reads one value from a bucket by its position within the bucket. Returns the value, or na when either coordinate is out of range. |
buckets.bucketSize(int slot) | Number of values in one bucket. Returns the occupancy, or 0 for an invalid slot. |
buckets.bucketCount() | Number of distinct keys. Returns the bucket count. |
buckets.pairCount() | Total number of stored pairs. Returns the flat value count. |
buckets.keyAt(int slot) | Key owning one bucket slot. Returns the key, or na for an invalid slot. |
buckets.isSealed() | Reports whether a build has completed. Returns true once buildFinish() has run. |
buckets.clear() | Empties every bucket while retaining all allocations. Returns the receiver, so calls chain. |
buckets.offsetsView() | The CSR bucket boundary array. Ownership: borrowed structure-owned view. Mutation: read-only by contract. Lifetime: valid until the next buildBegin(), buildFinish(), buildFromPairs() or clear(). Persistence: reacquire after that boundary. Returns the bucket boundaries, bucketCount() + 1 elements long. |
buckets.valuesView() | The flat value array every bucket is packed into. Ownership: borrowed structure-owned view. Mutation: read-only by contract. Lifetime: valid until the next buildBegin(), buildFinish(), buildFromPairs() or clear(). Persistence: reacquire after that boundary. Returns every bucket's values, grouped and contiguous, in slot order. |
buckets.keysView() | The key array of the underlying directory. Ownership: borrowed structure-owned view from the nested IntIndex. Mutation: read-only by contract. Lifetime: valid until the next buildBegin(), buildFinish(), buildFromPairs() or clear(). Persistence: reacquire after that boundary. Returns the distinct keys, in slot order. |
Double buffers
| Type | What it is |
|---|---|
op.FloatDoubleBuffer | Two retained float arrays whose references swap without copying. Complexity: swap() is O(1) plus the cost of clearing the new current. |
IntDoubleBuffer has the same methods with int arrays. The fields current and previous are the two arrays.
| Call | Description |
|---|---|
op.floatDoubleBuffer() | Creates a double buffer for float values. Returns a new FloatDoubleBuffer with two empty retained arrays. |
op.intDoubleBuffer() | Creates a double buffer for int values. Returns a new IntDoubleBuffer with two empty retained arrays. |
buffer.swap() | Exchanges the two buffers and clears the new current buffer. Returns [current, previous] as structure-owned mutable views. |
buffer.swapSized(int size, float fillValue = 0.0) | Exchanges the two buffers and resizes the new current buffer to a fixed length, overwriting every element. Returns [current, previous] as structure-owned mutable views. |
buffer.clear() | Empties both buffers, retaining their allocations. Returns the receiver, so calls chain. |
Storage utilities
They work on arrays you own and reuse their storage. Constants: op.MAX_ARRAY_ELEMENTS (100,000), op.MAX_MAP_PAIRS (50,000) and op.MAX_GENERATION (2,000,000,000).
| Call | Description |
|---|---|
op.ensureSizeInt(array<int> values, int minimumSize, int fillValue = 0) | Grows values to at least minimumSize by appending fillValue. Mutates in place, never shrinks, and preserves every existing element. Returns the resulting size. |
op.ensureSizeFloat(array<float> values, int minimumSize, float fillValue = 0.0) | Grows values to at least minimumSize by appending fillValue. Mutates in place, never shrinks, and preserves every existing element. Returns the resulting size. |
op.ensureSizeBool(array<bool> values, int minimumSize, bool fillValue = false) | Grows values to at least minimumSize by appending fillValue. Mutates in place, never shrinks, and preserves every existing element. Returns the resulting size. |
op.ensureSizeColor(array<color> values, int minimumSize, color fillValue = na) | Grows values to at least minimumSize by appending fillValue. Mutates in place, never shrinks, and preserves every existing element. Returns the resulting size. |
op.ensureSizeString(array<string> values, int minimumSize, string fillValue = na) | Grows values to at least minimumSize by appending fillValue. Mutates in place, never shrinks, and preserves every existing element. Returns the resulting size. |
op.resizeInt(array<int> values, int size, int fillValue = 0) | Resizes values to exactly size, preserving retained elements. Appends fillValue when growing and pops from the end when shrinking. Mutates in place and retains the allocation. Returns the resulting size. |
op.resizeFloat(array<float> values, int size, float fillValue = 0.0) | Resizes values to exactly size, preserving retained elements. Appends fillValue when growing and pops from the end when shrinking. Mutates in place and retains the allocation. Returns the resulting size. |
op.resizeBool(array<bool> values, int size, bool fillValue = false) | Resizes values to exactly size, preserving retained elements. Appends fillValue when growing and pops from the end when shrinking. Mutates in place and retains the allocation. Returns the resulting size. |
op.resizeColor(array<color> values, int size, color fillValue = na) | Resizes values to exactly size, preserving retained elements. Appends fillValue when growing and pops from the end when shrinking. Mutates in place and retains the allocation. Returns the resulting size. |
op.resizeString(array<string> values, int size, string fillValue = na) | Resizes values to exactly size, preserving retained elements. Appends fillValue when growing and pops from the end when shrinking. Mutates in place and retains the allocation. Returns the resulting size. |
op.refillInt(array<int> values, int size, int fillValue = 0) | Resizes values to exactly size and overwrites every element with fillValue. Retains the allocation. Returns the resulting size. |
op.refillFloat(array<float> values, int size, float fillValue = 0.0) | Resizes values to exactly size and overwrites every element with fillValue. Retains the allocation. Returns the resulting size. |
op.refillBool(array<bool> values, int size, bool fillValue = false) | Resizes values to exactly size and overwrites every element with fillValue. Retains the allocation. Returns the resulting size. |
op.refillColor(array<color> values, int size, color fillValue = na) | Resizes values to exactly size and overwrites every element with fillValue. Retains the allocation. Returns the resulting size. |
op.refillString(array<string> values, int size, string fillValue = na) | Resizes values to exactly size and overwrites every element with fillValue. Retains the allocation. Returns the resulting size. |
op.sameExactInt(array<int> left, array<int> right) | Exact element-by-element equality of two int arrays. Returns true when both arrays hold exactly the same elements in order. |
op.sameExactFloat(array<float> left, array<float> right) | Exact element-by-element equality of two float arrays. Returns true when both arrays hold exactly the same elements in order. |
op.sameExactBool(array<bool> left, array<bool> right) | Exact element-by-element equality of two bool arrays. Returns true when both arrays hold exactly the same elements in order. |
op.sameExactColor(array<color> left, array<color> right) | Exact element-by-element equality of two color arrays. Returns true when both arrays hold exactly the same elements in order. |
op.sameExactString(array<string> left, array<string> right) | Exact element-by-element equality of two string arrays. Returns true when both arrays hold exactly the same elements in order. |
Weight configuration
| Type | What it is |
|---|---|
op.WeightConfig | Configuration for weighted selection. |
| Call | Description |
|---|---|
op.weightConfig(WeightPolicy policy = WeightPolicy.prefix, NaWeightPolicy naWeights = NaWeightPolicy.treatAsZero, NegativeWeightPolicy negativeWeights = NegativeWeightPolicy.clampToZero, ExponentZeroPolicy exponentZero = ExponentZeroPolicy.uniform, int promoteAfterCycles = 2, float sparseUpdateRatio = 0.05) | Creates a weighted-selection configuration. Returns a new WeightConfig with every argument clamped to a valid range. |
op.weightConfigDeterministic() | Preset: bit-reproducible selection. Forces the linear prefix, whose left-to-right addition order never changes. Returns a WeightConfig. |
op.weightConfigStatic() | Preset: weights that rarely change under a stable exponent, where an O(log N) tree pays for itself across many draws. Returns a WeightConfig. |
op.weightConfigSparseUpdates() | Preset: automatic promotion for sparse point updates, such as a prioritized replay buffer whose priorities change a few at a time. Returns a WeightConfig. |
op.weightConfigStrict() | Preset: reject na and negative weights instead of clamping them, for callers that want a bad weight to surface immediately. Returns a WeightConfig. |
WeightPolicy
| Value | Meaning |
|---|---|
op.WeightPolicy.automatic | Start with the linear prefix and promote to a Fenwick tree once the exponent has been stable and updates have stayed sparse. |
op.WeightPolicy.prefix | Rebuilt left-to-right cumulative sums. This is the deterministic baseline: it preserves the exact addition order a hand written prefix implementation would use. |
op.WeightPolicy.fenwick | Binary indexed tree. Point updates and selection are O(log N), but its summation order differs from a linear prefix and can therefore change bit-exact selections at tie boundaries. |
NaWeightPolicy
| Value | Meaning |
|---|---|
op.NaWeightPolicy.treatAsZero | Store 0.0, making the entry unselectable. |
op.NaWeightPolicy.raiseError | Stop with a descriptive error. |
NegativeWeightPolicy
| Value | Meaning |
|---|---|
op.NegativeWeightPolicy.clampToZero | Store 0.0, making the entry unselectable. |
op.NegativeWeightPolicy.raiseError | Stop with a descriptive error. |
ExponentZeroPolicy
| Value | Meaning |
|---|---|
op.ExponentZeroPolicy.uniform | Every entry gets weight 1.0, including zero-weight entries. This is the mathematical result of pow(w, 0) and gives uniform sampling across the whole prepared range. |
op.ExponentZeroPolicy.preserveZeros | Strictly positive weights get 1.0 and zero weights stay 0.0, so a zero-weight entry remains unselectable at every exponent. |
WeightedSampler
| Type | What it is |
|---|---|
op.WeightedSampler | Tier 1 facade over WeightedIndex for the common non-circular case. Complexity: inherited from WeightedIndex. setWeight() is O(1) under the prefix policy and O(log N) while a Fenwick tree is active; setWeights() and setMany() are one batch each. |
| Call | Description |
|---|---|
op.weightedSampler(int capacity, float exponent = 1.0, WeightConfig settings = na) | Creates a weighted sampler. Returns a new WeightedSampler. |
sampler.setWeight(int slot, float weight) | Sets one slot weight. Returns true when the slot was in range. |
sampler.setWeights(array<float> weights) | Replaces every slot weight from one array. Complexity: O(capacity), plus one rebuild of the selection structure on the next draw. Returns the receiver, so calls chain. |
sampler.setMany(array<int> slots, array<float> weights) | Writes weights into selected slots. Complexity: O(batch), plus one rebuild of the selection structure on the next draw. Returns the number of slots actually written, so out-of-range entries are visible to the caller rather than silent. |
sampler.weight(int slot) | Reads one stored slot weight. Returns the normalized weight, or na when the slot is out of range. |
sampler.fill(float weight) | Sets every slot weight to one value. Returns the receiver, so calls chain. |
sampler.setExponent(float exponent) | Changes the selection exponent. Returns the receiver, so calls chain. |
sampler.sample(float fraction) | Draws one slot from a fraction in [0, 1). Returns the selected slot, or -1 when every weight is 0. |
sampler.sampleMany(array<float> fractions, array<int> output = na) | Draws a batch of slots, refreshing derived state once. Returns one slot per fraction, in request order. |
sampler.probability(int slot) | Selection probability of one slot. Returns the probability in [0, 1], or 0.0 when every weight is 0. |
sampler.total() | Transformed total weight across every slot. Returns the total. |
sampler.size() | Number of slots. Returns the capacity. |
sampler.mode() | Representation currently in use. Returns the active WeightPolicy. |
sampler.indexView() | The owned weighted index, for circular ranges, forced policies and scoped weight editing. Ownership: borrowed structure-owned object, not a raw collection. Mutation: supported through the WeightedIndex API. Lifetime: valid for the lifetime of the sampler. Returns the owned WeightedIndex. |
sampler.clear() | Sets every weight to 0 and forgets prepared state. Returns the receiver, so calls chain. |
WeightedIndex
| Type | What it is |
|---|---|
op.WeightedIndex | Reusable weighted-selection index over a circular physical range. Complexity: setWeight() O(1) in prefix mode and O(log N) while a Fenwick tree is valid. draw() O(log N) plus an O(N) refresh on the first read after a weight change in prefix mode. Limits: at most 99,999 weights. |
| Call | Description |
|---|---|
op.weightedIndex(int capacity, WeightConfig settings = na) | Creates a weighted index with every weight at 0. Returns a new WeightedIndex. |
weighted.setWeight(int physicalIndex, float weight) | Sets one physical weight. Writing the value it already holds is a no-op and does not invalidate any derived state. Returns true when the slot was in range. |
weighted.setWeightUnchecked(int physicalIndex, float weight) | Sets one physical weight without bounds checking or weight normalization. Returns the receiver, so calls chain. |
weighted.getWeight(int physicalIndex) | Reads one stored physical weight. Returns the normalized weight, or na when the slot is out of range. |
weighted.fill(float weight) | Sets every weight to one value. Returns the receiver, so calls chain. |
weighted.clear() | Sets every weight to 0 and forgets the prepared exponent, range and representation. Capacity and allocations are retained. Returns the receiver, so calls chain. |
weighted.weightsEditBegin() | Opens a scope in which weightsUnsafe() may be called. Returns the receiver, so calls chain. |
weighted.weightsUnsafe() | Returns the backing weight array for direct mutation. Ownership: borrowed structure-owned mutable view. Mutation: supported only inside an open weightsEditBegin() scope. Retaining the reference past weightsEditFinish() is a contract violation: the structure has no way to observe later writes, and every derived total would silently go stale. Lifetime: do not retain it past weightsEditFinish(). Repair: weightsEditFinish() normalizes the array and rebuilds every derived structure. touchWeights() does the same without closing a scope. |
weighted.touchWeights(bool normalize = true) | Announces that the backing weight array changed and repairs every derived structure. Safe to call without an open edit scope. Returns the receiver, so calls chain. |
weighted.weightsEditFinish(bool normalize = true) | Closes the unsafe edit scope and repairs every derived structure. Returns the receiver, so calls chain. |
weighted.weightsCopy(array<float> output = na) | Copies the weights into caller-owned storage. Returns the weights by physical slot. |
weighted.prepare(float exponent, int startPhysical, int count) | Fixes the selection exponent, the circular range and the representation policy. Returns the receiver, so calls chain. |
weighted.prepareAll(float exponent = 1.0) | Prepares selection over every physical slot. Returns the receiver, so calls chain. |
weighted.draw(float fraction) | Draws one physical slot from a fraction in [0, 1). Returns the selected physical slot, or -1 when the prepared range has no positive total weight or prepare() has not run. |
weighted.drawMany(array<float> fractions, array<int> output = na) | Draws a batch of physical slots, refreshing derived state once. Returns one physical slot per fraction, in request order. -1 marks a range with no positive total weight. |
weighted.total() | Transformed total weight of the prepared range. Returns the total, or 0.0 when prepare() has not run. |
weighted.probability(int physicalIndex) | Transformed selection probability of one physical slot. Returns the probability in [0, 1], or 0.0 when the slot is outside the prepared range or the range has no positive total weight. |
weighted.mode() | Representation currently in use. Returns the active WeightPolicy. Never automatic. |
weighted.limit() | Number of physical slots. Returns the capacity. |
weighted.isPrepared() | Whether prepare() has run. Returns true once a range has been prepared. |
weighted.currentExponent() | Exponent fixed by the last prepare(). Returns the exponent, or na before the first prepare. |
weighted.preparedRange() | Circular range fixed by the last prepare(). Returns [startPhysical, count]. |
weighted.pendingUpdates() | Weight mutations counted since the last prepare(). Named distinctly from the updatesSincePrepare field. Returns the update count. |
weighted.weightRevision() | Monotonic weight revision, for callers that cache derived results. Named distinctly from the free revision() constructor. Returns the revision. |
WeightedPrefix
| Type | What it is |
|---|---|
op.WeightedPrefix | Reusable left-to-right cumulative weights over a circular range. Complexity: build O(count); lowerBound() O(log count). |
| Call | Description |
|---|---|
op.weightedPrefix() | Creates an empty prefix index. Returns a new WeightedPrefix. |
prefix.buildCircular(array<float> weights, int startPhysical, int count, float exponent = 1.0, bool preserveZeroExponent = false) | Rebuilds cumulative weights over a circular logical range. Returns the receiver, so calls chain. |
prefix.build(array<float> weights, int count = na, float exponent = 1.0, bool preserveZeroExponent = false) | Rebuilds cumulative weights over a non-circular range starting at physical slot 0. Returns the receiver, so calls chain. |
prefix.lowerBound(float threshold) | Selects the smallest logical index whose cumulative sum reaches a threshold. Returns the logical index, or -1 when the range is empty or its total is 0. |
prefix.probability(int logicalIndex) | Transformed probability of one logical index in the built range. Returns the probability, or 0.0 when the index is outside the range or the total is 0. |
prefix.total() | Sum of every transformed weight in the built range. Returns the total. |
prefix.count() | Number of logical entries in the built range. Returns the entry count. |
prefix.cumulativeView() | The running cumulative totals, in logical order. Ownership: borrowed structure-owned view. Mutation: read-only by contract. Rebuild to change the weights. Lifetime: valid until the next build(), buildCircular() or clear(). Persistence: reacquire after that boundary. Returns the cumulative totals, count() elements long. |
prefix.clear() | Empties the index, retaining the allocation. Returns the receiver, so calls chain. |
FloatFenwick
| Type | What it is |
|---|---|
op.FloatFenwick | Dynamic prefix-sum index over non-negative float weights. Complexity: reset() and build() O(N); set(), add(), prefix() and lowerBound() O(log N). Limits: at most 99,999 weights, because the tree uses a sentinel slot. |
| Call | Description |
|---|---|
op.floatFenwick(int size = 0) | Creates a Fenwick tree. Returns a new FloatFenwick with every weight at 0. |
tree.reset(int size) | Resizes the tree and clears every weight to 0. Returns the receiver, so calls chain. |
tree.build(array<float> weights, int count = na) | Rebuilds the whole tree from a weight array in O(N). Returns the receiver, so calls chain. |
tree.set(int index, float value) | Sets one zero-based weight. Returns true when the index was in range. |
tree.add(int index, float delta) | Adds a delta to one zero-based weight, clamping the result at 0. Returns true when the index was in range. |
tree.get(int index) | Reads one zero-based weight. Returns the stored weight, or na when the index is out of range. |
tree.prefix(int endExclusive) | Sum of weights in [0, endExclusive). Returns the prefix sum. |
tree.rangeSum(int startInclusive, int endExclusive) | Sum of weights in [startInclusive, endExclusive). Returns the range sum. |
tree.total() | Sum of every weight. Returns the total. |
tree.count() | Number of weights. Returns the weight count. |
tree.lowerBound(float threshold) | Selects the smallest zero-based index whose prefix sum reaches a threshold, using binary lifting over the tree. Returns the index, or -1 when the tree is empty or its total is 0. |
tree.circularTotal(int startPhysical, int count) | Exact total over a circular physical range. Returns the exact total. Complexity O(count). |
tree.lowerBoundCircular(float threshold, int startPhysical, int count) | Selects over a circular physical range. Returns the selected physical slot, or -1 when the range is empty or its total is 0. |
tree.clear() | Clears every weight to 0, retaining the allocation and size. Returns the receiver, so calls chain. |