use scalar::FtsIndexBuilder;
use serde::Deserialize;
use serde_with::skip_serializing_none;
use std::sync::Arc;
use std::time::Duration;
use vector::IvfFlatIndexBuilder;
use crate::index::vector::IvfRqIndexBuilder;
use crate::{DistanceType, Error, Result, table::BaseTable};
use self::{
scalar::{BTreeIndexBuilder, BitmapIndexBuilder, LabelListIndexBuilder},
vector::{IvfHnswPqIndexBuilder, IvfHnswSqIndexBuilder, IvfPqIndexBuilder, IvfSqIndexBuilder},
};
pub mod scalar;
pub mod vector;
pub mod waiter;
#[derive(Debug, Clone)]
pub enum Index {
Auto,
BTree(BTreeIndexBuilder),
Bitmap(BitmapIndexBuilder),
LabelList(LabelListIndexBuilder),
FTS(FtsIndexBuilder),
IvfFlat(IvfFlatIndexBuilder),
IvfPq(IvfPqIndexBuilder),
IvfSq(IvfSqIndexBuilder),
IvfRq(IvfRqIndexBuilder),
IvfHnswPq(IvfHnswPqIndexBuilder),
IvfHnswSq(IvfHnswSqIndexBuilder),
}
pub struct IndexBuilder {
parent: Arc<dyn BaseTable>,
pub(crate) index: Index,
pub(crate) columns: Vec<String>,
pub(crate) replace: bool,
pub(crate) wait_timeout: Option<Duration>,
pub(crate) train: bool,
pub(crate) name: Option<String>,
}
impl IndexBuilder {
pub(crate) fn new(parent: Arc<dyn BaseTable>, columns: Vec<String>, index: Index) -> Self {
Self {
parent,
index,
columns,
replace: true,
train: true,
wait_timeout: None,
name: None,
}
}
pub fn replace(mut self, v: bool) -> Self {
self.replace = v;
self
}
pub fn name(mut self, v: String) -> Self {
self.name = Some(v);
self
}
pub fn train(mut self, v: bool) -> Self {
self.train = v;
self
}
pub fn wait_timeout(mut self, d: Duration) -> Self {
self.wait_timeout = Some(d);
self
}
pub async fn execute(self) -> Result<()> {
self.parent.clone().create_index(self).await
}
}
#[derive(Debug, Clone, PartialEq, Deserialize)]
pub enum IndexType {
#[serde(alias = "IVF_FLAT")]
IvfFlat,
#[serde(alias = "IVF_SQ")]
IvfSq,
#[serde(alias = "IVF_PQ")]
IvfPq,
#[serde(alias = "IVF_RQ")]
IvfRq,
#[serde(alias = "IVF_HNSW_PQ")]
IvfHnswPq,
#[serde(alias = "IVF_HNSW_SQ")]
IvfHnswSq,
#[serde(alias = "BTREE")]
BTree,
#[serde(alias = "BITMAP")]
Bitmap,
#[serde(alias = "LABEL_LIST")]
LabelList,
#[serde(alias = "INVERTED", alias = "Inverted")]
FTS,
}
impl std::fmt::Display for IndexType {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::IvfFlat => write!(f, "IVF_FLAT"),
Self::IvfSq => write!(f, "IVF_SQ"),
Self::IvfPq => write!(f, "IVF_PQ"),
Self::IvfRq => write!(f, "IVF_RQ"),
Self::IvfHnswPq => write!(f, "IVF_HNSW_PQ"),
Self::IvfHnswSq => write!(f, "IVF_HNSW_SQ"),
Self::BTree => write!(f, "BTREE"),
Self::Bitmap => write!(f, "BITMAP"),
Self::LabelList => write!(f, "LABEL_LIST"),
Self::FTS => write!(f, "FTS"),
}
}
}
impl std::str::FromStr for IndexType {
type Err = Error;
fn from_str(value: &str) -> Result<Self> {
match value.to_uppercase().as_str() {
"BTREE" => Ok(Self::BTree),
"BITMAP" => Ok(Self::Bitmap),
"LABEL_LIST" | "LABELLIST" => Ok(Self::LabelList),
"FTS" | "INVERTED" => Ok(Self::FTS),
"IVF_FLAT" => Ok(Self::IvfFlat),
"IVF_SQ" => Ok(Self::IvfSq),
"IVF_PQ" => Ok(Self::IvfPq),
"IVF_RQ" => Ok(Self::IvfRq),
"IVF_HNSW_PQ" => Ok(Self::IvfHnswPq),
"IVF_HNSW_SQ" => Ok(Self::IvfHnswSq),
_ => Err(Error::InvalidInput {
message: format!("the input value {} is not a valid IndexType", value),
}),
}
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct IndexConfig {
pub name: String,
pub index_type: IndexType,
pub columns: Vec<String>,
}
#[skip_serializing_none]
#[derive(Debug, Deserialize)]
pub(crate) struct IndexMetadata {
pub metric_type: Option<DistanceType>,
pub index_type: Option<IndexType>,
pub loss: Option<f64>,
}
#[skip_serializing_none]
#[derive(Debug, Deserialize)]
pub(crate) struct IndexStatisticsImpl {
pub num_indexed_rows: usize,
pub num_unindexed_rows: usize,
pub indices: Vec<IndexMetadata>,
pub index_type: Option<IndexType>,
pub num_indices: Option<u32>,
}
#[skip_serializing_none]
#[derive(Debug, Deserialize, PartialEq)]
pub struct IndexStatistics {
pub num_indexed_rows: usize,
pub num_unindexed_rows: usize,
pub index_type: IndexType,
pub distance_type: Option<DistanceType>,
pub num_indices: Option<u32>,
pub loss: Option<f64>,
}