use usearch::ScalarKind;
pub const HNSW_MMAP_SERVE_ENV: &str = "TRUSTY_HNSW_MMAP_SERVE";
pub const VECTOR_QUANT_ENV: &str = "TRUSTY_VECTOR_QUANT";
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum MmapServeMode {
#[default]
Mmap,
EagerHeap,
}
impl MmapServeMode {
pub fn from_env() -> Self {
match std::env::var(HNSW_MMAP_SERVE_ENV) {
Ok(raw) => Self::parse(&raw),
Err(_) => Self::default(),
}
}
fn parse(raw: &str) -> Self {
match raw.trim().to_ascii_lowercase().as_str() {
"" | "1" | "true" | "yes" | "on" | "enabled" => Self::Mmap,
"0" | "false" | "no" | "off" | "disabled" => Self::EagerHeap,
other => {
tracing::warn!(
"{HNSW_MMAP_SERVE_ENV}={other:?} is not a recognised boolean; \
defaulting to mmap-view serving (enabled)"
);
Self::default()
}
}
}
pub fn promote_on_load(self) -> bool {
matches!(self, Self::EagerHeap)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum VectorQuant {
#[default]
None,
F16,
I8,
}
impl VectorQuant {
pub fn from_env() -> Self {
match std::env::var(VECTOR_QUANT_ENV) {
Ok(raw) => Self::parse(&raw),
Err(_) => Self::default(),
}
}
fn parse(raw: &str) -> Self {
match raw.trim().to_ascii_lowercase().as_str() {
"" | "none" | "f32" | "fp32" | "full" => Self::None,
"f16" | "fp16" | "half" => Self::F16,
"i8" | "int8" => Self::I8,
other => {
tracing::warn!(
"{VECTOR_QUANT_ENV}={other:?} is not a recognised quantization kind \
(expected none|f16|i8); defaulting to none (f32)"
);
Self::default()
}
}
}
pub fn scalar_kind(self) -> ScalarKind {
match self {
Self::None => ScalarKind::F32,
Self::F16 => ScalarKind::F16,
Self::I8 => ScalarKind::I8,
}
}
pub fn label(self) -> &'static str {
match self {
Self::None => "f32 (none)",
Self::F16 => "f16",
Self::I8 => "i8",
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn mmap_serve_mode_default_is_mmap() {
assert_eq!(MmapServeMode::default(), MmapServeMode::Mmap);
assert!(!MmapServeMode::default().promote_on_load());
}
#[test]
fn mmap_serve_mode_parse_enabled_spellings() {
for s in ["", "1", "true", "TRUE", " yes ", "On", "enabled"] {
assert_eq!(
MmapServeMode::parse(s),
MmapServeMode::Mmap,
"{s:?} should enable mmap serving"
);
}
}
#[test]
fn mmap_serve_mode_parse_disabled_spellings() {
for s in ["0", "false", "FALSE", " no ", "Off", "disabled"] {
assert_eq!(
MmapServeMode::parse(s),
MmapServeMode::EagerHeap,
"{s:?} should disable mmap serving (eager heap)"
);
assert!(MmapServeMode::parse(s).promote_on_load());
}
}
#[test]
fn mmap_serve_mode_parse_garbage_defaults_to_mmap() {
assert_eq!(MmapServeMode::parse("banana"), MmapServeMode::Mmap);
}
#[test]
fn vector_quant_default_is_none() {
assert_eq!(VectorQuant::default(), VectorQuant::None);
assert_eq!(VectorQuant::None.scalar_kind(), ScalarKind::F32);
}
#[test]
fn vector_quant_parse_spellings() {
for s in ["", "none", "f32", "FP32", " full "] {
assert_eq!(VectorQuant::parse(s), VectorQuant::None, "{s:?}");
}
for s in ["f16", "FP16", " half "] {
assert_eq!(VectorQuant::parse(s), VectorQuant::F16, "{s:?}");
}
for s in ["i8", "INT8", " i8 "] {
assert_eq!(VectorQuant::parse(s), VectorQuant::I8, "{s:?}");
}
}
#[test]
fn vector_quant_parse_garbage_defaults_to_none() {
assert_eq!(VectorQuant::parse("bf16"), VectorQuant::None);
assert_eq!(VectorQuant::parse("q4"), VectorQuant::None);
}
#[test]
fn vector_quant_scalar_kind() {
assert_eq!(VectorQuant::None.scalar_kind(), ScalarKind::F32);
assert_eq!(VectorQuant::F16.scalar_kind(), ScalarKind::F16);
assert_eq!(VectorQuant::I8.scalar_kind(), ScalarKind::I8);
}
#[test]
fn vector_quant_labels() {
assert_eq!(VectorQuant::None.label(), "f32 (none)");
assert_eq!(VectorQuant::F16.label(), "f16");
assert_eq!(VectorQuant::I8.label(), "i8");
}
}