use core::ptr::NonNull;
use remdb::config::{DbConfig, WALConfig};
use remdb::memory::allocator;
use remdb::time_series::table::TimeSeriesConfig;
use remdb::{RemDb, Result};
struct SimpleAllocator;
impl remdb::config::MemoryAllocator for SimpleAllocator {
fn allocate(&self, _size: usize) -> Option<NonNull<u8>> {
static mut BUFFER: [u8; 4 * 1024 * 1024] = [0u8; 4 * 1024 * 1024];
unsafe { Some(NonNull::new(BUFFER.as_mut_ptr()).unwrap()) }
}
fn deallocate(&self, _ptr: NonNull<u8>, _size: usize) {
}
}
unsafe impl Sync for SimpleAllocator {}
static ALLOCATOR: SimpleAllocator = SimpleAllocator;
fn main() -> Result<()> {
let mut mem_buffer = Box::new([0u8; 64 * 1024 * 1024]); let ptr = mem_buffer.as_mut_ptr();
allocator::init_global_allocator(ptr, mem_buffer.len())?;
let config = Box::leak(Box::new(DbConfig {
tables: vec![], total_memory: 64 * 1024 * 1024, low_power_mode_supported: false,
low_power_max_records: None,
default_max_records: 1000,
memory_allocator: &ALLOCATOR, wal_config: WALConfig {
log_path: "./wal",
log_mode: remdb::config::LogMode::Async,
checkpoint_interval_ms: 60000,
log_file_size_limit: 16 * 1024 * 1024,
log_prealloc_size: 4 * 1024 * 1024,
log_segment_size: 16 * 1024 * 1024,
retained_checkpoints: 2,
max_consecutive_invalid: 100,
skip_threshold: 1000,
skip_block_size: 1024 * 1024,
max_skip_attempts: 3,
compression_type: remdb::config::WALCompressionType::None,
compression_level: 3,
},
time_series_defaults: TimeSeriesConfig {
partition_duration_secs: 3600, retention_period_secs: 7 * 24 * 3600, compression: remdb::time_series::compression::CompressionType::None,
max_partitions: 100,
},
#[cfg(feature = "ha")]
ha_config: None,
#[cfg(feature = "pubsub")]
pubsub_config: None,
model_worker_config: Default::default(),
}));
let mut db = RemDb::new(config);
db.init()?;
let test_cases = [
(
"L2 distance",
r#"CREATE TABLE products_l2 (
id INT32 PRIMARY KEY,
name TEXT,
embedding VECTOR(4) WITH DISTANCE=L2
)"#,
),
(
"COSINE distance",
r#"CREATE TABLE products_cosine (
id INT32 PRIMARY KEY,
name TEXT,
embedding VECTOR(4) WITH DISTANCE=COSINE
)"#,
),
(
"IP distance",
r#"CREATE TABLE products_ip (
id INT32 PRIMARY KEY,
name TEXT,
embedding VECTOR(4) WITH DISTANCE=IP
)"#,
),
(
"INNER_PRODUCT full name",
r#"CREATE TABLE products_inner_product (
id INT32 PRIMARY KEY,
name TEXT,
embedding VECTOR(4) WITH DISTANCE=INNER_PRODUCT
)"#,
),
];
for (test_name, sql) in test_cases.iter() {
println!("\nTest {}:", test_name);
println!("SQL: {}", sql);
match db.sql_query(sql) {
Ok(_) => println!("[OK] Success"),
Err(e) => println!("[ERROR] Failed: {}", e),
}
}
println!("\nVerify tables created:");
let tables = [
"products_l2",
"products_cosine",
"products_ip",
"products_inner_product",
];
for table in tables.iter() {
let select_sql = format!("SELECT * FROM {}", table);
match db.sql_query(&select_sql) {
Ok(result) => println!(
"[OK] Table {} exists, returned {} rows",
table,
result.rows.len()
),
Err(e) => println!("[ERROR] Table {} verification failed: {}", table, e),
}
}
println!("\nAll distance type tests completed!");
Ok(())
}