use rawdb::Database;
use tempfile::TempDir;
use vecdb::{Result, StoredVec, Version};
fn setup_test_db() -> Result<(Database, TempDir)> {
let temp_dir = TempDir::new()?;
let db = Database::open(temp_dir.path())?;
Ok((db, temp_dir))
}
fn run_write_visibility_test<V>() -> Result<(), Box<dyn std::error::Error>>
where
V: StoredVec<I = usize, T = u32>,
{
let version = Version::ZERO;
let (database, _temp) = setup_test_db()?;
let mut vec_a: V = V::forced_import(&database, "vec_a", version)?;
for i in 0..100u32 {
vec_a.push(i);
}
vec_a.write()?;
let vec_a_reader: V = V::forced_import(&database, "vec_a", version)?;
assert_eq!(
vec_a_reader.len(),
100,
"vec_b should see vec_a's written data"
);
for i in 0..100usize {
assert_eq!(
vec_a_reader.collect_one(i),
Some(i as u32),
"vec_b should read correct value at index {}",
i
);
}
Ok(())
}
fn run_compute_chain_test<V>() -> Result<(), Box<dyn std::error::Error>>
where
V: StoredVec<I = usize, T = u32>,
{
let version = Version::ZERO;
let (database, _temp) = setup_test_db()?;
let mut vec_a: V = V::forced_import(&database, "chain_a", version)?;
for i in 0..50u32 {
vec_a.push(i * 2); }
vec_a.write()?;
let vec_a_for_read: V = V::forced_import(&database, "chain_a", version)?;
let mut vec_b: V = V::forced_import(&database, "chain_b", version)?;
for i in 0..25usize {
let a1 = vec_a_for_read.collect_one(i * 2).unwrap();
let a2 = vec_a_for_read.collect_one(i * 2 + 1).unwrap();
vec_b.push(a1 + a2);
}
vec_b.write()?;
let vec_b_for_read: V = V::forced_import(&database, "chain_b", version)?;
let mut vec_c: V = V::forced_import(&database, "chain_c", version)?;
let mut cumsum = 0u32;
for val in vec_b_for_read.collect() {
cumsum += val;
vec_c.push(cumsum);
}
vec_c.write()?;
let vec_c_verify: V = V::forced_import(&database, "chain_c", version)?;
assert_eq!(vec_c_verify.len(), 25);
let expected_b: Vec<u32> = (0..25).map(|i| (i * 4) + (i * 4 + 2)).collect();
let expected_c: Vec<u32> = expected_b
.iter()
.scan(0u32, |acc, &x| {
*acc += x;
Some(*acc)
})
.collect();
let actual_c: Vec<u32> = vec_c_verify.collect();
assert_eq!(
actual_c, expected_c,
"compute chain should produce correct results"
);
Ok(())
}
fn run_write_returns_bool_test<V>() -> Result<(), Box<dyn std::error::Error>>
where
V: StoredVec<I = usize, T = u32>,
{
let version = Version::ZERO;
let (database, _temp) = setup_test_db()?;
let mut vec: V = V::forced_import(&database, "bool_test", version)?;
assert!(!vec.write()?, "write() with no data should return false");
vec.push(42);
assert!(vec.write()?, "write() with data should return true");
assert!(
!vec.write()?,
"write() after already written should return false"
);
vec.push(43);
assert!(vec.write()?, "write() with new data should return true");
Ok(())
}
mod bytes {
use super::*;
use vecdb::BytesVec;
type V = BytesVec<usize, u32>;
#[test]
fn test_write_visibility() -> Result<(), Box<dyn std::error::Error>> {
run_write_visibility_test::<V>()
}
#[test]
fn test_compute_chain() -> Result<(), Box<dyn std::error::Error>> {
run_compute_chain_test::<V>()
}
#[test]
fn test_write_returns_bool() -> Result<(), Box<dyn std::error::Error>> {
run_write_returns_bool_test::<V>()
}
}
#[cfg(feature = "pco")]
mod pco {
use super::*;
use vecdb::PcoVec;
type V = PcoVec<usize, u32>;
#[test]
fn test_write_visibility() -> Result<(), Box<dyn std::error::Error>> {
run_write_visibility_test::<V>()
}
#[test]
fn test_compute_chain() -> Result<(), Box<dyn std::error::Error>> {
run_compute_chain_test::<V>()
}
#[test]
fn test_write_returns_bool() -> Result<(), Box<dyn std::error::Error>> {
run_write_returns_bool_test::<V>()
}
}
#[cfg(feature = "lz4")]
mod lz4 {
use super::*;
use vecdb::LZ4Vec;
type V = LZ4Vec<usize, u32>;
#[test]
fn test_write_visibility() -> Result<(), Box<dyn std::error::Error>> {
run_write_visibility_test::<V>()
}
#[test]
fn test_compute_chain() -> Result<(), Box<dyn std::error::Error>> {
run_compute_chain_test::<V>()
}
#[test]
fn test_write_returns_bool() -> Result<(), Box<dyn std::error::Error>> {
run_write_returns_bool_test::<V>()
}
}
#[cfg(feature = "zstd")]
mod zstd {
use super::*;
use vecdb::ZstdVec;
type V = ZstdVec<usize, u32>;
#[test]
fn test_write_visibility() -> Result<(), Box<dyn std::error::Error>> {
run_write_visibility_test::<V>()
}
#[test]
fn test_compute_chain() -> Result<(), Box<dyn std::error::Error>> {
run_compute_chain_test::<V>()
}
#[test]
fn test_write_returns_bool() -> Result<(), Box<dyn std::error::Error>> {
run_write_returns_bool_test::<V>()
}
}
#[cfg(feature = "zerocopy")]
mod zerocopy {
use super::*;
use vecdb::ZeroCopyVec;
type V = ZeroCopyVec<usize, u32>;
#[test]
fn test_write_visibility() -> Result<(), Box<dyn std::error::Error>> {
run_write_visibility_test::<V>()
}
#[test]
fn test_compute_chain() -> Result<(), Box<dyn std::error::Error>> {
run_compute_chain_test::<V>()
}
#[test]
fn test_write_returns_bool() -> Result<(), Box<dyn std::error::Error>> {
run_write_returns_bool_test::<V>()
}
}