use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
pub db_path: PathBuf,
pub wal: WalConfig,
pub value_log: ValueLogConfig,
pub memtable: MemtableConfig,
pub sst: SstConfig,
pub compaction: CompactionConfig,
pub cache: CacheConfig,
pub learned_index: LearnedIndexConfig,
pub rl_agent: RlAgentConfig,
pub performance: PerformanceConfig,
}
impl Default for Config {
fn default() -> Self {
Self {
db_path: PathBuf::from("./auradb_data"),
wal: WalConfig::default(),
value_log: ValueLogConfig::default(),
memtable: MemtableConfig::default(),
sst: SstConfig::default(),
compaction: CompactionConfig::default(),
cache: CacheConfig::default(),
learned_index: LearnedIndexConfig::default(),
rl_agent: RlAgentConfig::default(),
performance: PerformanceConfig::default(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WalConfig {
pub wal_path: PathBuf,
pub max_file_size: u64,
pub async_writes: bool,
pub sync_policy: WalSyncPolicy,
pub buffer_size: usize,
}
impl Default for WalConfig {
fn default() -> Self {
Self {
wal_path: PathBuf::from("./auradb_data/wal"),
max_file_size: 64 * 1024 * 1024, async_writes: true,
sync_policy: WalSyncPolicy::EveryWrite,
buffer_size: 64 * 1024, }
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum WalSyncPolicy {
EveryWrite,
EveryNWrites(u64),
EveryNMs(u64),
Manual,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValueLogConfig {
pub vlog_path: PathBuf,
pub max_segment_size: u64,
pub separation_threshold: usize,
pub write_queues: usize,
pub cache_size: usize,
pub compress_values: bool,
pub compression_algorithm: CompressionAlgorithm,
}
impl Default for ValueLogConfig {
fn default() -> Self {
Self {
vlog_path: PathBuf::from("./auradb_data/vlog"),
max_segment_size: 256 * 1024 * 1024, separation_threshold: 1024, write_queues: 4,
cache_size: 64 * 1024 * 1024, compress_values: true,
compression_algorithm: CompressionAlgorithm::Lz4,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Copy)]
pub enum CompressionAlgorithm {
None,
Lz4,
Zstd,
Snappy,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemtableConfig {
pub max_size: usize,
pub implementation: MemtableImpl,
pub count: usize,
pub flush_threshold: f64,
}
impl Default for MemtableConfig {
fn default() -> Self {
Self {
max_size: 64 * 1024 * 1024, implementation: MemtableImpl::SkipList,
count: 2,
flush_threshold: 0.8, }
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum MemtableImpl {
SkipList,
Art,
BTree,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SstConfig {
pub sst_path: PathBuf,
pub target_file_size: u64,
pub block_size: usize,
pub use_bloom_filters: bool,
pub bloom_bits_per_key: f64,
pub use_ribbon_filters: bool,
pub compression: CompressionAlgorithm,
}
impl Default for SstConfig {
fn default() -> Self {
Self {
sst_path: PathBuf::from("./auradb_data/sst"),
target_file_size: 64 * 1024 * 1024, block_size: 64 * 1024, use_bloom_filters: true,
bloom_bits_per_key: 10.0,
use_ribbon_filters: false,
compression: CompressionAlgorithm::Lz4,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompactionConfig {
pub strategy: CompactionStrategy,
pub max_threads: usize,
pub io_rate_limit: Option<u64>,
pub use_rl_agent: bool,
pub triggers: CompactionTriggers,
}
impl Default for CompactionConfig {
fn default() -> Self {
Self {
strategy: CompactionStrategy::Leveled,
max_threads: 4,
io_rate_limit: Some(100), use_rl_agent: true,
triggers: CompactionTriggers::default(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CompactionStrategy {
Leveled,
Tiered,
Flexible,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompactionTriggers {
pub level0_files: usize,
pub level_size_ratio: f64,
pub write_amplification: f64,
}
impl Default for CompactionTriggers {
fn default() -> Self {
Self {
level0_files: 4,
level_size_ratio: 10.0,
write_amplification: 5.0,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CacheConfig {
pub block_cache_size: usize,
pub vlog_cache_size: usize,
pub eviction_policy: EvictionPolicy,
pub unified_cache: bool,
}
impl Default for CacheConfig {
fn default() -> Self {
Self {
block_cache_size: 256 * 1024 * 1024, vlog_cache_size: 64 * 1024 * 1024, eviction_policy: EvictionPolicy::Arc,
unified_cache: true,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum EvictionPolicy {
Lru,
Arc,
TinyLfu,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LearnedIndexConfig {
pub enabled: bool,
pub model_type: ModelType,
pub training_frequency: usize,
pub online_tuning: bool,
pub fallback_method: FallbackMethod,
}
impl Default for LearnedIndexConfig {
fn default() -> Self {
Self {
enabled: true,
model_type: ModelType::PiecewiseLinear,
training_frequency: 10000,
online_tuning: true,
fallback_method: FallbackMethod::BinarySearch,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ModelType {
PiecewiseLinear,
Rmi,
TinyNn,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum FallbackMethod {
BinarySearch,
FencePointers,
BloomScan,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RlAgentConfig {
pub enabled: bool,
pub learning_rate: f64,
pub exploration_rate: f64,
pub state_update_frequency: usize,
pub offline_training: bool,
pub training_data_path: Option<PathBuf>,
}
impl Default for RlAgentConfig {
fn default() -> Self {
Self {
enabled: true,
learning_rate: 0.01,
exploration_rate: 0.1,
state_update_frequency: 1000,
offline_training: false,
training_data_path: None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceConfig {
pub worker_threads: usize,
pub io_buffer_size: usize,
pub direct_io: bool,
pub memory_mapped: bool,
pub numa_aware: bool,
}
impl Default for PerformanceConfig {
fn default() -> Self {
Self {
worker_threads: num_cpus::get(),
io_buffer_size: 1024 * 1024, direct_io: false,
memory_mapped: true,
numa_aware: false,
}
}
}
impl Config {
pub fn new() -> Self {
Self::default()
}
pub fn with_db_path(mut self, path: PathBuf) -> Self {
self.db_path = path;
self
}
pub fn with_wal(mut self, wal: WalConfig) -> Self {
self.wal = wal;
self
}
pub fn with_value_log(mut self, vlog: ValueLogConfig) -> Self {
self.value_log = vlog;
self
}
pub fn with_memtable(mut self, memtable: MemtableConfig) -> Self {
self.memtable = memtable;
self
}
pub fn with_sst(mut self, sst: SstConfig) -> Self {
self.sst = sst;
self
}
pub fn with_compaction(mut self, compaction: CompactionConfig) -> Self {
self.compaction = compaction;
self
}
pub fn with_cache(mut self, cache: CacheConfig) -> Self {
self.cache = cache;
self
}
pub fn with_learned_index(mut self, learned_index: LearnedIndexConfig) -> Self {
self.learned_index = learned_index;
self
}
pub fn with_rl_agent(mut self, rl_agent: RlAgentConfig) -> Self {
self.rl_agent = rl_agent;
self
}
pub fn with_performance(mut self, performance: PerformanceConfig) -> Self {
self.performance = performance;
self
}
pub fn validate(&self) -> Result<(), String> {
if self.wal.max_file_size == 0 {
return Err("WAL max file size must be greater than 0".to_string());
}
if self.value_log.max_segment_size == 0 {
return Err("Value log max segment size must be greater than 0".to_string());
}
if self.memtable.max_size == 0 {
return Err("Memtable max size must be greater than 0".to_string());
}
if self.sst.target_file_size == 0 {
return Err("SST target file size must be greater than 0".to_string());
}
if self.cache.block_cache_size == 0 {
return Err("Block cache size must be greater than 0".to_string());
}
Ok(())
}
}