use crate::catalog::{IndexKind, ValType};
use crate::composite::CompositeCol;
use crate::spec_builder::IndexSpecBuilder;
use crate::spec_parts::{AnnSpec, FieldSpec, ValueSpec};
#[derive(Debug, Clone, PartialEq)]
pub struct IndexSpec {
pub(crate) name: Vec<u8>,
pub(crate) prefix: Vec<u8>,
pub(crate) fields: Vec<FieldSpec>,
pub(crate) ty: ValType,
pub(crate) kind: IndexKind,
pub(crate) max_bytes: u64,
pub(crate) ann: Option<AnnSpec>,
pub(crate) group_by: Option<Vec<u8>>,
pub(crate) with_positions: bool,
pub(crate) values: Vec<ValueSpec>,
pub(crate) composite: Option<Vec<CompositeCol>>,
}
pub type RowInputs = (Vec<(Vec<u8>, f32)>, Vec<Option<Vec<u8>>>);
impl IndexSpec {
pub fn builder(
name: impl Into<Vec<u8>>,
prefix: impl Into<Vec<u8>>,
kind: IndexKind,
ty: ValType,
) -> IndexSpecBuilder {
IndexSpecBuilder {
spec: IndexSpec {
name: name.into(),
prefix: prefix.into(),
fields: Vec::new(),
ty,
kind,
max_bytes: 0,
ann: None,
group_by: None,
with_positions: false,
values: Vec::new(),
composite: None,
},
}
}
pub fn name(&self) -> &[u8] {
&self.name
}
pub fn prefix(&self) -> &[u8] {
&self.prefix
}
pub fn fields(&self) -> &[FieldSpec] {
&self.fields
}
pub fn field(&self) -> &[u8] {
self.fields.first().map_or(&[][..], |f| f.name.as_slice())
}
pub fn ty(&self) -> ValType {
self.ty
}
pub fn kind(&self) -> IndexKind {
self.kind
}
pub fn max_bytes(&self) -> u64 {
self.max_bytes
}
pub fn ann(&self) -> Option<AnnSpec> {
self.ann
}
pub fn group_by(&self) -> Option<&[u8]> {
self.group_by.as_deref()
}
pub fn has_positions(&self) -> bool {
self.with_positions
}
pub fn values(&self) -> &[ValueSpec] {
&self.values
}
pub fn composite(&self) -> Option<&[CompositeCol]> {
self.composite.as_deref()
}
pub fn read_row(&self, mut get: impl FnMut(&[u8]) -> Option<Vec<u8>>) -> RowInputs {
let mut fields = Vec::with_capacity(self.fields.len());
for f in &self.fields {
if let Some(raw) = get(&f.name) {
fields.push((raw, f.weight));
}
}
let values = self.values.iter().map(|v| get(&v.name)).collect();
(fields, values)
}
}