mod definition;
mod manager;
pub use definition::*;
pub use manager::*;
use uuid::Uuid;
use crate::ILResult;
pub use crate::catalog::RowValidity;
use crate::expr::Expr;
use crate::storage::{InputFile, OutputFile};
use arrow::array::{ArrayRef, RecordBatch};
use arrow::datatypes::FieldRef;
use std::any::Any;
use std::fmt::Debug;
use std::sync::Arc;
pub trait IndexKind: Debug + Send + Sync {
fn kind(&self) -> &str;
fn decode_params(&self, value: &str) -> ILResult<Arc<dyn IndexParams>>;
fn supports(&self, index_def: &IndexDefinition) -> ILResult<()>;
fn builder(&self, index_def: &IndexDefinitionRef) -> ILResult<Box<dyn IndexBuilder>>;
fn supports_search(
&self,
index_def: &IndexDefinition,
query: &dyn SearchQuery,
) -> ILResult<bool>;
fn search_query_codec(&self) -> Option<Arc<dyn SearchQueryCodec>>;
fn dynamic_fields(&self) -> Vec<FieldRef>;
fn supports_filter(
&self,
index_def: &IndexDefinition,
filter: &Expr,
) -> ILResult<FilterSupport>;
fn inline_index_segment_row_count(&self, index_def: &IndexDefinition) -> usize;
}
#[async_trait::async_trait]
pub trait IndexBuilder: Debug + Send + Sync {
fn index_def(&self) -> &IndexDefinitionRef;
fn is_empty(&self) -> bool;
fn append(&mut self, batch: &RecordBatch) -> ILResult<()>;
async fn read_file(&mut self, input_file: Box<dyn InputFile>) -> ILResult<()>;
async fn write_file(&mut self, output_file: Box<dyn OutputFile>) -> ILResult<()>;
fn read_bytes(&mut self, buf: &[u8]) -> ILResult<()>;
fn write_bytes(&mut self, buf: &mut Vec<u8>) -> ILResult<()>;
fn build(&mut self) -> ILResult<Box<dyn Index>>;
}
#[async_trait::async_trait]
pub trait Index: Debug + Send + Sync {
async fn search(
&self,
query: &dyn SearchQuery,
dynamic_fields: &[String],
validity: &RowValidity,
limit: Option<usize>,
) -> ILResult<SearchIndexEntries>;
async fn filter(
&self,
filters: &[Expr],
validity: &RowValidity,
) -> ILResult<FilterIndexEntries>;
}
#[derive(Debug, Clone)]
pub struct DynamicColumn {
pub field: FieldRef,
pub values: ArrayRef,
}
#[derive(Debug, Clone)]
pub struct SearchIndexEntries {
pub row_ids: Vec<Uuid>,
pub scores: Vec<f64>,
pub score_higher_is_better: bool,
pub dynamic_columns: Vec<DynamicColumn>,
}
#[derive(Debug, Clone)]
pub struct FilterIndexEntries {
pub row_ids: Vec<Uuid>,
}
#[derive(Debug, Clone, Copy)]
pub enum FilterSupport {
Unsupported,
Exact,
Inexact,
}
pub trait SearchQuery: Debug + Send + Sync + Any {
fn index_kind(&self) -> &str;
}
pub trait SearchQueryCodec: Debug + Send + Sync {
fn encode(&self, query: &dyn SearchQuery) -> ILResult<Vec<u8>>;
fn decode(&self, data: &[u8]) -> ILResult<Arc<dyn SearchQuery>>;
}
impl dyn SearchQuery {
pub fn is<T: SearchQuery>(&self) -> bool {
(self as &dyn Any).is::<T>()
}
pub fn downcast_ref<T: SearchQuery>(&self) -> Option<&T> {
(self as &dyn Any).downcast_ref::<T>()
}
}
pub trait IndexParams: Debug + Send + Sync + Any {
fn encode(&self) -> ILResult<String>;
}
impl dyn IndexParams {
pub fn is<T: IndexParams>(&self) -> bool {
(self as &dyn Any).is::<T>()
}
pub fn downcast_ref<T: IndexParams>(&self) -> Option<&T> {
(self as &dyn Any).downcast_ref::<T>()
}
}