Skip to main content

SegmentManager

Struct SegmentManager 

Source
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>

Source

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

Source

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.

Source

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.

Source

pub async fn get_segment_ids(&self) -> Vec<String>

Get the current segment IDs

Source

pub fn trained(&self) -> Option<Arc<TrainedVectorStructures>>

Get trained vector structures (lock-free via ArcSwap)

Source

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.

Source

pub fn tracker(&self) -> Arc<SegmentTracker>

Get the segment tracker

Source

pub fn directory(&self) -> Arc<D>

Get the directory

Source§

impl<D: DirectoryWriter + 'static> SegmentManager<D>

Source

pub async fn commit( self: &Arc<Self>, new_segments: &[(String, u32)], ) -> Result<()>

Atomic commit: register new segments + persist metadata.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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).

Source

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.

Source

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.

Source

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.

Source

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.

Source

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> DropFlavorWrapper<T> for T

Source§

type Flavor = MayDrop

The DropFlavor that wraps T into Self
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, W> HasTypeWitness<W> for T
where W: MakeTypeWitness<Arg = T>, T: ?Sized,

Source§

const WITNESS: W = W::MAKE

A constant of the type witness
Source§

impl<T> Identity for T
where T: ?Sized,

Source§

const TYPE_EQ: TypeEq<T, <T as Identity>::Type> = TypeEq::NEW

Proof that Self is the same type as Self::Type, provides methods for casting between Self and Self::Type.
Source§

type Type = T

The same type as Self, used to emulate type equality bounds (T == U) with associated type equality constraints (T: Identity<Type = U>).
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more