pub mod brute_force_bm25;
pub mod cas_conformance;
pub mod fault_storage;
pub mod admit_trace {
use std::sync::Mutex;
static ADMITS: Mutex<Vec<Vec<u32>>> = Mutex::new(Vec::new());
static FINES: Mutex<Vec<Vec<(u32, f32)>>> = Mutex::new(Vec::new());
pub fn record_admit(cells: Vec<u32>) {
ADMITS.lock().expect("admit probe lock").push(cells);
}
pub fn record_fine(ranked: Vec<(u32, f32)>) {
FINES.lock().expect("fine probe lock").push(ranked);
}
#[allow(clippy::type_complexity)]
pub fn drain() -> (Vec<Vec<u32>>, Vec<Vec<(u32, f32)>>) {
(
std::mem::take(&mut *ADMITS.lock().expect("admit probe lock")),
std::mem::take(&mut *FINES.lock().expect("fine probe lock")),
)
}
}
pub mod served_shortlist_probe {
use std::sync::Mutex;
static RECORDS: Mutex<Vec<(usize, usize)>> = Mutex::new(Vec::new());
pub fn record(limit: usize, cell_floor: usize) {
RECORDS
.lock()
.expect("shortlist probe lock")
.push((limit, cell_floor));
}
pub fn drain() -> Vec<(usize, usize)> {
std::mem::take(&mut *RECORDS.lock().expect("shortlist probe lock"))
}
}
use std::{collections::HashSet, path::Path, sync::Arc};
use arrow_array::{Decimal128Array, LargeStringArray, RecordBatch};
use arrow_schema::{DataType, Field, Schema};
use rayon::ThreadPoolBuilder;
use crate::{
storage::StorageProvider,
superfile::{
builder::{FtsConfig, VectorConfig},
fts::tokenize::{AsciiLowerTokenizer, Tokenizer},
vector::{distance::Metric, rerank_codec::RerankCodec},
},
supertable::{
SupertableOptions,
reader_cache::{ColdFetchMode, DiskCacheConfig, DiskCacheStore, LruPolicy},
},
};
const TEST_DISK_CACHE_BUDGET_BYTES: u64 = 1 << 30;
const TEST_COLD_FETCH_STREAMS: usize = 4;
const TEST_COLD_FETCH_CHUNK_BYTES: u64 = 1 << 20;
pub fn default_disk_cache(
storage: Arc<dyn StorageProvider>,
cache_root: &Path,
) -> Arc<DiskCacheStore> {
let cfg = DiskCacheConfig {
cache_root: cache_root.to_path_buf(),
disk_budget_bytes: TEST_DISK_CACHE_BUDGET_BYTES,
cold_fetch_mode: ColdFetchMode::HybridWithPrefetch,
cold_fetch_streams: TEST_COLD_FETCH_STREAMS,
cold_fetch_chunk_bytes: TEST_COLD_FETCH_CHUNK_BYTES,
mmap_cold_threshold_secs: 0,
mmap_sweep_interval_secs: 0,
eviction: Box::new(LruPolicy::new()),
verify_crc_on_open: true,
..Default::default()
};
let pinned: Arc<dyn Fn() -> HashSet<_> + Send + Sync> = Arc::new(HashSet::new);
DiskCacheStore::new(storage, cfg, pinned).expect("test disk cache")
}
pub fn lazy_foreground_disk_cache(
storage: Arc<dyn StorageProvider>,
cache_root: &Path,
) -> Arc<DiskCacheStore> {
let cfg = DiskCacheConfig {
cache_root: cache_root.to_path_buf(),
disk_budget_bytes: TEST_DISK_CACHE_BUDGET_BYTES,
cold_fetch_mode: ColdFetchMode::LazyForegroundWithBackgroundFill,
cold_fetch_streams: TEST_COLD_FETCH_STREAMS,
cold_fetch_chunk_bytes: TEST_COLD_FETCH_CHUNK_BYTES,
mmap_cold_threshold_secs: 0,
mmap_sweep_interval_secs: 0,
eviction: Box::new(LruPolicy::new()),
verify_crc_on_open: true,
..Default::default()
};
let pinned: Arc<dyn Fn() -> HashSet<_> + Send + Sync> = Arc::new(HashSet::new);
DiskCacheStore::new(storage, cfg, pinned).expect("test lazy-foreground disk cache")
}
pub fn decimal128_ids<I: IntoIterator<Item = u64>>(ids: I) -> Decimal128Array {
Decimal128Array::from(ids.into_iter().map(|v| v as i128).collect::<Vec<_>>())
.with_precision_and_scale(38, 0)
.expect("Decimal128(38, 0) is a valid precision/scale pair")
}
pub fn decimal128_id_field(name: &str) -> Field {
Field::new(name, DataType::Decimal128(38, 0), false)
}
pub fn default_tokenizer() -> Arc<dyn Tokenizer> {
Arc::new(AsciiLowerTokenizer)
}
pub fn default_vector_config(column: &str, rot_seed: u64) -> VectorConfig {
VectorConfig {
column: column.into(),
dim: 16,
rot_seed,
metric: Metric::Cosine,
rerank_codec: RerankCodec::Fp32,
provided_centroids: None,
}
}
pub fn schema_id_title() -> Arc<Schema> {
Arc::new(Schema::new(vec![Field::new(
"title",
DataType::LargeUtf8,
false,
)]))
}
pub fn build_title_batch(titles: &[&str]) -> RecordBatch {
let titles_arr = LargeStringArray::from(titles.to_vec());
RecordBatch::try_new(schema_id_title(), vec![Arc::new(titles_arr)])
.expect("RecordBatch shape matches schema_id_title")
}
pub fn default_supertable_options() -> SupertableOptions {
let pool = Arc::new(
ThreadPoolBuilder::new()
.num_threads(1)
.build()
.expect("rayon ThreadPoolBuilder with num_threads(1) builds"),
);
SupertableOptions::new(
schema_id_title(),
vec![FtsConfig {
column: "title".into(),
positions: false,
}],
vec![],
Some(default_tokenizer()),
)
.expect("SupertableOptions::new with default test fixture args")
.with_writer_pool(pool)
}