use std::fs::File;
use std::io::{BufReader, Read, Seek, SeekFrom};
use std::path::Path;
use crate::brute_force::BruteForceRabitqIndex;
use crate::ivf::IvfRabitqIndex;
use crate::RabitqError;
#[derive(Debug, Clone)]
pub enum RabitqIndex {
Ivf(IvfRabitqIndex),
BruteForce(BruteForceRabitqIndex),
}
impl RabitqIndex {
pub fn load_from_path<P: AsRef<Path>>(path: P) -> Result<Self, RabitqError> {
let file = File::open(path)?;
let reader = BufReader::new(file);
Self::load_from_reader(reader)
}
pub fn load_from_reader<R: Read + Seek>(mut reader: R) -> Result<Self, RabitqError> {
let mut magic = [0u8; 4];
reader.read_exact(&mut magic)?;
reader.seek(SeekFrom::Start(0))?;
match &magic {
b"RBQ1" => {
let ivf_index = IvfRabitqIndex::load_from_reader(reader)?;
Ok(RabitqIndex::Ivf(ivf_index))
}
b"RBF1" => {
let bf_index = BruteForceRabitqIndex::load_from_reader(reader)?;
Ok(RabitqIndex::BruteForce(bf_index))
}
_ => Err(RabitqError::InvalidPersistence(
"unrecognized index magic header (expected RBQ1 or RBF1)",
)),
}
}
pub fn len(&self) -> usize {
match self {
RabitqIndex::Ivf(idx) => idx.len(),
RabitqIndex::BruteForce(idx) => idx.len(),
}
}
pub fn is_empty(&self) -> bool {
match self {
RabitqIndex::Ivf(idx) => idx.is_empty(),
RabitqIndex::BruteForce(idx) => idx.is_empty(),
}
}
pub fn is_ivf(&self) -> bool {
matches!(self, RabitqIndex::Ivf(_))
}
pub fn is_brute_force(&self) -> bool {
matches!(self, RabitqIndex::BruteForce(_))
}
pub fn unwrap_ivf(self) -> IvfRabitqIndex {
match self {
RabitqIndex::Ivf(idx) => idx,
RabitqIndex::BruteForce(_) => panic!("called unwrap_ivf on BruteForce index"),
}
}
pub fn unwrap_brute_force(self) -> BruteForceRabitqIndex {
match self {
RabitqIndex::BruteForce(idx) => idx,
RabitqIndex::Ivf(_) => panic!("called unwrap_brute_force on IVF index"),
}
}
pub fn as_ivf(&self) -> Option<&IvfRabitqIndex> {
match self {
RabitqIndex::Ivf(idx) => Some(idx),
RabitqIndex::BruteForce(_) => None,
}
}
pub fn as_brute_force(&self) -> Option<&BruteForceRabitqIndex> {
match self {
RabitqIndex::BruteForce(idx) => Some(idx),
RabitqIndex::Ivf(_) => None,
}
}
pub fn as_ivf_mut(&mut self) -> Option<&mut IvfRabitqIndex> {
match self {
RabitqIndex::Ivf(idx) => Some(idx),
RabitqIndex::BruteForce(_) => None,
}
}
pub fn as_brute_force_mut(&mut self) -> Option<&mut BruteForceRabitqIndex> {
match self {
RabitqIndex::BruteForce(idx) => Some(idx),
RabitqIndex::Ivf(_) => None,
}
}
}