feat: add LiveReload trait for read-only field indexes (#9295)

* feat: add LiveReload trait for read-only field indexes

* fix: ci

* chore: remove comment

* feat: implement LiveReload for map index (#9296)
This commit is contained in:
Daniel Boros
2026-08-04 11:16:47 +02:00
committed by generall
parent b2818713b9
commit cd1cd46c34
5 changed files with 55 additions and 4 deletions
@@ -10,4 +10,6 @@ pub use builder::{FieldIndexBuilder, FieldIndexBuilderTrait};
pub use field_index::FieldIndex;
pub use field_index_read::FieldIndexRead;
pub use payload_field_index::{PayloadFieldIndex, PayloadFieldIndexRead};
#[allow(unused_imports)]
pub(crate) use read_only::LiveReload;
pub use value_indexer::ValueIndexer;
@@ -0,0 +1,41 @@
use common::counter::hardware_counter::HardwareCounterCell;
use common::types::PointOffsetType;
use crate::common::operation_error::OperationResult;
/// Common live-reload surface shared by the read-only field-index variants.
///
/// A read-only index is opened over a [`UniversalRead`] backend while a writer
/// keeps appending to the same files. `live_reload` refreshes the in-memory
/// view to the current on-disk state without a full re-open. Implementers fall
/// into two shapes:
///
/// - immutable mmap variants only re-apply the authoritative `deleted_points`
/// to their in-memory deletion bitmap — `fs` and `new_points` are unused
/// because no on-disk state changes after build;
/// - appendable gridstore variants reload the backing storage through `fs`,
/// drop `deleted_points` from the in-memory index, then ingest `new_points`
/// from the refreshed storage view.
///
/// `deleted_points` / `new_points` are supplied by the caller (typically the
/// segment's id-tracker diff accumulated since the previous reload).
///
/// [`UniversalRead`]: common::universal_io::UniversalRead
// No in-crate implementer on the trait-only branch; the per-index impls land
// on the sibling branches that fork from here.
#[allow(dead_code)]
pub(crate) trait LiveReload {
/// Filesystem context (`S::Fs` of the backing [`UniversalRead`]) used to
/// re-read on-disk state during a reload.
///
/// [`UniversalRead`]: common::universal_io::UniversalRead
type Fs;
fn live_reload(
&mut self,
fs: &Self::Fs,
deleted_points: &[PointOffsetType],
new_points: &[PointOffsetType],
hw_counter: &HardwareCounterCell,
) -> OperationResult<()>;
}
@@ -1,10 +1,12 @@
mod lifecycle;
mod live_reload;
mod read_ops;
use std::fmt::{Debug, Formatter};
use std::path::PathBuf;
use common::universal_io::UniversalRead;
pub(crate) use live_reload::LiveReload;
use crate::common::operation_error::OperationResult;
use crate::index::field_index::bool_index::ReadOnlyBoolIndex;
@@ -6,14 +6,17 @@ use gridstore::Blob;
use gridstore::error::GridstoreError;
use crate::common::operation_error::OperationResult;
use crate::index::field_index::LiveReload;
use crate::index::field_index::map_index::MapIndexKey;
use crate::index::field_index::map_index::mutable_map_index::read_only::ReadOnlyAppendableMapIndex;
impl<N: MapIndexKey + ?Sized, S: UniversalRead> ReadOnlyAppendableMapIndex<N, S>
impl<N: MapIndexKey + ?Sized, S: UniversalRead> LiveReload for ReadOnlyAppendableMapIndex<N, S>
where
Vec<<N as MapIndexKey>::Owned>: Blob + Send + Sync,
{
pub fn live_reload(
type Fs = S::Fs;
fn live_reload(
&mut self,
fs: &S::Fs,
deleted_points: &[PointOffsetType],
@@ -4,15 +4,18 @@ use common::types::PointOffsetType;
use common::universal_io::UniversalRead;
use crate::common::operation_error::OperationResult;
use crate::index::field_index::LiveReload;
use crate::index::field_index::map_index::MapIndexKey;
use crate::index::field_index::map_index::on_disk_map_index::OnDiskMapIndex;
impl<N, S> OnDiskMapIndex<N, S>
impl<N, S> LiveReload for OnDiskMapIndex<N, S>
where
N: MapIndexKey + Key + ?Sized,
S: UniversalRead,
{
pub fn live_reload(
type Fs = S::Fs;
fn live_reload(
&mut self,
_fs: &S::Fs,
deleted_points: &[PointOffsetType],