use crate::common::counter::hardware_counter::HardwareCounterCell;
use crate::common::types::PointOffsetType;
use crate::common::universal_io::UniversalRead;
use serde_json::Value;
use super::mutable_geo_index::read_only::ReadOnlyAppendableGeoIndex;
use super::on_disk_geo_index::OnDiskGeoIndex;
use super::read_ops::GeoIndexRead;
use crate::segment::common::utils::MultiValue;
use crate::segment::index::field_index::geo_index::immutable_geo_index::ImmutableGeoIndex;
use crate::segment::index::payload_config::IndexMutability;
use crate::segment::index::query_optimization::rescore_formula::value_retriever::VariableRetrieverFn;
mod lifecycle;
mod live_reload;
mod read_ops;
#[allow(clippy::large_enum_variant)]
pub enum ReadOnlyGeoIndex<S: UniversalRead> {
Appendable(ReadOnlyAppendableGeoIndex<S>),
Immutable(ImmutableGeoIndex<S>),
OnDisk(OnDiskGeoIndex<S>),
}
impl<S: UniversalRead> ReadOnlyGeoIndex<S> {
pub fn value_retriever<'a>(
&'a self,
_hw_counter: &'a HardwareCounterCell,
) -> VariableRetrieverFn<'a> {
Box::new(move |point_id: PointOffsetType| -> MultiValue<Value> {
GeoIndexRead::get_values(self, point_id)
.into_iter()
.flatten()
.filter_map(|v| serde_json::to_value(v).ok())
.collect()
})
}
pub fn get_mutability_type(&self) -> IndexMutability {
match self {
Self::Appendable(_) => IndexMutability::Mutable,
Self::Immutable(_) => IndexMutability::Immutable,
Self::OnDisk(_) => IndexMutability::Immutable,
}
}
}
#[cfg(test)]
mod tests {
use crate::common::counter::hardware_counter::HardwareCounterCell;
use crate::common::universal_io::{MmapFile, ReadOnly, UniversalRead, UniversalReadFileOps};
use tempfile::TempDir;
use super::super::GeoIndexRead;
use super::super::mutable_geo_index::MutableGeoIndex;
use super::ReadOnlyGeoIndex;
use crate::segment::types::GeoPoint;
#[test]
fn parent_open_gridstore_round_trip() {
let dir = TempDir::with_prefix("ro_geo_parent_gridstore").unwrap();
let hw_counter = HardwareCounterCell::new();
{
let mut mutable = MutableGeoIndex::open(dir.path().to_path_buf(), true)
.unwrap()
.unwrap();
mutable
.add_many_geo_points(0, vec![GeoPoint::new_unchecked(13.41, 52.52)], &hw_counter)
.unwrap();
mutable
.add_many_geo_points(1, vec![GeoPoint::new_unchecked(2.35, 48.85)], &hw_counter)
.unwrap();
mutable
.add_many_geo_points(
2,
vec![
GeoPoint::new_unchecked(1.0, 1.0),
GeoPoint::new_unchecked(2.0, 2.0),
],
&hw_counter,
)
.unwrap();
mutable.flusher()().unwrap();
}
type RoFs = <ReadOnly<MmapFile> as UniversalRead>::Fs;
let fs = RoFs::from_context(Default::default()).unwrap();
let index: ReadOnlyGeoIndex<ReadOnly<MmapFile>> =
ReadOnlyGeoIndex::open_appendable(&fs, dir.path().to_path_buf())
.unwrap()
.unwrap();
assert!(matches!(index, ReadOnlyGeoIndex::Appendable(_)));
assert_eq!(GeoIndexRead::points_count(&index), 3);
assert_eq!(GeoIndexRead::points_values_count(&index), 4);
assert_eq!(GeoIndexRead::max_values_per_point(&index), 2);
assert_eq!(GeoIndexRead::values_count(&index, 0), 1);
assert_eq!(GeoIndexRead::values_count(&index, 2), 2);
}
}