pub mod registry;
pub mod analyzer;
pub mod router;
pub mod classifier;
pub mod discovery;
pub mod metrics;
pub mod admin;
pub use registry::{
SchemaRegistry, TableSchema, ColumnSchema, IndexSchema,
AccessPattern, DataTemperature, WorkloadType, ShardingConfig,
NodeCapabilities, PartitionKey, Relationship,
};
pub use analyzer::{QueryAnalyzer, QueryAnalysis, TableRef, ShardKeyValue};
pub use router::{
SchemaAwareRouter, RoutingDecision, RoutingPreference,
RAGStage, AIWorkloadType, RouteTarget, RoutingReason,
};
pub use classifier::{LearningClassifier, ClassificationModel, QueryHistory, QueryType, TableClassification};
pub use admin::{SchemaRoutingAdmin, AdminError};
pub use discovery::{SchemaDiscovery, DiscoveryConfig, DiscoveryError};
pub use metrics::{
SchemaRoutingMetrics, RoutingStats, TableStats, WorkloadStats,
AIWorkloadStats, RAGStats, MetricsReport,
};
use std::collections::HashMap;
use std::time::Duration;
#[derive(Debug, Clone)]
pub struct SchemaRoutingConfig {
pub enabled: bool,
pub auto_discover: bool,
pub refresh_interval: Duration,
pub learning_enabled: bool,
pub classification_threshold: u64,
pub default_temperature: DataTemperature,
pub default_workload: WorkloadType,
pub tables: Vec<TableConfig>,
pub node_capabilities: HashMap<String, NodeCapabilities>,
}
impl Default for SchemaRoutingConfig {
fn default() -> Self {
Self {
enabled: true,
auto_discover: true,
refresh_interval: Duration::from_secs(300),
learning_enabled: true,
classification_threshold: 1000,
default_temperature: DataTemperature::Warm,
default_workload: WorkloadType::Mixed,
tables: Vec::new(),
node_capabilities: HashMap::new(),
}
}
}
#[derive(Debug, Default)]
pub struct SchemaRoutingConfigBuilder {
config: SchemaRoutingConfig,
}
impl SchemaRoutingConfigBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn enabled(mut self, enabled: bool) -> Self {
self.config.enabled = enabled;
self
}
pub fn auto_discover(mut self, auto_discover: bool) -> Self {
self.config.auto_discover = auto_discover;
self
}
pub fn refresh_interval(mut self, interval: Duration) -> Self {
self.config.refresh_interval = interval;
self
}
pub fn learning_enabled(mut self, enabled: bool) -> Self {
self.config.learning_enabled = enabled;
self
}
pub fn classification_threshold(mut self, threshold: u64) -> Self {
self.config.classification_threshold = threshold;
self
}
pub fn default_temperature(mut self, temp: DataTemperature) -> Self {
self.config.default_temperature = temp;
self
}
pub fn default_workload(mut self, workload: WorkloadType) -> Self {
self.config.default_workload = workload;
self
}
pub fn add_table(mut self, table: TableConfig) -> Self {
self.config.tables.push(table);
self
}
pub fn add_node_capability(mut self, node_name: impl Into<String>, caps: NodeCapabilities) -> Self {
self.config.node_capabilities.insert(node_name.into(), caps);
self
}
pub fn build(self) -> SchemaRoutingConfig {
self.config
}
}
impl SchemaRoutingConfig {
pub fn builder() -> SchemaRoutingConfigBuilder {
SchemaRoutingConfigBuilder::new()
}
}
#[derive(Debug, Clone)]
pub struct TableConfig {
pub name: String,
pub temperature: DataTemperature,
pub workload: WorkloadType,
pub access_pattern: AccessPattern,
pub shard_key: Option<String>,
pub shard_count: Option<u32>,
pub preferred_nodes: Vec<String>,
}
impl TableConfig {
pub fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
temperature: DataTemperature::Warm,
workload: WorkloadType::Mixed,
access_pattern: AccessPattern::Mixed,
shard_key: None,
shard_count: None,
preferred_nodes: Vec::new(),
}
}
pub fn with_temperature(mut self, temp: DataTemperature) -> Self {
self.temperature = temp;
self
}
pub fn with_workload(mut self, workload: WorkloadType) -> Self {
self.workload = workload;
self
}
pub fn with_access_pattern(mut self, pattern: AccessPattern) -> Self {
self.access_pattern = pattern;
self
}
pub fn with_shard_key(mut self, key: impl Into<String>, count: u32) -> Self {
self.shard_key = Some(key.into());
self.shard_count = Some(count);
self
}
pub fn with_preferred_node(mut self, node: impl Into<String>) -> Self {
self.preferred_nodes.push(node.into());
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum SyncMode {
Sync,
Async,
Primary,
}
#[derive(Debug, Clone)]
pub struct NodeInfo {
pub id: String,
pub name: String,
pub is_primary: bool,
pub sync_mode: SyncMode,
pub capabilities: NodeCapabilities,
pub current_load: f64,
pub current_latency_ms: u64,
pub indexes_in_memory: Vec<String>,
}
impl NodeInfo {
pub fn new(id: impl Into<String>, name: impl Into<String>) -> Self {
Self {
id: id.into(),
name: name.into(),
is_primary: false,
sync_mode: SyncMode::Async,
capabilities: NodeCapabilities::default(),
current_load: 0.0,
current_latency_ms: 0,
indexes_in_memory: Vec::new(),
}
}
pub fn as_primary(mut self) -> Self {
self.is_primary = true;
self.sync_mode = SyncMode::Primary;
self
}
pub fn with_sync_mode(mut self, mode: SyncMode) -> Self {
self.sync_mode = mode;
self
}
pub fn with_capabilities(mut self, caps: NodeCapabilities) -> Self {
self.capabilities = caps;
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_config_builder() {
let config = SchemaRoutingConfig::builder()
.enabled(true)
.auto_discover(true)
.refresh_interval(Duration::from_secs(60))
.learning_enabled(true)
.default_temperature(DataTemperature::Hot)
.build();
assert!(config.enabled);
assert!(config.auto_discover);
assert_eq!(config.refresh_interval, Duration::from_secs(60));
assert_eq!(config.default_temperature, DataTemperature::Hot);
}
#[test]
fn test_table_config_builder() {
let config = TableConfig::new("users")
.with_temperature(DataTemperature::Hot)
.with_workload(WorkloadType::OLTP)
.with_access_pattern(AccessPattern::PointLookup)
.with_preferred_node("primary")
.with_preferred_node("standby-sync");
assert_eq!(config.name, "users");
assert_eq!(config.temperature, DataTemperature::Hot);
assert_eq!(config.workload, WorkloadType::OLTP);
assert_eq!(config.preferred_nodes.len(), 2);
}
#[test]
fn test_node_info() {
let node = NodeInfo::new("node1", "primary")
.as_primary()
.with_capabilities(NodeCapabilities {
vector_search: true,
gpu_acceleration: true,
..Default::default()
});
assert!(node.is_primary);
assert_eq!(node.sync_mode, SyncMode::Primary);
assert!(node.capabilities.vector_search);
}
}