| Crates.io | anycow |
| lib.rs | anycow |
| version | 0.1.0 |
| created_at | 2025-07-28 03:43:09.365581+00 |
| updated_at | 2025-07-28 03:43:09.365581+00 |
| description | A supercharged container for read-heavy, occasionally-updated data structures with multiple storage strategies |
| homepage | https://github.com/antouhou/anycow |
| repository | https://github.com/antouhou/anycow |
| max_upload_size | |
| id | 1770632 |
| size | 52,280 |
A supercharged container for read-heavy, occasionally-updated data structures
AnyCow is a versatile, high-performance container that extends the concept of Cow (Clone-on-Write) with multiple storage strategies optimized for different use cases. Perfect for scenarios where you need to read values frequently but update them only occasionally.
Multiple Storage Strategies: Choose the right storage for your use case
Borrowed - Zero-cost references for temporary dataOwned - Heap-allocated owned data via Box<T>Shared - Arc<T> for shared immutable dataUpdatable - Lock-free atomic updates using arc-swapLazy - Lazy initialization with atomic updates for static contextsLock-Free Updates: The Updatable and Lazy variants use arc-swap for atomic, lock-free updates
Lazy Initialization: The Lazy variant makes it possbile to create an Updatable in a static context
Flexible API: Easy conversion between different storage types
Zero-Cost Abstractions: Minimal overhead for common operations
Thread-Safe: Share data safely across threads with Shared, Updatable, and Lazy variants
Add this to your Cargo.toml:
[dependencies]
anycow = "0.1"
AnyCow shines in scenarios where you have:
use anycow::AnyCow;
// Create from different sources
let borrowed = AnyCow::borrowed(&"hello");
let owned = AnyCow::owned(String::from("world"));
let shared = AnyCow::shared(std::sync::Arc::new(42));
let updatable = AnyCow::updatable(vec![1, 2, 3]);
let lazy = AnyCow::lazy(|| vec![7, 8, 9]);
// Read values efficiently
println!("{}", *borrowed.borrow()); // "hello"
println!("{}", *owned.borrow()); // "world"
// Atomic updates (lock-free!)
updatable.try_replace(vec![4, 5, 6]).unwrap();
lazy.try_replace(vec![10, 11, 12]).unwrap();
use anycow::AnyCow;
use std::sync::Arc;
#[derive(Clone, Debug)]
struct Config {
max_connections: usize,
timeout_ms: u64,
}
// Create updatable config
let config = AnyCow::updatable(Config {
max_connections: 100,
timeout_ms: 5000,
});
// Read frequently (very fast)
let current_config = config.borrow();
println!("Max connections: {}", current_config.max_connections);
// Update occasionally (atomic, lock-free)
config.try_replace(Config {
max_connections: 200,
timeout_ms: 3000,
}).unwrap();
use anycow::AnyCow;
fn process_data<'a>(data: AnyCow<'a, str>) {
// Works with borrowed, owned, or shared data
println!("Processing: {}", *data.borrow());
}
// All of these work!
process_data(AnyCow::borrowed("borrowed string"));
process_data(AnyCow::owned(String::from("owned string")));
process_data(AnyCow::shared(std::sync::Arc::new(String::from("shared string"))));
use anycow::AnyCow;
use std::thread;
use std::sync::Arc;
let cache = Arc::new(AnyCow::updatable(vec![1, 2, 3]));
// Spawn reader threads
let cache_clone = cache.clone();
let reader = thread::spawn(move || {
for _ in 0..1000 {
let data = cache_clone.borrow();
println!("Sum: {}", data.iter().sum::<i32>());
}
});
// Update cache atomically
cache.try_replace(vec![4, 5, 6, 7, 8]).unwrap();
reader.join().unwrap();
use anycow::AnyCow;
use std::collections::HashMap;
// Perfect for static/global data that's expensive to initialize
static CONFIG: AnyCow<HashMap<String, String>> = AnyCow::lazy(|| {
println!("Loading configuration..."); // Only runs once!
let mut config = HashMap::new();
config.insert("app_name".to_string(), "MyApp".to_string());
config.insert("version".to_string(), "1.0.0".to_string());
config
});
fn main() {
// First access initializes the config
let app_name = CONFIG.borrow().get("app_name").cloned().unwrap();
println!("App: {}", app_name);
// Subsequent accesses are fast (no re-initialization)
let version = CONFIG.borrow().get("version").cloned().unwrap();
println!("Version: {}", version);
// Update the global config atomically
let mut new_config = HashMap::new();
new_config.insert("app_name".to_string(), "MyApp Pro".to_string());
new_config.insert("version".to_string(), "2.0.0".to_string());
CONFIG.try_replace(new_config).unwrap();
}
## 🧠 Storage Strategy Guide
| Variant | Best For | Thread Safe | Mutable | Memory |
|---------|----------|-------------|---------|--------|
| `Borrowed` | Temporary refs, hot paths | ❌ | ❌ | Zero-copy |
| `Owned` | Exclusive ownership | ❌ | ✅ | Heap |
| `Shared` | Read-only sharing | ✅ | ❌ | Shared |
| `Updatable` | Concurrent reads + atomic updates | ✅ | Via `try_replace()` | Shared + Atomic |
| `Lazy` | Static/global data + atomic updates | ✅ | Via `try_replace()` | Lazy + Shared + Atomic |
## 🔧 API Reference
### Construction
```rust
AnyCow::borrowed(&value) // From reference
AnyCow::owned(value) // From owned value (boxed)
AnyCow::shared(arc) // From Arc<T>
AnyCow::updatable(value) // Create updatable variant
AnyCow::lazy(init_fn) // Create lazy variant with init function
container.borrow() // Get reference to value
container.to_mut() // Get mutable reference (COW)
container.into_owned() // Convert to owned value
container.to_arc() // Convert to Arc<T>
container.try_replace(new_value) // Atomic update (Updatable & Lazy only)
AnyCow is designed for performance:
Borrowed variantLazy variant allow to create an Updatable in a static contextUpdatable and Lazy use arc-swap for atomic operationsContributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
This project is licensed under the MIT License - see the LICENSE file for details.
arc-swap for lock-free atomic operationsCow but supercharged for modern use casesMade with ❤️ for the Rust community. Happy coding! 🦀