use std::sync::Arc;
use atomic_refcell::AtomicRefCell;
use crate::common::universal_io::UniversalReadFs;
use super::{ReadOnlyIndexesMap, ReadOnlyStructPayloadIndex};
use crate::segment::common::operation_error::OperationResult;
use crate::segment::id_tracker::IdTrackerRead;
use crate::segment::index::UniversalReadExt;
use crate::segment::index::field_index::ReadOnlyFieldIndex;
use crate::segment::index::payload_config::PayloadConfig;
use crate::segment::types::{PayloadKeyType, VectorName, VectorNameBuf};
use crate::segment::vector_storage::read_only::VectorStorageReadEnum;
pub struct PayloadIndexReloadDiff<S: UniversalReadExt> {
new_config: PayloadConfig,
added: ReadOnlyIndexesMap<S>,
removed: Vec<PayloadKeyType>,
}
impl<S: UniversalReadExt> PayloadIndexReloadDiff<S> {
pub fn is_empty(&self) -> bool {
let Self {
new_config: _,
added,
removed,
} = self;
added.is_empty() && removed.is_empty()
}
}
impl<S: UniversalReadExt> ReadOnlyStructPayloadIndex<S> {
pub fn config_reload_diff(
&self,
fs: &impl UniversalReadFs<File = S>,
new_config: PayloadConfig,
) -> OperationResult<PayloadIndexReloadDiff<S>> {
let mut added: ReadOnlyIndexesMap<S> = Default::default();
{
let id_tracker = self.id_tracker.borrow();
let total_point_count = id_tracker.total_point_count();
let deleted_points = id_tracker.deleted_point_bitslice();
for (field, indexed) in new_config.indices.iter() {
if self.config.indices.get(field) == Some(indexed) {
continue;
}
let mut indexes = Vec::with_capacity(indexed.types.len());
for index_type in &indexed.types {
if let Some(index) = ReadOnlyFieldIndex::open(
fs,
&self.path,
field,
&indexed.schema,
index_type,
total_point_count,
deleted_points,
None,
)? {
indexes.push(index);
}
}
added.insert(field.clone(), indexes);
}
}
let removed = self
.config
.indices
.keys()
.filter(|field| !new_config.indices.contains_key(*field))
.cloned()
.collect();
Ok(PayloadIndexReloadDiff {
new_config,
added,
removed,
})
}
pub fn apply_config_reload(&mut self, diff: PayloadIndexReloadDiff<S>) {
let PayloadIndexReloadDiff {
new_config,
added,
removed,
} = diff;
for field in &removed {
self.field_indexes.remove(field);
}
for (field, indexes) in added {
if indexes.is_empty() {
self.field_indexes.remove(&field);
} else {
self.field_indexes.insert(field, indexes);
}
}
self.config = new_config;
}
pub fn register_vector_storage(
&mut self,
vector_name: VectorNameBuf,
vector_storage: Arc<AtomicRefCell<VectorStorageReadEnum<S>>>,
) {
self.vector_storages.insert(vector_name, vector_storage);
}
pub fn unregister_vector_storage(&mut self, vector_name: &VectorName) {
self.vector_storages.remove(vector_name);
}
}