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<Semaphore>, 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). Query scoring uses the global rayon pool; keeping background BP off it prevents a large merge from queueing every search behind gain 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 load_and_publish_trained(&self)

Compatibility entry point: load the complete trained set or clear the published generation and log the validation failure.

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.

Tokio cannot abort a spawn_blocking closure once it has started. The old implementation aborted only the async wrapper and returned while merge-time BP still owned an OffsetWriter, allowing index deletion or orphan cleanup to race a live writer. Awaiting is the only sound generic behavior until every merge phase supports cooperative cancellation.

Source

pub async fn wait_for_merging_thread(self: &Arc<Self>)

Wait for all current in-flight merges to complete.

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 h.await returns all cascading handles are registered.

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 the fewest possible segments, 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<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
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