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 viaBox<T>Shared-Arc<T>for shared immutable dataUpdatable- Lock-free atomic updates usingarc-swapLazy- Lazy initialization with atomic updates for static contexts
-
Lock-Free Updates: The
UpdatableandLazyvariants usearc-swapfor atomic, lock-free updates -
Lazy Initialization: The
Lazyvariant makes it possbile to create anUpdatablein 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, andLazyvariants
Add this to your Cargo.toml:
[dependencies]
anycow = "0.1"AnyCow shines in scenarios where you have:
- Configuration data that's read frequently but updated occasionally
- Global/static data that needs lazy initialization and atomic updates
- Cached values that need atomic updates without locks
- Shared state across multiple threads with infrequent modifications
- Hot paths where you want to minimize allocation overhead
- APIs that need to accept both borrowed and owned data flexibly
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 functioncontainer.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:
- Zero-cost borrowing: No allocation for
Borrowedvariant - Lazy initialization:
Lazyvariant allow to create anUpdatablein a static context - Lock-free updates:
UpdatableandLazyusearc-swapfor atomic operations - Minimal overhead: Smart enum design with efficient memory layout
- Branch prediction friendly: Common operations are optimized
Contributions 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.
- Built with
arc-swapfor lock-free atomic operations - Inspired by the standard library's
Cowbut supercharged for modern use cases
Made with β€οΈ for the Rust community. Happy coding! π¦