pub struct SegmentManager<D: DirectoryWriter + 'static> { /* private fields */ }Expand description
Segment manager — coordinates segment commit, background merging, and trained structures.
SOLE owner of metadata.json. All metadata mutations go through state Mutex.
Implementations§
Source§impl<D: DirectoryWriter + 'static> SegmentManager<D>
impl<D: DirectoryWriter + 'static> SegmentManager<D>
Sourcepub fn new(
directory: Arc<D>,
schema: Arc<Schema>,
metadata: IndexMetadata,
merge_policy: Box<dyn MergePolicy>,
term_cache_blocks: usize,
max_concurrent_merges: usize,
global_merge_permits: Arc<Semaphore>,
merge_bp_time_budget: Option<Duration>,
bp_memory_budget_bytes: usize,
reorder_permits: Arc<ReorderConcurrencyGate>,
background_reorder_pool: Option<Arc<ThreadPool>>,
) -> Self
pub fn new( directory: Arc<D>, schema: Arc<Schema>, metadata: IndexMetadata, merge_policy: Box<dyn MergePolicy>, term_cache_blocks: usize, max_concurrent_merges: usize, global_merge_permits: Arc<Semaphore>, merge_bp_time_budget: Option<Duration>, bp_memory_budget_bytes: usize, reorder_permits: Arc<ReorderConcurrencyGate>, background_reorder_pool: Option<Arc<ThreadPool>>, ) -> Self
Create a new segment manager with existing metadata
Sourcepub fn background_cpu_pool(&self) -> Arc<ThreadPool> ⓘ
pub fn background_cpu_pool(&self) -> Arc<ThreadPool> ⓘ
Bounded rayon pool for background CPU (merge-time BP, manual reorder, and global vector-codebook training). Query scoring uses a dedicated search pool; keeping background work on this separate bounded pool prevents a merge or retrain from queueing every search behind its CPU passes.
Sourcepub fn begin_shutdown(&self)
pub fn begin_shutdown(&self)
Stop new indexing/merge/reorder operations from claiming segment IDs.
Used as the first half of index deletion; the writer then joins its
workers before Self::wait_for_shutdown drains remaining ownership.
Sourcepub async fn get_segment_ids(&self) -> Vec<String>
pub async fn get_segment_ids(&self) -> Vec<String>
Get the current segment IDs
Sourcepub fn trained(&self) -> Option<Arc<TrainedVectorStructures>>
pub fn trained(&self) -> Option<Arc<TrainedVectorStructures>>
Get trained vector structures (lock-free via ArcSwap)
Sourcepub async fn acquire_snapshot(&self) -> SegmentSnapshot
pub async fn acquire_snapshot(&self) -> SegmentSnapshot
Acquire a snapshot of current segments for reading. The snapshot holds references — segments won’t be deleted while snapshot exists.
Sourcepub fn tracker(&self) -> Arc<SegmentTracker> ⓘ
pub fn tracker(&self) -> Arc<SegmentTracker> ⓘ
Get the segment tracker
Source§impl<D: DirectoryWriter + 'static> SegmentManager<D>
impl<D: DirectoryWriter + 'static> SegmentManager<D>
Sourcepub async fn commit(
self: &Arc<Self>,
new_segments: &[(String, u32)],
) -> Result<()>
pub async fn commit( self: &Arc<Self>, new_segments: &[(String, u32)], ) -> Result<()>
Atomic commit: register new segments + persist metadata.
Sourcepub async fn maybe_merge(self: &Arc<Self>)
pub async fn maybe_merge(self: &Arc<Self>)
Evaluate merge policy and spawn background merges for all eligible candidates.
Atomicity: The entire filter → find_merges → spawn_merge sequence runs
under the state lock to prevent a TOCTOU race where concurrent callers
both see segments as eligible before either claims operation ownership.
spawn_merge is non-blocking (just try_register + tokio::spawn), so
holding the state lock through it is safe and sub-microsecond.
The hard merge semaphore is acquired before lifecycle ownership, so concurrent triggers cannot exceed configured merge capacity.
Sourcepub async fn abort_merges(&self)
pub async fn abort_merges(&self)
Drain all in-flight merge tasks safely.
Merge/reorder writers use synchronous block-in-place sections, so an abort request takes effect only after the owned writer reaches its next await. Draining the complete task remains necessary before index deletion or orphan cleanup can safely proceed.
Cancellation-safe: dropping this future mid-drain returns un-awaited
handles to merge_handles so later drains still see in-flight merges.
Sourcepub async fn wait_for_merging_thread(self: &Arc<Self>)
pub async fn wait_for_merging_thread(self: &Arc<Self>)
Wait for all current in-flight merges to complete.
Cancellation-safe: dropping this future mid-drain returns un-awaited
handles to merge_handles so later drains still see in-flight merges.
Sourcepub async fn wait_for_all_merges(self: &Arc<Self>)
pub async fn wait_for_all_merges(self: &Arc<Self>)
Wait for all eligible merges to complete, including cascading merges.
Drains current handles, then loops. Each completed merge auto-triggers
maybe_merge (which pushes new handles) before its JoinHandle resolves,
so by the time join_next returns all cascading handles are registered.
Cancellation-safe: dropping this future mid-drain returns un-awaited
handles to merge_handles so later drains still see in-flight merges.
Sourcepub async fn wait_for_shutdown(self: &Arc<Self>)
pub async fn wait_for_shutdown(self: &Arc<Self>)
Complete the second half of shutdown after the owning IndexWriter
has been dropped. This drains tracked merges and then waits for every
remaining guard, including optimizer reorders that are intentionally
launched outside the writer lock.
Sourcepub async fn force_merge(self: &Arc<Self>) -> Result<()>
pub async fn force_merge(self: &Arc<Self>) -> Result<()>
Force merge segments into compact, size-balanced groups, respecting
max_segment_docs from the merge policy.
If the policy defines a max segment size, segments are merged in batches that stay within that limit. Otherwise, all segments are merged into one.
Each batch is registered in active_operations via an RAII guard to prevent
maybe_merge from spawning a conflicting background merge.
Sourcepub async fn reorder_segments(self: &Arc<Self>) -> Result<()>
pub async fn reorder_segments(self: &Arc<Self>) -> Result<()>
Reorder all segments via Recursive Graph Bisection (BP) for better BMP pruning.
Each segment is individually rebuilt with reordered BMP blocks. Non-BMP fields are copied unchanged via streaming file copy.
Uses active-operation ownership to prevent concurrent work on the same segment.
Sourcepub async fn unreordered_segment_ids(&self) -> Vec<String>
pub async fn unreordered_segment_ids(&self) -> Vec<String>
Get segment IDs that have not been reordered yet.
Excludes segments currently involved in a merge or reorder operation to avoid wasted work (the optimizer would skip them anyway).
Sourcepub async fn unreordered_segments(&self) -> Vec<(String, u32)>
pub async fn unreordered_segments(&self) -> Vec<(String, u32)>
Segments never reordered, with doc counts — for the optimizer to pick a size-appropriate BP budget.
Sourcepub async fn unconverged_segments(&self) -> Vec<(String, u32)>
pub async fn unconverged_segments(&self) -> Vec<(String, u32)>
Segments whose last BP pass hit its wall-clock budget before finishing
(bp_converged == false). A warm-started follow-up pass deepens the
ordering; the optimizer revisits these at low priority.
Sourcepub async fn unconverged_segments_below(
&self,
max_unconverged_passes: u32,
) -> Vec<(String, u32, u32)>
pub async fn unconverged_segments_below( &self, max_unconverged_passes: u32, ) -> Vec<(String, u32, u32)>
Unconverged segments still below a hard replacement-lineage work bound. Includes the persisted attempt count for scheduler diagnostics.
Sourcepub async fn reorder_single_segment(
self: &Arc<Self>,
seg_id: &str,
rayon_pool: Option<Arc<ThreadPool>>,
bp_budget: BpBudget,
) -> Result<bool>
pub async fn reorder_single_segment( self: &Arc<Self>, seg_id: &str, rayon_pool: Option<Arc<ThreadPool>>, bp_budget: BpBudget, ) -> Result<bool>
Reorder a single segment via BP. Returns Ok(true) if reordered, Ok(false) if skipped.
Non-blocking: operation ownership prevents conflicts with background merges. Copies unchanged files and rebuilds only the sparse file with reordered BMP data.
Sourcepub async fn cleanup_orphan_segments(&self) -> Result<usize>
pub async fn cleanup_orphan_segments(&self) -> Result<usize>
Clean up orphan segment files not registered in metadata.
Reads metadata, active-operation ownership, and snapshot-deferred deletions to determine which segments are legitimate. Filesystem deletion is asynchronous; in-flight outputs and retired sources still held by readers are both protected.
Auto Trait Implementations§
impl<D> !Freeze for SegmentManager<D>
impl<D> !RefUnwindSafe for SegmentManager<D>
impl<D> !UnwindSafe for SegmentManager<D>
impl<D> Send for SegmentManager<D>
impl<D> Sync for SegmentManager<D>
impl<D> Unpin for SegmentManager<D>
impl<D> UnsafeUnpin for SegmentManager<D>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> DropFlavorWrapper<T> for T
impl<T> DropFlavorWrapper<T> for T
Source§impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
Source§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more