tess 1.0.0
Performance-first tile and path simulation substrate
Loading...
Searching...
No Matches
tess::experimental::maintenance::ChunkMaintenanceAdapter< World, Product, Rebuild, Backend > Class Template Referencefinal

#include <tess/experimental/chunk_maintenance.h>

Public Member Functions

 ChunkMaintenanceAdapter (World &world, DirtyMask owned_dirty_mask, Rebuild rebuild, std::size_t backend_capacity=0)
 ChunkMaintenanceAdapter (const ChunkMaintenanceAdapter &)=delete
auto operator= (const ChunkMaintenanceAdapter &) -> ChunkMaintenanceAdapter &=delete
 ChunkMaintenanceAdapter (ChunkMaintenanceAdapter &&)=delete
auto operator= (ChunkMaintenanceAdapter &&) -> ChunkMaintenanceAdapter &=delete
auto mark_dirty (ChunkKey key, DirtyMask mask, Box3 bounds) -> ChunkMarkResult
auto retry (ChunkKey key) -> std::optional< ScheduleResult >
auto run_some (MaintenanceBudget budget) -> DrainResult
auto flush () -> DrainResult
auto product (ChunkKey key) const -> ChunkProductView< Product >
auto current (ChunkProductToken token) const noexcept -> bool
auto metrics () const noexcept -> MaintenanceMetrics
auto ensure_resident (ChunkKey key) -> ChunkResidencyResult requires(is_sparse)
auto evict (ChunkKey key) -> ChunkEvictionResult requires(is_sparse)
auto reconcile_residency () -> ChunkResidencyStatus requires(is_sparse)
auto try_release () -> ChunkAdapterReleaseResult

Detailed Description

template<typename World, typename Product, typename Rebuild, typename Backend = DirtyBitScheduler>
requires std::default_initializable<Product> && std::invocable<Rebuild&, const World&, ChunkKey, DirtyObservation, Product&>
class tess::experimental::maintenance::ChunkMaintenanceAdapter< World, Product, Rebuild, Backend >

External fixed-slot adapter for one derived product per chunk.

World is borrowed and must outlive this immovable adapter. Product is adapter-owned, while Rebuild is invoked as rebuild(const World&, ChunkKey, DirtyObservation, Product&). A successful callback publishes a content-version/residency token, then clears only the observed bits. The observation may have an empty mask when retry() repairs content-version drift caused by a disjoint owner. If the generation or content version changed, the product remains explicitly stale and the fixed task schedules another pass. Callback exceptions propagate verbatim, leave the owned dirty signal or content-version drift intact, and require the caller to use retry() after inspecting partial product effects.

owned_dirty_mask must be nonzero and disjoint from every other clearing owner for the same world. mark_dirty() rejects zero and foreign bits. It mutates authoritative metadata before offering maintenance, so a capacity failure loses no dirty signal. Scheduling is coalescing; one call does not imply one execution. A disjoint owner may advance the shared content version and stale this product without setting an owned bit; retry() then rebuilds against that content version without clearing the other owner's bits. Failed follow-up admission is retained as adapter-owned retry debt and reoffered by unbounded flush() or explicit retry(), so it cannot produce a false Idle.

Dense slots equal chunk keys. Sparse slots equal the world's fixed resident slots and are rebound only through this adapter at a quiescent boundary. Before ensure_resident(), evict(), or reconcile_residency(), callers close and join every producer, call flush() until it returns a fresh positive Idle, and keep producers closed through the transition. Once a sparse adapter exists, direct world residency mutation is unsupported; reconcile_residency() is the explicit exception for a coordinated archive load or other externally owned transition. A task rechecks resident_ref() before every unchecked sparse access, but that check does not make unsynchronized world mutation safe.

World reads and mutations are not internally synchronized. Concurrent offers are supported by the registered scheduler, but callers must provide the world's documented external synchronization whenever a producer or drain accesses it. Residency and release operations require exclusive adapter access after every producer is closed and joined. Product borrows remain valid until adapter destruction, but sparse slot rebinding may replace their value; copy a needed product before a residency transition.

Constructor & Destructor Documentation

◆ ChunkMaintenanceAdapter()

template<typename World, typename Product, typename Rebuild, typename Backend = DirtyBitScheduler>
tess::experimental::maintenance::ChunkMaintenanceAdapter< World, Product, Rebuild, Backend >::ChunkMaintenanceAdapter ( World & world,
DirtyMask owned_dirty_mask,
Rebuild rebuild,
std::size_t backend_capacity = 0 )
inline

Allocates fixed task, product, handle, and backend storage, then seals it.

A zero backend_capacity selects the slot count. A smaller capacity is useful only for queue-capacity comparison backends; fixed-registration backends require enough capacity for every adapter slot.

Member Function Documentation

◆ current()

template<typename World, typename Product, typename Rebuild, typename Backend = DirtyBitScheduler>
auto tess::experimental::maintenance::ChunkMaintenanceAdapter< World, Product, Rebuild, Backend >::current ( ChunkProductToken token) const -> bool
inlinenodiscardnoexcept

Returns whether token still names the current clean slot product.

◆ ensure_resident()

template<typename World, typename Product, typename Rebuild, typename Backend = DirtyBitScheduler>
auto tess::experimental::maintenance::ChunkMaintenanceAdapter< World, Product, Rebuild, Backend >::ensure_resident ( ChunkKey key) -> ChunkResidencyResult requires(is_sparse)
inlinenodiscard

Makes a sparse key resident at an established quiescent boundary.

The boundary stays open for a batch of adapter-owned residency changes; any later maintenance offer closes it.

◆ evict()

template<typename World, typename Product, typename Rebuild, typename Backend = DirtyBitScheduler>
auto tess::experimental::maintenance::ChunkMaintenanceAdapter< World, Product, Rebuild, Backend >::evict ( ChunkKey key) -> ChunkEvictionResult requires(is_sparse)
inlinenodiscard

Evicts a sparse key at an established quiescent boundary.

◆ flush()

template<typename World, typename Product, typename Rebuild, typename Backend = DirtyBitScheduler>
auto tess::experimental::maintenance::ChunkMaintenanceAdapter< World, Product, Rebuild, Backend >::flush ( ) -> DrainResult
inlinenodiscard

Flushes reachable tasks; Idle opens the sparse transition boundary. Adapter retry debt is reoffered around the drain and prevents Idle.

◆ mark_dirty()

template<typename World, typename Product, typename Rebuild, typename Backend = DirtyBitScheduler>
auto tess::experimental::maintenance::ChunkMaintenanceAdapter< World, Product, Rebuild, Backend >::mark_dirty ( ChunkKey key,
DirtyMask mask,
Box3 bounds ) -> ChunkMarkResult
inlinenodiscard

Marks owned dirty bits and offers the corresponding fixed task.

◆ metrics()

template<typename World, typename Product, typename Rebuild, typename Backend = DirtyBitScheduler>
auto tess::experimental::maintenance::ChunkMaintenanceAdapter< World, Product, Rebuild, Backend >::metrics ( ) const -> MaintenanceMetrics
inlinenodiscardnoexcept

Thread-safe monotonic scheduler diagnostics.

◆ product()

template<typename World, typename Product, typename Rebuild, typename Backend = DirtyBitScheduler>
auto tess::experimental::maintenance::ChunkMaintenanceAdapter< World, Product, Rebuild, Backend >::product ( ChunkKey key) const -> ChunkProductView< Product >
inlinenodiscard

Validates and returns one product's content-version/residency token.

◆ reconcile_residency()

template<typename World, typename Product, typename Rebuild, typename Backend = DirtyBitScheduler>
auto tess::experimental::maintenance::ChunkMaintenanceAdapter< World, Product, Rebuild, Backend >::reconcile_residency ( ) -> ChunkResidencyStatus requires(is_sparse)
inlinenodiscard

Rebinds sparse slots after one coordinated external residency transition.

This is intended for archive load. It is not permission for arbitrary direct world residency mutation while producers or tasks are active. Returns Ready, NotIdle, or Released; reconciliation cannot report Missing because it scans the world's complete resident set.

◆ retry()

template<typename World, typename Product, typename Rebuild, typename Backend = DirtyBitScheduler>
auto tess::experimental::maintenance::ChunkMaintenanceAdapter< World, Product, Rebuild, Backend >::retry ( ChunkKey key) -> std::optional< ScheduleResult >
inlinenodiscard

Reoffers dirty or content-version-stale work without changing world state.

Empty means an out-of-bounds or currently non-resident key, or a released adapter. Capacity and zero-progress outcomes remain explicit.

◆ run_some()

template<typename World, typename Product, typename Rebuild, typename Backend = DirtyBitScheduler>
auto tess::experimental::maintenance::ChunkMaintenanceAdapter< World, Product, Rebuild, Backend >::run_some ( MaintenanceBudget budget) -> DrainResult
inlinenodiscard

Runs fixed tasks within budget; world access needs external locking. Adapter retry debt is not reoffered here because a custom backend may execute an accepted offer synchronously outside this budget. Retained debt makes an otherwise completed drain report BudgetExhausted; use retry() or unbounded flush() to reoffer it.

◆ try_release()

template<typename World, typename Product, typename Rebuild, typename Backend = DirtyBitScheduler>
auto tess::experimental::maintenance::ChunkMaintenanceAdapter< World, Product, Rebuild, Backend >::try_release ( ) -> ChunkAdapterReleaseResult
inlinenodiscard

Retires every task after the required fresh positive Idle.

The caller first closes and joins every producer, then keeps exclusive access to this adapter through the Idle observation and release.


The documentation for this class was generated from the following file: