//! Key-Value store abstraction use std::sync::Arc; use std::time::Duration; use dashmap::DashMap; use crate::error::{ClusterError, Result}; /// KV store interface /// /// Provides access to distributed key-value storage with namespace isolation. pub struct Kv { namespaces: DashMap>, default_namespace: Arc, } impl Kv { /// Create a new KV store pub(crate) fn new() -> Self { let default_namespace = Arc::new(KvNamespace::new("default".to_string())); Self { namespaces: DashMap::new(), default_namespace, } } /// Get or create a namespace pub fn namespace(&self, name: &str) -> Arc { if name == "default" { return self.default_namespace.clone(); } self.namespaces .entry(name.to_string()) .or_insert_with(|| Arc::new(KvNamespace::new(name.to_string()))) .clone() } /// Get the default namespace pub fn default_namespace(&self) -> &Arc { &self.default_namespace } // Convenience methods on default namespace /// Get a value by key from the default namespace pub async fn get(&self, key: impl AsRef<[u8]>) -> Result>> { self.default_namespace.get(key).await } /// Put a value in the default namespace pub async fn put(&self, key: impl AsRef<[u8]>, value: impl AsRef<[u8]>) -> Result { self.default_namespace.put(key, value).await } /// Delete a key from the default namespace pub async fn delete(&self, key: impl AsRef<[u8]>) -> Result { self.default_namespace.delete(key).await } /// Compare-and-swap in the default namespace pub async fn compare_and_swap( &self, key: impl AsRef<[u8]>, expected_version: u64, value: impl AsRef<[u8]>, ) -> Result { self.default_namespace .compare_and_swap(key, expected_version, value) .await } } /// KV namespace for data isolation pub struct KvNamespace { name: String, // TODO: Add storage backend and raft reference } impl KvNamespace { pub(crate) fn new(name: String) -> Self { Self { name } } /// Get the namespace name pub fn name(&self) -> &str { &self.name } /// Get a value by key pub async fn get(&self, _key: impl AsRef<[u8]>) -> Result>> { // TODO: Implement with storage backend Ok(None) } /// Get with revision pub async fn get_with_revision( &self, _key: impl AsRef<[u8]>, ) -> Result, u64)>> { // TODO: Implement with storage backend Ok(None) } /// Put a value (goes through Raft if available) pub async fn put(&self, _key: impl AsRef<[u8]>, _value: impl AsRef<[u8]>) -> Result { // TODO: Implement with Raft Ok(0) } /// Put with options pub async fn put_with_options( &self, _key: impl AsRef<[u8]>, _value: impl AsRef<[u8]>, _options: KvOptions, ) -> Result { // TODO: Implement with Raft Ok(KvPutResult { revision: 0, prev_value: None, }) } /// Delete a key pub async fn delete(&self, _key: impl AsRef<[u8]>) -> Result { // TODO: Implement with Raft Ok(false) } /// Compare-and-swap pub async fn compare_and_swap( &self, _key: impl AsRef<[u8]>, expected_version: u64, _value: impl AsRef<[u8]>, ) -> Result { // TODO: Implement with storage backend Err(ClusterError::VersionMismatch { expected: expected_version, actual: 0, }) } /// Scan keys with prefix pub async fn scan_prefix( &self, _prefix: impl AsRef<[u8]>, _limit: u32, ) -> Result> { // TODO: Implement with storage backend Ok(Vec::new()) } /// Scan keys in a range pub async fn scan_range( &self, _start: impl AsRef<[u8]>, _end: impl AsRef<[u8]>, _limit: u32, ) -> Result> { // TODO: Implement with storage backend Ok(Vec::new()) } /// Get with specified consistency level pub async fn get_with_consistency( &self, _key: impl AsRef<[u8]>, _consistency: ReadConsistency, ) -> Result>> { // TODO: Implement with consistency options Ok(None) } } /// Options for KV operations #[derive(Debug, Clone, Default)] pub struct KvOptions { /// Lease ID for TTL-based expiration pub lease_id: Option, /// Return previous value pub prev_kv: bool, /// Time-to-live for the key pub ttl: Option, } /// Result of a put operation #[derive(Debug, Clone)] pub struct KvPutResult { /// New revision after the put pub revision: u64, /// Previous value, if requested and existed pub prev_value: Option>, } /// A key-value entry with metadata #[derive(Debug, Clone)] pub struct KvEntry { /// The key pub key: Vec, /// The value pub value: Vec, /// Revision when the key was created pub create_revision: u64, /// Revision when the key was last modified pub mod_revision: u64, /// Version number (increments on each update) pub version: u64, /// Lease ID if the key is attached to a lease pub lease_id: Option, } /// Result of a compare-and-swap operation #[derive(Debug, Clone)] pub enum CasResult { /// CAS succeeded, contains new revision Success(u64), /// CAS failed due to version mismatch Conflict { /// Expected version expected: u64, /// Actual version found actual: u64, }, /// Key did not exist NotFound, } /// Read consistency level #[derive(Debug, Clone, Copy, Default, PartialEq, Eq)] pub enum ReadConsistency { /// Read from local storage (may be stale) Local, /// Read from any node, but verify with leader's committed index Serializable, /// Read only from leader (linearizable, strongest guarantee) #[default] Linearizable, } /// Lightweight handle for KV operations #[derive(Clone)] pub struct KvHandle { kv: Arc, } impl KvHandle { pub(crate) fn new(kv: Arc) -> Self { Self { kv } } /// Get the underlying KV store pub fn inner(&self) -> &Arc { &self.kv } /// Get a value by key pub async fn get(&self, key: impl AsRef<[u8]>) -> Result>> { self.kv.get(key).await } /// Put a value pub async fn put(&self, key: impl AsRef<[u8]>, value: impl AsRef<[u8]>) -> Result { self.kv.put(key, value).await } /// Delete a key pub async fn delete(&self, key: impl AsRef<[u8]>) -> Result { self.kv.delete(key).await } /// Get a namespace pub fn namespace(&self, name: &str) -> Arc { self.kv.namespace(name) } }