### Basic FeOxDB Store Operations in Rust Source: https://github.com/mehrantsi/feoxdb/blob/master/README.md Demonstrates creating an in-memory store, inserting, getting, checking existence, and deleting key-value pairs. Requires `feoxdb` crate and `FeoxStore`. ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { // Create an in-memory store let store = FeoxStore::new(None)?; // Insert a key-value pair store.insert(b"user:123", b"{\"name\":\"Mehran\"}")?; // Get a value let value = store.get(b"user:123")?; println!("Value: {}", String::from_utf8_lossy(&value)); // Check existence if store.contains_key(b"user:123") { println!("Key exists!"); } // Delete a key store.delete(b"user:123")?; Ok(()) } ``` -------------------------------- ### Install FeOxDB with Cargo Source: https://context7.com/mehrantsi/feoxdb/llms.txt Add FeOxDB to your project's Cargo.toml. Use the `system-alloc` feature to opt-out of the default jemalloc. ```toml [dependencies] feoxdb = "0.5.0" ``` ```toml [dependencies] feoxdb = { version = "0.5.0", default-features = false, features = ["system-alloc"] } ``` -------------------------------- ### Run FeOxDB Benchmarks Source: https://github.com/mehrantsi/feoxdb/blob/master/README.md Instructions for running performance benchmarks for FeOxDB. Use `cargo run --release --example deterministic_test` for deterministic tests and `cargo bench` for Criterion benchmarks. ```bash # Deterministic test cargo run --release --example deterministic_test 100000 100 # Criterion benchmarks cargo bench ``` -------------------------------- ### Get Real-time Performance Statistics Snapshot Source: https://context7.com/mehrantsi/feoxdb/llms.txt Use the `stats()` method to get a `StatsSnapshot` for monitoring or adaptive tuning. The snapshot provides a point-in-time view of performance counters. ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::new(None)?; for i in 0..10_000u32 { store.insert(format!("k:{}", i).as_bytes(), b"v")?; } for i in 0..10_000u32 { let _ = store.get(format!("k:{}", i).as_bytes())?; } let snap = store.stats(); println!("Records: {}", snap.record_count); println!("Memory: {:.2} MB", snap.memory_usage as f64 / 1_048_576.0); println!("Total ops: {}", snap.total_operations); println!("Avg GET latency: {} ns", snap.avg_get_latency_ns); println!("Avg INSERT latency: {} ns", snap.avg_insert_latency_ns); println!("Cache hit rate: {:.1}%", snap.cache_hit_rate); println!("Disk reads: {}", snap.disk_reads); println!("Writes buffered: {}", snap.writes_buffered); println!("Write failures: {}", snap.write_failures); // Or use the built-in formatter println!("{}", snap.format()); Ok(()) } ``` -------------------------------- ### Concurrent Access with Arc Source: https://context7.com/mehrantsi/feoxdb/llms.txt Wrap `FeoxStore` in `Arc` to share it across multiple threads safely. This example demonstrates spawning writer threads that concurrently insert data. ```rust use feoxdb::FeoxStore; use std::sync::Arc; use std::thread; fn main() -> feoxdb::Result<()> { let store = Arc::new(FeoxStore::new(None)?); let mut handles = vec![]; // 8 writer threads for i in 0..8usize { let s = Arc::clone(&store); handles.push(thread::spawn(move || { for j in 0..1000usize { let key = format!("thread{}:item{}", i, j); s.insert(key.as_bytes(), b"value").unwrap(); } })); } for h in handles { h.join().unwrap(); } assert_eq!(store.len(), 8 * 1000); println!("Total keys inserted: {}", store.len()); Ok(()) } ``` -------------------------------- ### Retrieve Value by Key in FeoxDB Source: https://context7.com/mehrantsi/feoxdb/llms.txt Use `get` to retrieve a value by its key. Returns `FeoxError::KeyNotFound` if the key does not exist or has expired. Hot values may be served from cache. ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::new(None)?; store.insert(b"product:42", b"{\"price\":9.99,\"stock\":100}")?; match store.get(b"product:42") { Ok(data) => println!("Found: {}", String::from_utf8_lossy(&data)), Err(feoxdb::FeoxError::KeyNotFound) => println!("Not found"), Err(e) => eprintln!("Error: {}", e), } // Output: Found: {"price":9.99,"stock":100} // KeyNotFound for missing key assert!(store.get(b"missing:key").is_err()); Ok(()) } ``` -------------------------------- ### Zero-Copy Retrieve as Bytes in FeoxDB Source: https://context7.com/mehrantsi/feoxdb/llms.txt Use `get_bytes` to retrieve a value as a `bytes::Bytes` reference without copying. This is significantly faster for large values compared to `get()`. ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::new(None)?; store.insert(b"image:001", &vec![0xABu8; 50_000])?; let data: bytes::Bytes = store.get_bytes(b"image:001")?; // Zero-copy: data shares underlying memory with the store println!("Image size: {} bytes", data.len()); // 50000 Ok(()) } ``` -------------------------------- ### `get_bytes` — Zero-copy retrieve as `Bytes` Source: https://context7.com/mehrantsi/feoxdb/llms.txt Returns the value as a reference-counted `bytes::Bytes` without copying. Significantly faster than `get()` for large values: ~50% faster at 1KB, ~95% faster at 100KB. ```APIDOC ## `get_bytes` — Zero-copy retrieve as `Bytes` ### Description Returns the value as a reference-counted `bytes::Bytes` without copying. Significantly faster than `get()` for large values: ~50% faster at 1KB, ~95% faster at 100KB. ### Method `FeoxStore::get_bytes` ### Parameters - **key** (`&[u8]`): The key to retrieve. ### Returns - `Ok(bytes::Bytes)`: The value associated with the key as a `Bytes` object. - `Err(FeoxError::KeyNotFound)`: If the key does not exist or has expired. ### Example ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::new(None)?; store.insert(b"image:001", &vec![0xABu8; 50_000])?; let data: bytes::Bytes = store.get_bytes(b"image:001")?; println!("Image size: {} bytes", data.len()); // 50000 Ok(()) } ``` ``` -------------------------------- ### `get` — Retrieve a value by key Source: https://context7.com/mehrantsi/feoxdb/llms.txt Looks up a key in the hash table and returns its value as `Vec`. In persistent mode with caching enabled, hot values are served from the CLOCK cache. Returns `FeoxError::KeyNotFound` if the key does not exist or has expired. ```APIDOC ## `get` — Retrieve a value by key ### Description Looks up a key in the hash table and returns its value as `Vec`. In persistent mode with caching enabled, hot values are served from the CLOCK cache. Returns `FeoxError::KeyNotFound` if the key does not exist or has expired. ### Method `FeoxStore::get` ### Parameters - **key** (`&[u8]`): The key to retrieve. ### Returns - `Ok(Vec)`: The value associated with the key. - `Err(FeoxError::KeyNotFound)`: If the key does not exist or has expired. ### Example ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::new(None)?; store.insert(b"product:42", b"{\"price\":9.99,\"stock\":100}")?; match store.get(b"product:42") { Ok(data) => println!("Found: {}", String::from_utf8_lossy(&data)), Err(feoxdb::FeoxError::KeyNotFound) => println!("Not found"), Err(e) => eprintln!("Error: {}", e), } assert!(store.get(b"missing:key").is_err()); Ok(()) } ``` ``` -------------------------------- ### range_query — Inclusive range scan Source: https://context7.com/mehrantsi/feoxdb/llms.txt Returns all key-value pairs within a specified lexicographical range, ordered by key. The scan is inclusive of the start and end keys and is limited by a maximum number of results. This operation leverages a lock-free SkipList for efficient seeking and scanning. ```APIDOC ## `range_query` — Inclusive range scan Returns all key-value pairs in lexicographic order where `start_key <= key <= end_key`, up to `limit` results. Uses the lock-free Crossbeam SkipList for O(log n) seek and O(k) scan. ### Method `range_query(start_key: &[u8], end_key: &[u8], limit: usize) -> Result>` ### Parameters - **start_key** (bytes) - The inclusive lower bound of the key range. - **end_key** (bytes) - The inclusive upper bound of the key range. - **limit** (usize) - The maximum number of key-value pairs to return. ### Response - **Success Response (Ok)**: Returns a `Vec` of `(&[u8], &[u8])` tuples representing the key-value pairs within the specified range, up to the limit. - **Error Response (Err)**: An error if the operation fails. ``` -------------------------------- ### `get_size` — Get value size without loading Source: https://context7.com/mehrantsi/feoxdb/llms.txt Returns the byte size of a stored value without reading the value data itself. Useful for checking large value sizes before deciding whether to load from disk. ```APIDOC ## `get_size` — Get value size without loading ### Description Returns the byte size of a stored value without reading the value data itself. Useful for checking large value sizes before deciding whether to load from disk. ### Method `FeoxStore::get_size` ### Parameters - **key** (`&[u8]`): The key whose value size is to be retrieved. ### Returns - `Ok(usize)`: The size of the value in bytes. - `Err(FeoxError::KeyNotFound)`: If the key does not exist or has expired. ### Example ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::new(None)?; store.insert(b"file:report.pdf", &vec![0u8; 2_500_000])?; let size = store.get_size(b"file:report.pdf")?; assert_eq!(size, 2_500_000); Ok(()) } ``` ``` -------------------------------- ### Get Value Size Without Loading in FeoxDB Source: https://context7.com/mehrantsi/feoxdb/llms.txt Use `get_size` to retrieve the byte size of a stored value without loading the actual data. This is useful for checking large value sizes before deciding to load them. ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::new(None)?; store.insert(b"file:report.pdf", &vec![0u8; 2_500_000])?; let size = store.get_size(b"file:report.pdf")?; assert_eq!(size, 2_500_000); println!("File size: {:.2} MB", size as f64 / 1_048_576.0); Ok(()) } ``` -------------------------------- ### Create and Use Persistent Store Source: https://github.com/mehrantsi/feoxdb/blob/master/README.md Demonstrates creating a persistent FeoxStore, inserting data, flushing to disk, and verifying data persistence after a restart. ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { // Create a persistent store let store = FeoxStore::new(Some("/path/to/data.feox".to_string()))?; // Operations are automatically persisted store.insert(b"config:app", b"production")?; // Flush to disk store.flush(); // Data survives restarts drop(store); let store = FeoxStore::new(Some("/path/to/data.feox".to_string()))?; let value = store.get(b"config:app")?; assert_eq!(value, b"production"); Ok(()) } ``` -------------------------------- ### Configure and Build FeoxStore with Builder Source: https://context7.com/mehrantsi/feoxdb/llms.txt Use the `FeoxStore::builder()` for advanced configuration options like file path, size limits, caching, and TTL settings. Call `.build()` to create the store instance. ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::builder() .device_path("/data/app.feox") // Enable persistence (omit for memory-only) .file_size(10 * 1024 * 1024 * 1024) // Pre-allocate 10GB file .max_memory(2_000_000_000) // 2GB memory limit (default: 4GB) .hash_bits(20) // 1M hash buckets (default: 8M via bits=23) .enable_caching(true) // CLOCK cache for persistent mode .enable_ttl(true) // Enable TTL + background sweeper .ttl_sweeper_config( 200, // sample_size: keys checked per batch 0.25, // threshold: re-run if >25% expired 10, // max_time_ms per run 100, // interval_ms between runs ) .build()?; store.insert(b"key", b"value")?; println!("Records: {}", store.len()); Ok(()) } ``` -------------------------------- ### FeoxStore::new Source: https://context7.com/mehrantsi/feoxdb/llms.txt Creates a FeoxStore instance. It can be configured as a pure in-memory store by passing `None`, or as a persistent store by providing a file path. ```APIDOC ## FeoxStore::new ### Description Creates a `FeoxStore` with default configuration. Pass `None` for a pure in-memory store, or `Some(path)` to enable persistence to a `.feox` file. In persistent mode, a write buffer and background flush workers are automatically started. ### Method `FeoxStore::new(path: Option) -> Result` ### Parameters #### Path Parameters - **path** (Option) - Required - The file path for persistent storage. `None` for in-memory. ### Request Example ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { // In-memory store let mem_store = FeoxStore::new(None)?; mem_store.insert(b"hello", b"world")?; let v = mem_store.get(b"hello")?; assert_eq!(v, b"world"); // Persistent store let db = FeoxStore::new(Some("/tmp/myapp.feox".to_string()))?; db.insert(b"config:env", b"production")?; db.flush(); drop(db); let db2 = FeoxStore::new(Some("/tmp/myapp.feox".to_string()))?; let val = db2.get(b"config:env")?; assert_eq!(val, b"production"); Ok(()) } ``` ### Response #### Success Response (FeoxStore) Returns a `FeoxStore` instance. #### Error Response (feoxdb::Error) An error occurred during store creation or initialization. ``` -------------------------------- ### Configure FeoxStore with Builder Source: https://github.com/mehrantsi/feoxdb/blob/master/README.md Shows how to configure FeoxStore using its builder pattern, setting initial file size, memory limits, caching, hash bits, and TTL support. ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::builder() .device_path("/data/myapp.feox") .file_size(10 * 1024 * 1024 * 1024) // 10GB initial file size .max_memory(2_000_000_000) // 2GB limit .enable_caching(true) // Enable CLOCK cache .hash_bits(20) // 1M hash buckets .enable_ttl(true) // Enable TTL support .build()?; Ok(()) } ``` -------------------------------- ### Create FeoxStore: Memory-only or Persistent Source: https://context7.com/mehrantsi/feoxdb/llms.txt Instantiate a FeoxStore. Pass `None` for a fast, in-memory-only store, or `Some(path)` to enable persistence with background write-behind logging. ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { // In-memory store — fastest, no durability let mem_store = FeoxStore::new(None)?; mem_store.insert(b"hello", b"world")?; let v = mem_store.get(b"hello")?; assert_eq!(v, b"world"); // Persistent store — data survives restarts let db = FeoxStore::new(Some("/tmp/myapp.feox".to_string()))?; db.insert(b"config:env", b"production")?; db.flush(); // Synchronously flush all buffered writes to disk (fsync) // Reload and verify data survived drop(db); let db2 = FeoxStore::new(Some("/tmp/myapp.feox".to_string()))?; let val = db2.get(b"config:env")?; assert_eq!(val, b"production"); Ok(()) } ``` -------------------------------- ### Perform Range Queries Source: https://github.com/mehrantsi/feoxdb/blob/master/README.md Demonstrates how to perform range queries on FeoxStore. Keys are inserted in sorted order, and a query retrieves keys within a specified range. ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::new(None)?; // Insert sorted keys store.insert(b"user:001", b"Mehran")?; store.insert(b"user:002", b"Bob")?; store.insert(b"user:003", b"Charlie")?; store.insert(b"user:004", b"David")?; // Range query: get users 001-003 (inclusive on both ends) let results = store.range_query(b"user:001", b"user:003", 10)?; for (key, value) in results { println!("{}: {}", String::from_utf8_lossy(&key), String::from_utf8_lossy(&value)); } // Outputs: user:001, user:002, user:003 Ok(()) } ``` -------------------------------- ### Build FeOxDB with System Allocator Source: https://github.com/mehrantsi/feoxdb/blob/master/README.md Use the system allocator instead of jemalloc for specific use cases like embedded systems, debugging, or targeting platforms where jemalloc doesn't compile. This can also reduce binary size. ```bash cargo build --no-default-features --features system-alloc ``` ```bash cargo install feoxdb --no-default-features --features system-alloc ``` -------------------------------- ### Generate Local API Documentation Source: https://github.com/mehrantsi/feoxdb/blob/master/README.md Generates and opens the full API documentation for the FeOxDB project locally. This is useful for detailed API exploration. ```bash cargo doc --open ``` -------------------------------- ### Manage Time-To-Live (TTL) for Keys Source: https://github.com/mehrantsi/feoxdb/blob/master/README.md Demonstrates enabling TTL support, setting keys with expiration times, checking remaining TTL, extending TTL, and removing TTL to make keys permanent. ```rust use feoxdb::FeoxStore; // Enable TTL feature via builder let store = FeoxStore::builder() .enable_ttl(true) .build()?; // Set key to expire after 60 seconds store.insert_with_ttl(b"session:123", b"session_data", 60)?; // Check remaining TTL if let Some(ttl) = store.get_ttl(b"session:123")? { println!("Session expires in {} seconds", ttl); } // Extend TTL to 120 seconds store.update_ttl(b"session:123", 120)?; // Remove TTL (make permanent) store.persist(b"session:123")?; ``` -------------------------------- ### Concurrent Access with Threads Source: https://github.com/mehrantsi/feoxdb/blob/master/README.md Illustrates safe concurrent access to FeoxStore from multiple threads using `Arc`. Each thread inserts multiple keys, and the total number of keys is printed. ```rust use feoxdb::FeoxStore; use std::sync::Arc; use std::thread; fn main() -> feoxdb::Result<()> { let store = Arc::new(FeoxStore::new(None)?); let mut handles = vec![]; // Spawn 10 threads, each inserting data for i in 0..10 { let store_clone = Arc::clone(&store); handles.push(thread::spawn(move || { for j in 0..1000 { let key = format!("thread_{}:key_{}", i, j); store_clone.insert(key.as_bytes(), b"value", None).unwrap(); } })); } for handle in handles { handle.join().unwrap(); } println!("Total keys: {}", store.len()); // 10,000 Ok(()) } ``` -------------------------------- ### FeoxStore::builder Source: https://context7.com/mehrantsi/feoxdb/llms.txt Provides a builder pattern for advanced configuration of the FeoxStore, allowing fine-grained control over various parameters. ```APIDOC ## FeoxStore::builder ### Description Returns a `StoreBuilder` for advanced configuration. All builder methods are chainable. Calling `.build()` returns a `Result`. ### Method `FeoxStore::builder() -> StoreBuilder` ### Builder Methods | Method | Description | Default | |--------|-------------|---------| | `.device_path(path)` | Path for persistent file | `None` (memory-only) | | `.file_size(bytes)` | Initial file pre-allocation | 1 GB | | `.max_memory(bytes)` | Max in-memory bytes | 4 GB | | `.no_memory_limit()` | Remove memory cap | — | | `.hash_bits(bits)` | Hash table size = 2^bits | 23 (8M buckets) | | `.enable_caching(bool)` | CLOCK eviction cache | `true` for persistent | | `.enable_ttl(bool)` | TTL support + sweeper | `false` | | `.ttl_sweeper_config(...)` | Tune TTL background cleaner | Defaults | ### Request Example ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::builder() .device_path("/data/app.feox") // Enable persistence .file_size(10 * 1024 * 1024 * 1024) // 10GB file size .max_memory(2_000_000_000) // 2GB memory limit .hash_bits(20) // 1M hash buckets .enable_caching(true) // Enable CLOCK cache .enable_ttl(true) // Enable TTL support .ttl_sweeper_config( 200, // sample_size 0.25, // threshold 10, // max_time_ms 100, // interval_ms ) .build()?; store.insert(b"key", b"value")?; println!("Records: {}", store.len()); Ok(()) } ``` ### Response #### Success Response (FeoxStore) Returns a configured `FeoxStore` instance upon successful build. #### Error Response (feoxdb::Error) An error occurred during the store building process. ``` -------------------------------- ### Inspect Store State with Utility Methods Source: https://context7.com/mehrantsi/feoxdb/llms.txt Provides utility methods to query store state without reading individual values. Includes checking if the store is empty, its size, and if a key exists. ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::new(None)?; assert!(store.is_empty()); assert_eq!(store.len(), 0); for i in 0..1000u32 { store.insert(format!("key:{}", i).as_bytes(), b"data")?; } assert_eq!(store.len(), 1000); assert!(!store.is_empty()); assert!(store.contains_key(b"key:500")); assert!(!store.contains_key(b"key:9999")); println!("Memory: {:.2} MB", store.memory_usage() as f64 / 1_048_576.0); Ok(()) } ``` -------------------------------- ### Add FeOxDB Dependency to Cargo.toml Source: https://github.com/mehrantsi/feoxdb/blob/master/README.md Add this to your Cargo.toml file to include FeOxDB in your project. ```toml [dependencies] feoxdb = "0.1.0" ``` -------------------------------- ### Insert or Update Key-Value Pair in FeoxDB Source: https://context7.com/mehrantsi/feoxdb/llms.txt Use `insert` to add a new key-value pair or overwrite an existing one. It returns `true` for new keys and `false` for updates. Keys can be up to 100KB and values up to 4MB. ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::new(None)?; // New insert → returns true let is_new = store.insert(b"user:1", b"{\"name\":\"Alice\",\"role\":\"admin\"}")?; assert!(is_new); // Update existing → returns false let is_new = store.insert(b"user:1", b"{\"name\":\"Alice\",\"role\":\"superadmin\"}")?; assert!(!is_new); // Keys can be up to 100KB; values up to 4MB store.insert(b"blob:img1", &vec![0xFFu8; 1_000_000])?; Ok(()) } ``` -------------------------------- ### Perform an inclusive range scan in FeoxDB Source: https://context7.com/mehrantsi/feoxdb/llms.txt Returns all key-value pairs in lexicographic order where `start_key <= key <= end_key`, up to `limit` results. Uses the lock-free Crossbeam SkipList for O(log n) seek and O(k) scan. ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::new(None)?; // Insert sorted keys for i in 1u32..=10 { let key = format!("order:{:04}", i); let val = format!("{{\"id\":{},\"status\":\"pending\"}}", i); store.insert(key.as_bytes(), val.as_bytes())?; } // Inclusive range: order:0003 through order:0007, max 10 results let results = store.range_query(b"order:0003", b"order:0007", 10)?; assert_eq!(results.len(), 5); for (k, v) in &results { println!("{} => {}", String::from_utf8_lossy(k), String::from_utf8_lossy(v)); } // order:0003 => {"id":3,"status":"pending"} // order:0004 => {"id":4,"status":"pending"} // ... Ok(()) } ``` -------------------------------- ### Zero-Copy Insert with Bytes in FeoxDB Source: https://context7.com/mehrantsi/feoxdb/llms.txt Utilize `insert_bytes` for zero-copy insertion when data is already in a `bytes::Bytes` buffer. This can be significantly faster for large values. ```rust use feoxdb::FeoxStore; use bytes::Bytes; fn main() -> feoxdb::Result<()> { let store = FeoxStore::new(None)?; // Data received from network, already a Bytes let payload = Bytes::from(r#"{"event":"click","user":42}"#.to_string()); store.insert_bytes(b"event:latest", payload)?; let result = store.get_bytes(b"event:latest")?; println!("{}", std::str::from_utf8(&result).unwrap()); // Output: {"event":"click","user":42} Ok(()) } ``` -------------------------------- ### `insert` — Insert or update a key-value pair Source: https://context7.com/mehrantsi/feoxdb/llms.txt Inserts a new key or overwrites an existing one. Returns `Ok(true)` if a new key was created, `Ok(false)` if an existing key was updated. Uses the current time as the conflict-resolution timestamp. If the key had a TTL, it is removed on plain `insert`. ```APIDOC ## `insert` — Insert or update a key-value pair ### Description Inserts a new key or overwrites an existing one. Returns `Ok(true)` if a new key was created, `Ok(false)` if an existing key was updated. Uses the current time as the conflict-resolution timestamp. If the key had a TTL, it is removed on plain `insert`. ### Method `FeoxStore::insert` ### Parameters - **key** (`&[u8]`): The key to insert or update. - **value** (`&[u8]`): The value associated with the key. ### Returns - `Ok(true)`: If a new key was created. - `Ok(false)`: If an existing key was updated. ### Example ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::new(None)?; let is_new = store.insert(b"user:1", b"{\"name\":\"Alice\",\"role\":\"admin\"}")?; assert!(is_new); let is_new = store.insert(b"user:1", b"{\"name\":\"Alice\",\"role\":\"superadmin\"}")?; assert!(!is_new); Ok(()) } ``` ``` -------------------------------- ### Manage Key Expiry with TTL Operations Source: https://context7.com/mehrantsi/feoxdb/llms.txt Enables Time-To-Live (TTL) for keys, causing them to expire. Expired keys return `FeoxError::KeyNotFound` on access. TTL must be explicitly enabled in `FeoxStore`. ```rust use feoxdb::FeoxStore; use std::time::Duration; use std::thread; fn main() -> feoxdb::Result<()> { let store = FeoxStore::builder() .enable_ttl(true) .build()?; // Insert with 60-second TTL store.insert_with_ttl(b"session:xyz", b"user_data", 60)?; // Check remaining TTL (returns Some(seconds) or None if no TTL) if let Ok(Some(ttl)) = store.get_ttl(b"session:xyz") { println!("Expires in ~{} seconds", ttl); // ~60 } // Extend TTL to 120 seconds store.update_ttl(b"session:xyz", 120)?; // Remove TTL entirely, making the key permanent store.persist(b"session:xyz")?; assert_eq!(store.get_ttl(b"session:xyz")?, None); // Zero-copy TTL insert using Bytes use bytes::Bytes; let data = Bytes::from_static(b"token_payload"); store.insert_bytes_with_ttl(b"token:abc", data, 300)?; // 5 min TTL // Insert with TTL + explicit timestamp for conflict resolution let ts = store.get_timestamp_pub(); store.insert_with_ttl_and_timestamp(b"rate:user:42", b"100", 60, Some(ts))?; Ok(()) } ``` -------------------------------- ### Force Synchronous Disk Write with `flush` Source: https://context7.com/mehrantsi/feoxdb/llms.txt Forces all buffered writes to be flushed to disk and completes fsync. This operation blocks until durability is guaranteed. It is a no-op in memory-only mode. ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::new(Some("/tmp/critical.feox".to_string()))?; store.insert(b"txn:1234:result", b"committed")?; store.insert(b"txn:1234:amount", b"500")?; // Block until all pending writes are safely on disk store.flush(); println!("Transaction durably committed"); Ok(()) } ``` -------------------------------- ### Perform Compare-and-Swap (CAS) Operations in Rust Source: https://github.com/mehrantsi/feoxdb/blob/master/README.md Demonstrates atomic Compare-and-Swap operations for optimistic concurrency control. Use this for thread-safe updates where you need to ensure a value hasn't changed before modifying it. ```rust use feoxdb::FeoxStore; use std::sync::{Arc, Barrier}; use std::thread; fn main() -> feoxdb::Result<()> { let store = Arc::new(FeoxStore::new(None)?); // Multiple servers processing orders concurrently store.insert(b"product:iPhone16:stock", b"50")?; // Initial stock let barrier = Arc::new(Barrier::new(5)); let mut handles = vec![]; for order_id in 0..5 { let store_clone = Arc::clone(&store); let barrier_clone = Arc::clone(&barrier); handles.push(thread::spawn(move || -> feoxdb::Result { barrier_clone.wait(); // Start all orders simultaneously let quantity_requested = 10; // Try to reserve inventory atomically let current = store_clone.get(b"product:iPhone16:stock")?; let stock: u32 = String::from_utf8_lossy(¤t) .parse() .unwrap_or(0); if stock >= quantity_requested { let new_stock = (stock - quantity_requested).to_string(); // Attempt atomic update if store_clone.compare_and_swap( b"product:iPhone16:stock", ¤t, new_stock.as_bytes() )? { return Ok(true); // Successfully reserved } } Ok(false) // Failed - insufficient stock or lost race })); } let successful_orders: Vec = handles .into_iter() .map(|h| h.join().unwrap().unwrap()) .collect(); // With single-attempt CAS, some orders may fail due to races // Typically 3-4 orders succeed out of 5 let successful_count = successful_orders.iter().filter(|&&x| x).count(); println!("Successful orders: {}/5", successful_count); let final_stock = store.get(b"product:iPhone16:stock")?; println!("Final stock: {}", String::from_utf8_lossy(&final_stock)); Ok(()) } ``` -------------------------------- ### `insert_bytes` — Zero-copy insert using `Bytes` Source: https://context7.com/mehrantsi/feoxdb/llms.txt Inserts using a `bytes::Bytes` value, avoiding an extra allocation when the data is already in a `Bytes` buffer (e.g., from network reads). Up to 95% faster than `insert` for 100KB+ values. ```APIDOC ## `insert_bytes` — Zero-copy insert using `Bytes` ### Description Inserts using a `bytes::Bytes` value, avoiding an extra allocation when the data is already in a `Bytes` buffer (e.g., from network reads). Up to 95% faster than `insert` for 100KB+ values. ### Method `FeoxStore::insert_bytes` ### Parameters - **key** (`&[u8]`): The key to insert. - **value** (`bytes::Bytes`): The value to insert, already in a `Bytes` buffer. ### Example ```rust use feoxdb::FeoxStore; use bytes::Bytes; fn main() -> feoxdb::Result<()> { let store = FeoxStore::new(None)?; let payload = Bytes::from(r#"{"event":"click","user":42}"#.to_string()); store.insert_bytes(b"event:latest", payload)?; Ok(()) } ``` ``` -------------------------------- ### Perform Atomic Counter Operations in Rust Source: https://github.com/mehrantsi/feoxdb/blob/master/README.md Shows how to use FeOxDB's atomic increment/decrement operations for 8-byte i64 counters. This is thread-safe and efficient for tracking statistics like visits or downloads. ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::new(None)?; // Initialize counters (must be 8-byte i64 values) let zero: i64 = 0; store.insert(b"stats:visits", &zero.to_le_bytes())?; store.insert(b"stats:downloads", &zero.to_le_bytes())?; // Increment atomically (thread-safe) let visits = store.atomic_increment(b"stats:visits", 1)?; println!("Visits: {}", visits); // 1 // Increment by 10 let downloads = store.atomic_increment(b"stats:downloads", 10)?; println!("Downloads: {}", downloads); // 10 // Decrement let visits = store.atomic_increment(b"stats:visits", -1)?; println!("Visits after decrement: {}", visits); // 0 Ok(()) } ``` -------------------------------- ### Apply JSON Patches to Update JSON Documents in Rust Source: https://github.com/mehrantsi/feoxdb/blob/master/README.md Demonstrates how to apply RFC 6902 JSON Patches for partial updates to JSON documents stored in FeOxDB. Use this to modify specific fields within a JSON document without replacing the entire document. ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::new(None)?; // Store a JSON document let user = r#"{ "name": "Mehran", "age": 30, "skills": ["Rust", "Go"], "address": { "city": "San Francisco", "zip": "94105" } }"#; store.insert(b"user:123", user.as_bytes())?; // Apply patches to modify specific fields let patches = r#"[ {"op": "replace", "path": "/age", "value": 31}, {"op": "add", "path": "/skills/-", "value": "Python"}, {"op": "add", "path": "/email", "value": "mehran@example.com"}, {"op": "replace", "path": "/address/city", "value": "Seattle"} ]"#; store.json_patch(b"user:123", patches.as_bytes())?; // Document is now updated with patches applied let updated = store.get(b"user:123")?; println!("Updated: {}", String::from_utf8_lossy(&updated)); Ok(()) } ``` -------------------------------- ### atomic_increment_with_ttl — Lock-free integer counter with TTL Source: https://context7.com/mehrantsi/feoxdb/llms.txt Atomically increments a 64-bit signed integer counter and sets a Time-To-Live (TTL) for the key. If the key does not exist, it is created with the delta as its initial value. The key will expire after the specified TTL duration. Returns the new value after the increment. ```APIDOC ## `atomic_increment_with_ttl` — Lock-free integer counter with TTL Atomically increments or decrements a stored `i64` counter (stored as 8-byte little-endian) and sets a Time-To-Live (TTL) for the key. If the key does not exist, it is created with the delta as its initial value. Passing a negative delta decrements. Returns the new value. ### Method `atomic_increment_with_ttl(key: &[u8], delta: i64, ttl_seconds: u32) -> Result` ### Parameters - **key** (bytes) - The key of the counter to increment or decrement. - **delta** (i64) - The amount to increment (positive) or decrement (negative) the counter by. - **ttl_seconds** (u32) - The time-to-live for the key in seconds. ### Response - **Success Response (Ok)**: Returns the new value of the counter as an `i64`. - **Error Response (Err)**: An error if the operation fails. ``` -------------------------------- ### delete — Delete a key-value pair Source: https://context7.com/mehrantsi/feoxdb/llms.txt Removes a key from the store. Returns an error if the key does not exist. In persistent mode, this queues a tombstone write to disk and immediately clears the key from the CLOCK cache. ```APIDOC ## `delete` — Delete a key-value pair Removes a key from the store. Returns `FeoxError::KeyNotFound` if the key does not exist. Queues a tombstone write to disk in persistent mode. Clears the key from the CLOCK cache immediately. ### Method `delete(key: &[u8]) -> Result<()>` ### Parameters - **key** (bytes) - The key to delete from the store. ### Response - **Success Response (Ok)**: Returns `Ok(())` if the key was successfully deleted. - **Error Response (Err)**: Returns `FeoxError::KeyNotFound` if the key does not exist. ``` -------------------------------- ### compare_and_swap — Atomic CAS operation Source: https://context7.com/mehrantsi/feoxdb/llms.txt Performs an atomic Compare-And-Swap (CAS) operation on a key's value. It checks if the current value matches an expected value. If they match, it replaces the current value with a new value and returns `true`. If the value has changed or the key doesn't exist, it returns `false`. This operation is designed to prevent ABA problems by using pointer identity. ```APIDOC ## `compare_and_swap` — Atomic CAS operation Atomically compares the stored value against `expected`. If they match, replaces the value with `new_value` and returns `Ok(true)`. Returns `Ok(false)` if the value has changed or the key does not exist. Uses pointer identity to prevent ABA problems between the read and write phases. ### Method `compare_and_swap(key: &[u8], expected: &[u8], new_value: &[u8]) -> Result` ### Parameters - **key** (bytes) - The key to perform the CAS operation on. - **expected** (bytes) - The expected current value of the key. - **new_value** (bytes) - The new value to set if the comparison succeeds. ### Response - **Success Response (Ok)**: Returns `Ok(true)` if the value was successfully updated. Returns `Ok(false)` if the value did not match `expected` or the key does not exist. - **Error Response (Err)**: An error if the operation fails. ``` -------------------------------- ### Delete a key-value pair in FeoxDB Source: https://context7.com/mehrantsi/feoxdb/llms.txt Removes a key from the store. Returns `FeoxError::KeyNotFound` if the key does not exist. Queues a tombstone write to disk in persistent mode and clears the key from the CLOCK cache immediately. ```rust use feoxdb::FeoxStore; fn main() -> feoxdb::Result<()> { let store = FeoxStore::new(None)?; store.insert(b"session:abc", b"user_data")?; assert!(store.contains_key(b"session:abc")); store.delete(b"session:abc")?; assert!(!store.contains_key(b"session:abc")); // Deleting non-existent key returns error let result = store.delete(b"session:abc"); assert!(matches!(result, Err(feoxdb::FeoxError::KeyNotFound))); Ok(()) } ``` -------------------------------- ### Atomic Compare-and-Swap (CAS) operation in FeoxDB Source: https://context7.com/mehrantsi/feoxdb/llms.txt Atomically compares the stored value against `expected`. If they match, replaces the value with `new_value` and returns `Ok(true)`. Returns `Ok(false)` if the value has changed or the key does not exist. Uses pointer identity to prevent ABA problems. ```rust use feoxdb::FeoxStore; use std::sync::{Arc, Barrier}; use std::thread; fn main() -> feoxdb::Result<()> { let store = Arc::new(FeoxStore::new(None)?); // State machine: PENDING → PROCESSING → COMPLETED store.insert(b"job:99:status", b"PENDING")?; let barrier = Arc::new(Barrier::new(3)); let mut handles = vec![]; for worker_id in 0..3usize { let s = Arc::clone(&store); let b = Arc::clone(&barrier); handles.push(thread::spawn(move || -> feoxdb::Result<()> { b.wait(); // All workers start simultaneously if s.compare_and_swap(b"job:99:status", b"PENDING", b"PROCESSING")? { println!("Worker {} claimed job", worker_id); // Only one worker will succeed due to CAS atomicity s.compare_and_swap(b"job:99:status", b"PROCESSING", b"COMPLETED")?; } Ok(()) })); } for h in handles { h.join().unwrap()?; } let status = store.get(b"job:99:status")?; assert_eq!(status, b"COMPLETED"); Ok(()) } ```