use crate::simd_native::{cosine_similarity_native, DistanceEngine, SimdLevel};
use crate::sparse_index::{SparseInvertedIndex, SparseVector};
use crate::velesql::{ParseError, Query, QueryCache};
use std::hash::{BuildHasher, Hasher};
#[must_use]
pub fn cosine_scalar(a: &[f32], b: &[f32]) -> f32 {
crate::simd_native::scalar::cosine_scalar(a, b)
}
#[must_use]
pub fn cosine_dispatch(a: &[f32], b: &[f32]) -> f32 {
cosine_similarity_native(a, b)
}
#[must_use]
pub fn cosine_resolved(a: &[f32], b: &[f32]) -> f32 {
let engine = DistanceEngine::new(a.len());
engine.cosine_similarity(a, b)
}
#[must_use]
pub fn detected_simd_level() -> SimdLevel {
crate::simd_native::simd_level()
}
#[cfg(target_arch = "x86_64")]
#[must_use]
pub fn cosine_avx2_2acc(a: &[f32], b: &[f32]) -> Option<f32> {
if std::arch::is_x86_feature_detected!("avx2") && std::arch::is_x86_feature_detected!("fma") {
Some(unsafe { crate::simd_native::cosine_fused_avx2_2acc(a, b) })
} else {
None
}
}
#[cfg(target_arch = "x86_64")]
#[must_use]
pub fn cosine_avx2_4acc(a: &[f32], b: &[f32]) -> Option<f32> {
if std::arch::is_x86_feature_detected!("avx2") && std::arch::is_x86_feature_detected!("fma") {
Some(unsafe { crate::simd_native::cosine_fused_avx2(a, b) })
} else {
None
}
}
#[cfg(target_arch = "x86_64")]
#[must_use]
pub fn cosine_avx512(a: &[f32], b: &[f32]) -> Option<f32> {
if std::arch::is_x86_feature_detected!("avx512f") {
Some(unsafe { crate::simd_native::cosine_fused_avx512(a, b) })
} else {
None
}
}
pub fn sparse_insert_batch(index: &SparseInvertedIndex, docs: &[(u64, SparseVector)]) {
index.insert_batch_chunk(docs);
}
#[must_use]
pub fn sparse_linear_scan_search(
index: &SparseInvertedIndex,
query: &SparseVector,
k: usize,
) -> Vec<crate::index::sparse::ScoredDoc> {
crate::sparse_index::search::linear_scan_search_for_bench(index, query, k)
}
#[must_use]
pub fn sparse_maxscore_search(
index: &SparseInvertedIndex,
query: &SparseVector,
k: usize,
) -> Vec<crate::index::sparse::ScoredDoc> {
crate::sparse_index::search::maxscore_search_for_bench(index, query, k)
}
#[must_use]
pub fn sparse_scoring_ops() -> u64 {
crate::sparse_index::op_count::scoring_ops()
}
pub fn reset_sparse_scoring_ops() {
crate::sparse_index::op_count::reset_scoring_ops();
}
pub fn velesql_parse_without_stats(
cache: &QueryCache,
query: &str,
) -> Result<std::sync::Arc<Query>, ParseError> {
cache.parse_without_stats(query)
}
#[must_use]
pub fn velesql_canonical_hash(query: &str) -> u64 {
let canonical = query.split_whitespace().collect::<Vec<_>>().join(" ");
let mut hasher = rustc_hash::FxBuildHasher.build_hasher();
hasher.write(canonical.as_bytes());
hasher.finish()
}
#[cfg(feature = "persistence")]
#[must_use]
pub fn hnsw_distance_evals() -> u64 {
crate::index::hnsw::eval_count::distance_evals()
}
#[cfg(feature = "persistence")]
pub fn reset_hnsw_distance_evals() {
crate::index::hnsw::eval_count::reset_distance_evals();
}
#[must_use]
pub fn vacuum_reconciled_under_guard() -> u64 {
crate::index::hnsw::index::swap_count::reconciled_under_guard()
}
#[must_use]
pub fn vacuum_peak_reconciled_under_guard() -> u64 {
crate::index::hnsw::index::swap_count::peak_reconciled_under_guard()
}
#[must_use]
pub fn vacuum_settled_under_seal() -> u64 {
crate::index::hnsw::index::swap_count::settled_under_seal()
}
pub fn reset_vacuum_reconciled_under_guard() {
crate::index::hnsw::index::swap_count::reset_reconciled_under_guard();
}