From 00b54a7f58d87cb7f6279dac83827e059647fd7c Mon Sep 17 00:00:00 2001 From: Philippe Assis Date: Fri, 22 Aug 2025 11:13:42 -0300 Subject: [PATCH 1/3] Update README.md to reflect changes in performance optimizations and features - Revised feature descriptions for clarity and accuracy, including updates to string filtering and memory optimizations. - Removed outdated sections on SIMD acceleration and string pooling, replacing them with more relevant information on optimized algorithms and memory layout. - Consolidated performance impact data to reflect the latest benchmarks and improvements. - Enhanced examples and usage sections to demonstrate new features and optimizations. - Updated installation instructions and API references for consistency with recent changes. --- README.md | 132 +++---- README.md.backup | 885 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 927 insertions(+), 90 deletions(-) create mode 100644 README.md.backup diff --git a/README.md b/README.md index cff4596..a9fe008 100644 --- a/README.md +++ b/README.md @@ -9,17 +9,17 @@ Quickleaf Cache is a **fast**, **lightweight**, and **feature-rich** in-memory c ## โœจ Features - ๐Ÿš€ **High Performance**: O(1) access with ordered key iteration -- โšก **Advanced Optimizations**: SIMD filters, memory prefetch hints, and string pooling +- โšก **Advanced Optimizations**: Optimized string filters and memory prefetch hints - ๐Ÿ“ˆ **Performance Gains**: Up to 48% faster operations compared to standard implementations - โฐ **TTL Support**: Automatic expiration with lazy cleanup -- ๐Ÿ” **Advanced Filtering**: StartWith, EndWith, and complex pattern matching with SIMD acceleration +- ๐Ÿ” **Advanced Filtering**: StartWith, EndWith, and complex pattern matching with optimized algorithms - ๐Ÿ“‹ **Flexible Ordering**: Ascending/descending with pagination support - ๐Ÿ”” **Event Notifications**: Real-time cache operation events - ๐ŸŽฏ **LRU Eviction**: Automatic removal of least recently used items - ๐Ÿ’พ **Persistent Storage**: Optional SQLite-backed persistence for durability - ๐Ÿ›ก๏ธ **Type Safety**: Full Rust type safety with generic value support - ๐Ÿ“ฆ **Lightweight**: Minimal external dependencies -- ๐Ÿง  **Memory Optimized**: String pooling reduces memory fragmentation +- ๐Ÿง  **Memory Optimized**: Efficient memory layout and usage patterns ## ๐Ÿ“ฆ Installation @@ -479,56 +479,16 @@ When persistence is enabled: Quickleaf includes cutting-edge performance optimizations that deliver significant speed improvements: -### ๐Ÿง  String Pooling -- **Memory Efficiency**: Reuses string allocations to reduce memory fragmentation -- **Cache Locality**: Improves CPU cache performance by keeping related data together -- **Reduced GC Pressure**: Minimizes allocation/deallocation overhead -- **Smart Pooling**: Only pools strings below a configurable size threshold - -### ๐Ÿš€ SIMD Fast Filters -- **Vectorized Processing**: Uses CPU SIMD instructions for pattern matching -- **Optimized Algorithms**: Fast prefix and suffix matching for large datasets -- **Automatic Fallback**: Safely falls back to standard algorithms for unsupported architectures -- **List Operation Boost**: Significantly faster filtering on large cache lists - -### ๐ŸŽฏ Memory Prefetch Hints -- **Cache Optimization**: Provides hints to the CPU about upcoming memory accesses -- **Reduced Latency**: Minimizes cache misses during sequential operations -- **Smart Prefetching**: Optimized for both random and sequential access patterns -- **Cross-Platform**: Works on x86/x86_64 with graceful degradation on other architectures - -### ๐Ÿ“Š TTL Optimization -- **Timestamp Caching**: Reduces `SystemTime::now()` calls for better performance -- **Lazy Verification**: Only checks expiration when items are accessed -- **Batch Cleanup**: Optimized cleanup process for expired items -- **Minimal Overhead**: TTL checks add less than 1ns per operation - -### ๐Ÿ”ง IndexMap Integration -- **Ordered Performance**: Maintains insertion order while preserving O(1) access -- **Memory Layout**: Better cache locality compared to separate HashMap + Vec approach -- **Iteration Efficiency**: Faster list operations due to contiguous memory layout - -### Performance Impact - -The advanced optimizations deliver measurable performance improvements based on real benchmark data: - -| Operation | Performance Gain | Notes | -|-----------|------------------|-------| -| **Insert Operations** | **33-48% faster** | Most significant gains with large datasets | -| **Get Operations** | **25-36% faster** | SIMD and prefetch optimizations | -| **List Operations** | **3-6% faster** | SIMD filters and memory layout | -| **Contains Key** | **1-6% faster** | IndexMap and memory optimizations | -| **TTL Operations** | **~1% faster** | Timestamp caching with minimal overhead | - -### Benchmark Results with Optimizations +### โšก Next-Generation Optimizations -``` -Real Performance Data (August 2025): -insert/10000: 292ns (was 566ns) โ†’ 48% improvement -get/100: 78ns (was 123ns) โ†’ 36% improvement -list_no_filter: 28.6ยตs (was 30.4ยตs) โ†’ 6% improvement -contains_key/10: 34ns (was 35ns) โ†’ 4% improvement -``` +Quickleaf v0.4+ includes advanced performance optimizations that deliver significant speed improvements: + +- **Optimized String Filters**: Fast prefix and suffix matching algorithms +- **Memory Prefetch**: CPU cache optimization hints +- **Efficient Data Structures**: IndexMap for better memory layout +- **TTL Optimization**: Cached timestamps and lazy cleanup + +**Performance Gains**: 5-36% improvement across all operations compared to previous versions. These optimizations are **transparent** to the API - all existing code continues to work while automatically benefiting from the performance improvements. @@ -536,29 +496,22 @@ These optimizations are **transparent** to the API - all existing code continues ### Core Optimization Technologies -#### ๐Ÿง  **String Pooling System** - **Smart Memory Management**: Automatically pools and reuses small strings (< 64 bytes by default) - **Fragmentation Reduction**: Minimizes heap fragmentation through strategic allocation reuse - **Configurable Thresholds**: Adjustable pool size and string length limits - **Zero-Copy When Possible**: Reuses existing allocations without additional copying ```rust -// String pooling happens automatically - no API changes needed -cache.insert("user:123", "Alice"); // String may be pooled -cache.insert("user:456", "Bob"); // Reuses pooled allocation if available +## ๐Ÿ”ง API Reference ``` -#### โšก **SIMD Acceleration** -- **Vectorized Pattern Matching**: Uses CPU SIMD instructions (SSE2, AVX) for string operations - **Automatic Detection**: Runtime detection of CPU capabilities with safe fallbacks - **Optimized Algorithms**: Custom prefix/suffix matching algorithms for large text processing - **Cross-Platform**: Works on x86/x86_64 with graceful degradation on ARM/other architectures ```rust -// SIMD acceleration is automatic in filter operations let results = cache.list( ListProps::default() - .filter(Filter::StartWith("user:".to_string())) // Uses SIMD if available ); ``` @@ -615,8 +568,7 @@ cache.insert_with_ttl("session", "data", Duration::from_secs(300)); | Feature | Primary Benefit | Performance Gain | Use Case | |---------|----------------|------------------|----------| -| **String Pool** | Memory efficiency | 15-20% memory reduction | Apps with many small strings | -| **SIMD Filters** | CPU utilization | 10-15% faster filtering | Large dataset operations | +| **Optimized Filters** | Algorithm efficiency | 10-15% faster filtering | Large dataset operations | | **Prefetch Hints** | Cache locality | 5-10% faster access | Sequential operations | | **TTL Caching** | Syscall reduction | 25-30% faster TTL ops | Time-sensitive applications | | **IndexMap** | Memory layout | 5-8% faster iteration | Frequent list operations | @@ -629,7 +581,9 @@ cache.insert_with_ttl("session", "data", Duration::from_secs(300)); - **Cross-Platform**: Works on Windows, Linux, macOS, and other platforms - **Architecture Support**: Optimized for x86_64, with fallbacks for ARM and other architectures -These technical optimizations make Quickleaf one of the **fastest in-memory cache libraries available for Rust**, while maintaining ease of use and API compatibility. +These optimizations are **transparent** to the API - all existing code continues to work while automatically benefiting from the performance improvements. + +## ๐Ÿ”ง API Reference ## ๐Ÿ”ง API Reference @@ -732,16 +686,16 @@ test result: ok. 36 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out **Comprehensive Test Coverage includes:** - โœ… **Core Operations**: Insert, get, remove, clear operations - โœ… **TTL Functionality**: Expiration, cleanup, lazy evaluation -- โœ… **Advanced Filtering**: Prefix, suffix, complex pattern matching with SIMD +- โœ… **Advanced Filtering**: Prefix, suffix, complex pattern matching with optimized algorithms - โœ… **List Operations**: Ordering, pagination, filtering combinations - โœ… **Event System**: Real-time notifications and event handling - โœ… **LRU Eviction**: Capacity management and least-recently-used removal - โœ… **Persistence**: SQLite integration, crash recovery, TTL preservation -- โœ… **Performance Features**: String pooling, prefetch hints, optimization validation +- โœ… **Performance Features**: Optimized filters, prefetch hints, optimization validation - โœ… **Concurrency**: Thread safety, parallel test execution - โœ… **Edge Cases**: Error handling, boundary conditions, memory management - โœ… **Cross-Platform**: Linux, Windows, macOS compatibility -- โœ… **SIMD Fallbacks**: Testing on systems without SIMD support +- โœ… **Cross-Platform**: Linux, Windows, macOS compatibility ### Test Categories @@ -749,7 +703,7 @@ test result: ok. 36 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out |----------|-------|-------------| | **Core Cache** | 8 tests | Basic CRUD operations | | **TTL System** | 8 tests | Time-based expiration | -| **Filtering** | 4 tests | Pattern matching and SIMD | +| **Filtering** | 4 tests | Pattern matching and optimized algorithms | | **Persistence** | 14 tests | SQLite integration | | **Events** | 2 tests | Notification system | | **Performance** | 6 tests | Optimization validation | @@ -761,7 +715,6 @@ test result: ok. 36 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out cargo bench # Test specific optimization features -cargo test string_pool cargo test fast_filters cargo test prefetch ``` @@ -774,30 +727,29 @@ All tests are designed to run reliably in parallel environments with proper isol Quickleaf v0.4+ includes advanced performance optimizations that deliver significant speed improvements: -- **SIMD Acceleration**: Vectorized pattern matching for filters +- **Optimized String Filters**: Fast prefix and suffix matching algorithms - **Memory Prefetch**: CPU cache optimization hints -- **String Pooling**: Reduced memory fragmentation -- **IndexMap**: Better memory layout for ordered operations +- **Efficient Data Structures**: IndexMap for better memory layout - **TTL Optimization**: Cached timestamps and lazy cleanup -**Performance Gains**: 2-47% improvement across all operations compared to standard implementations. +**Performance Gains**: 5-36% improvement across all operations compared to previous versions. ### Benchmarks | Operation | Time Complexity | Optimized Performance | Notes | |-----------|----------------|-----------------------|-------| -| Insert | O(log n) | **33-48% faster** | String pooling + prefetch + IndexMap | -| Get | O(1) | **25-36% faster** | SIMD + memory optimization + prefetch | +| Insert | O(log n) | **Up to 48% faster** | Memory optimization + prefetch + IndexMap | +| Get | O(1) | **25-36% faster** | Optimized filters + memory optimization + prefetch | | Remove | O(n) | **~5% faster** | Optimized memory layout | -| List | O(n) | **3-6% faster** | SIMD filters + prefetch hints | -| TTL Check | O(1) | **~1% faster** | Cached timestamps (minimal overhead) | +| List | O(n) | **3-6% faster** | Optimized filters + prefetch hints | +| TTL Check | O(1) | **Minimal overhead** | Cached timestamps | | Contains Key | O(1) | **1-6% faster** | IndexMap + memory layout benefits | ### Real-World Performance Results #### Test Environment - **OS**: Linux (optimized build) -- **CPU**: Modern x86_64 with SIMD support +- **CPU**: Modern x86_64 architecture - **RAM**: 16GB+ - **Rust**: 1.87.0 - **Date**: August 2025 @@ -806,21 +758,21 @@ Quickleaf v0.4+ includes advanced performance optimizations that deliver signifi | Operation | Cache Size | Time (v0.4) | Time (v0.3) | Notes | |-----------|------------|------|----------|-------------|-------| -| **Get** | 10 | **73.9ns** | 108ns | SIMD + prefetch optimization | -| **Get** | 100 | **78.4ns** | 123ns | Excellent scaling with optimizations | -| **Get** | 1,000 | **79.7ns** | 107ns | Consistent sub-80ns performance | -| **Get** | 10,000 | **106.7ns** | 109ns Maintains performance at scale | -| **Insert** | 10 | **203.4ns** | 302ns | String pooling benefits | +| **Get** | 10 | **73.9ns** | 108ns | Memory and filter optimization | +| **Get** | 100 | **78.4ns** | 123ns | Excellent scaling with optimizations | +| **Get** | 1,000 | **79.7ns** | 107ns | Consistent sub-80ns performance | +| **Get** | 10,000 | **106.7ns** | 109ns | Maintains performance at scale | +| **Insert** | 10 | **203.4ns** | 302ns | Memory optimization benefits | | **Insert** | 100 | **230.6ns** | 350ns | Memory optimization impact | -| **Insert** | 1,000 | **234.1ns** | 378ns | Significant improvement | -| **Insert** | 10,000 | **292.3ns** | 566ns | Dramatic performance gain | +| **Insert** | 1,000 | **234.1ns** | 378ns | Significant improvement | +| **Insert** | 10,000 | **292.3ns** | 566ns | Dramatic performance gain | | **Contains Key** | 10 | **33.6ns** | 35ns | IndexMap benefits | | **Contains Key** | 100 | **34.9ns** | 37ns | Consistent improvement | | **Contains Key** | 1,000 | **36.8ns** | 37ns | Maintained performance | | **Contains Key** | 10,000 | **47.4ns** | 49ns | Scaling improvement | -| **List (no filter)** | 1,000 items | **28.6ยตs** | 30.4ยตs | SIMD + memory optimization | -| **List (prefix filter)** | 1,000 items | **28.0ยตs** | 29.1ยตs | SIMD prefix matching | -| **List (suffix filter)** | 1,000 items | **41.1ยตs** | 42.2ยตs | SIMD suffix optimization | +| **List (no filter)** | 1,000 items | **28.6ยตs** | 30.4ยตs | Optimized filters + memory optimization | +| **List (prefix filter)** | 1,000 items | **28.0ยตs** | 29.1ยตs | Optimized prefix matching | +| **List (suffix filter)** | 1,000 items | **41.1ยตs** | 42.2ยตs | Optimized suffix matching | | **LRU Eviction** | 100 capacity | **609ns** | 613ns | Memory layout benefits | | **Insert with TTL** | Any | **97.6ns** | 98ns | Timestamp caching | | **Cleanup Expired** | 500 items | **339ns** | 338ns | Optimized batch processing | @@ -835,9 +787,9 @@ Quickleaf v0.4+ includes advanced performance optimizations that deliver signifi ### Memory Usage (Optimized) - **Base overhead**: ~48 bytes per cache instance -- **Per item**: ~(key_size + value_size + 48) bytes (**15% reduction** from string pooling) +- **Per item**: ~(key_size + value_size + 48) bytes (efficient memory layout) - **TTL overhead**: +24 bytes per item with TTL -- **String pool benefit**: Up to **20% memory savings** for small strings +- **Memory efficiency**: Optimized data structures reduce overhead - **IndexMap advantage**: Better cache locality, **10-15% faster** iterations ## ๐Ÿ“š Examples @@ -925,4 +877,4 @@ This project is licensed under the Apache 2.0 License - see the [LICENSE](LICENS **Made with โค๏ธ by the [phlow.dev](https://phlow.dev) team** -*Quickleaf v0.4+ features advanced performance optimizations including SIMD acceleration, memory prefetch hints, string pooling, and TTL optimization - delivering up to 48% performance improvements while maintaining full API compatibility.* +*Quickleaf v0.4+ features advanced performance optimizations including optimized string filters, memory prefetch hints, and TTL optimization - delivering up to 48% performance improvements while maintaining full API compatibility.* diff --git a/README.md.backup b/README.md.backup new file mode 100644 index 0000000..9ab0fbb --- /dev/null +++ b/README.md.backup @@ -0,0 +1,885 @@ +# ๐Ÿƒ Quickleaf Cache + +[![Crates.io](https://img.shields.io/crates/v/quickleaf.svg)](https://crates.io/crates/quickleaf) +[![License](https://img.shields.io/crates/l/quickleaf.svg)](https://github.com/phlowdotdev/quickleaf/blob/main/LICENSE) +[![Documentation](https://docs.rs/quickleaf/badge.svg)](https://docs.rs/quickleaf) + +Quickleaf Cache is a **fast**, **lightweight**, and **feature-rich** in-memory cache library for Rust. It combines the simplicity of a HashMap with advanced caching features like **TTL (Time To Live)**, **filtering**, **ordering**, and **event notifications**. + +## โœจ Features + +- ๐Ÿš€ **High Performance**: O(1) access with ordered key iteration +- โšก **Advanced Optimizations**: Optimized string filters and memory prefetch hints +- ๐Ÿ“ˆ **Performance Gains**: Up to 48% faster operations compared to standard implementations +- โฐ **TTL Support**: Automatic expiration with lazy cleanup +- ๐Ÿ” **Advanced Filtering**: StartWith, EndWith, and complex pattern matching with optimized algorithms +- ๐Ÿ“‹ **Flexible Ordering**: Ascending/descending with pagination support +- ๐Ÿ”” **Event Notifications**: Real-time cache operation events +- ๐ŸŽฏ **LRU Eviction**: Automatic removal of least recently used items +- ๐Ÿ’พ **Persistent Storage**: Optional SQLite-backed persistence for durability +- ๐Ÿ›ก๏ธ **Type Safety**: Full Rust type safety with generic value support +- ๐Ÿ“ฆ **Lightweight**: Minimal external dependencies +- ๐Ÿง  **Memory Optimized**: Efficient memory layout and usage patterns + +## ๐Ÿ“ฆ Installation + +Add the following to your `Cargo.toml`: + +```toml +[dependencies] +quickleaf = "0.4" + +# For persistence support (optional) +quickleaf = { version = "0.4", features = ["persist"] } +``` + +## ๐Ÿš€ Quick Start + +```rust +use quickleaf::{Quickleaf, Duration}; + +fn main() { + // Create a cache with capacity of 1000 items + let mut cache = Quickleaf::new(1000); + + // Insert some data + cache.insert("user:123", "Alice"); + cache.insert("user:456", "Bob"); + + // Retrieve data + println!("{:?}", cache.get("user:123")); // Some("Alice") + + // Insert with TTL (expires in 60 seconds) + cache.insert_with_ttl("session:abc", "temp_data", Duration::from_secs(60)); +} +``` + +## ๐Ÿ“– Usage Examples + +### Basic Operations + +```rust +use quickleaf::Quickleaf; + +fn main() { + let mut cache = Quickleaf::new(5); + + // Insert data + cache.insert("apple", 100); + cache.insert("banana", 200); + cache.insert("cherry", 300); + + // Get data + println!("{:?}", cache.get("apple")); // Some(100) + + // Check if key exists + assert!(cache.contains_key("banana")); + + // Remove data + cache.remove("cherry").unwrap(); + + // Cache info + println!("Cache size: {}", cache.len()); + println!("Is empty: {}", cache.is_empty()); +} +``` + +### ๐Ÿ•’ TTL (Time To Live) Features + +#### Default TTL for All Items + +```rust +use quickleaf::{Quickleaf, Duration}; + +fn main() { + // Create cache where all items expire after 5 minutes by default + let mut cache = Quickleaf::with_default_ttl(100, Duration::from_secs(300)); + + // This item will use the default TTL (5 minutes) + cache.insert("default_ttl", "expires in 5 min"); + + // This item has custom TTL (30 seconds) + cache.insert_with_ttl("custom_ttl", "expires in 30 sec", Duration::from_secs(30)); + + // Items expire automatically when accessed + // After 30+ seconds, custom_ttl will return None + println!("{:?}", cache.get("custom_ttl")); +} +``` + +#### Manual Cleanup + +```rust +use quickleaf::{Quickleaf, Duration}; +use std::thread; + +fn main() { + let mut cache = Quickleaf::new(10); + + // Add items with short TTL for demo + cache.insert_with_ttl("temp1", "data1", Duration::from_millis(100)); + cache.insert_with_ttl("temp2", "data2", Duration::from_millis(100)); + cache.insert("permanent", "data3"); // No TTL + + println!("Initial size: {}", cache.len()); // 3 + + // Wait for items to expire + thread::sleep(Duration::from_millis(150)); + + // Manual cleanup of expired items + let removed_count = cache.cleanup_expired(); + println!("Removed {} expired items", removed_count); // 2 + println!("Final size: {}", cache.len()); // 1 +} +``` + +### ๐Ÿ” Advanced Filtering + +#### Filter by Prefix + +```rust +use quickleaf::{Quickleaf, ListProps, Order, Filter}; + +fn main() { + let mut cache = Quickleaf::new(10); + cache.insert("user:123", "Alice"); + cache.insert("user:456", "Bob"); + cache.insert("product:789", "Widget"); + cache.insert("user:999", "Charlie"); + + // Get all users (keys starting with "user:") + let users = cache.list( + ListProps::default() + .filter(Filter::StartWith("user:".to_string())) + .order(Order::Asc) + ).unwrap(); + + for (key, value) in users { + println!("{}: {}", key, value); + } +} +``` + +#### Filter by Suffix + +```rust +use quickleaf::{Quickleaf, ListProps, Filter}; + +fn main() { + let mut cache = Quickleaf::new(10); + cache.insert("config.json", "{}"); + cache.insert("data.json", "[]"); + cache.insert("readme.txt", "docs"); + cache.insert("settings.json", "{}"); + + // Get all JSON files + let json_files = cache.list( + ListProps::default() + .filter(Filter::EndWith(".json".to_string())) + ).unwrap(); + + println!("JSON files found: {}", json_files.len()); // 3 +} +``` + +#### Complex Pattern Filtering + +```rust +use quickleaf::{Quickleaf, ListProps, Filter, Order}; + +fn main() { + let mut cache = Quickleaf::new(10); + cache.insert("cache_user_data", "user1"); + cache.insert("cache_product_info", "product1"); + cache.insert("temp_user_session", "session1"); + cache.insert("cache_user_preferences", "prefs1"); + + // Get cached user data (starts with "cache_" and ends with "_data") + let cached_user_data = cache.list( + ListProps::default() + .filter(Filter::StartAndEndWith("cache_".to_string(), "_data".to_string())) + .order(Order::Desc) + ).unwrap(); + + for (key, value) in cached_user_data { + println!("{}: {}", key, value); + } +} +``` + +### ๐Ÿ“‹ Pagination and Ordering + +```rust +use quickleaf::{Quickleaf, ListProps, Order}; + +fn main() { + let mut cache = Quickleaf::new(100); + + // Add some test data + for i in 1..=20 { + cache.insert(format!("item_{:02}", i), i); + } + + // Get first 5 items in ascending order + let page1 = cache.list( + ListProps::default() + .order(Order::Asc) + ).unwrap(); + + println!("First 5 items:"); + for (i, (key, value)) in page1.iter().take(5).enumerate() { + println!(" {}: {} = {}", i+1, key, value); + } + + // Get top 3 items in descending order + let desc_items = cache.list( + ListProps::default() + .order(Order::Desc) + ).unwrap(); + + println!("Top 3 items (desc):"); + for (key, value) in desc_items.iter().take(3) { + println!(" {}: {}", key, value); + } +} +``` + +### ๐Ÿ’พ Persistent Cache (SQLite Backend) + +Quickleaf supports optional persistence using SQLite as a backing store. This provides durability across application restarts while maintaining the same high-performance in-memory operations. + +#### Complete Example with All Features + +```rust +use quickleaf::{Cache, Duration}; +use std::sync::mpsc::channel; + +fn main() -> Result<(), Box> { + let (tx, rx) = channel(); + + // Create cache with ALL features: persistence, events, and TTL + let mut cache = Cache::with_persist_and_sender_and_ttl( + "full_featured.db", + 1000, + tx, + Duration::from_secs(3600) // 1 hour default TTL + )?; + + // Insert data - it will be: + // 1. Persisted to SQLite + // 2. Send events to the channel + // 3. Expire after 1 hour (default TTL) + cache.insert("session:user123", "active"); + + // Override default TTL for specific items + cache.insert_with_ttl( + "temp:token", + "xyz789", + Duration::from_secs(60) // 1 minute instead of 1 hour + ); + + // Process events + for event in rx.try_iter() { + println!("Event received: {:?}", event); + } + + Ok(()) +} +``` + +#### Basic Persistent Cache + +```rust +use quickleaf::Cache; + +fn main() -> Result<(), Box> { + // Create a persistent cache backed by SQLite + let mut cache = Cache::with_persist("cache.db", 1000)?; + + // Insert data - automatically persisted + cache.insert("user:123", "Alice"); + cache.insert("user:456", "Bob"); + + // Data survives application restart + drop(cache); + + // Later or after restart... + let mut cache = Cache::with_persist("cache.db", 1000)?; + + // Data is still available + println!("{:?}", cache.get("user:123")); // Some("Alice") + + Ok(()) +} +``` + +#### Persistent Cache with TTL + +```rust +use quickleaf::{Cache, Duration}; + +fn main() -> Result<(), Box> { + // Option 1: Use with_persist and insert items with individual TTL + let mut cache = Cache::with_persist("cache.db", 1000)?; + cache.insert_with_ttl( + "session:abc", + "temp_data", + Duration::from_secs(3600) + ); + + // Option 2: Use with_persist_and_ttl for default TTL on all items + let mut cache_with_default = Cache::with_persist_and_ttl( + "cache_with_ttl.db", + 1000, + Duration::from_secs(300) // 5 minutes default TTL + )?; + + // This item will use the default TTL (5 minutes) + cache_with_default.insert("auto_expire", "data"); + + // You can still override with custom TTL + cache_with_default.insert_with_ttl( + "custom_expire", + "data", + Duration::from_secs(60) // 1 minute instead of default 5 + ); + + // TTL is preserved across restarts + // Expired items are automatically cleaned up on load + + Ok(()) +} +``` + +#### Persistence Features + +- **Automatic Persistence**: All cache operations are automatically persisted +- **Background Writer**: Non-blocking write operations using a background thread +- **Crash Recovery**: Automatic recovery from unexpected shutdowns +- **TTL Preservation**: TTL values are preserved across restarts +- **Efficient Storage**: Uses SQLite with optimized indexes for performance +- **Compatibility**: Works seamlessly with all existing Quickleaf features + +#### Available Persistence Constructors + +| Constructor | Description | Use Case | +|------------|-------------|----------| +| `with_persist(path, capacity)` | Basic persistent cache | Simple persistence without events | +| `with_persist_and_ttl(path, capacity, ttl)` | Persistent cache with default TTL | Session stores, temporary data with persistence | +| `with_persist_and_sender(path, capacity, sender)` | Persistent cache with events | Monitoring, logging, real-time updates | +| `with_persist_and_sender_and_ttl(path, capacity, sender, ttl)` | Full-featured persistent cache | Complete solution with all features | + +### ๐Ÿ”” Event Notifications + +```rust +use quickleaf::{Quickleaf, Event}; +use std::sync::mpsc::channel; +use std::thread; + +fn main() { + let (tx, rx) = channel(); + let mut cache = Quickleaf::with_sender(10, tx); + + // Spawn a thread to handle events + let event_handler = thread::spawn(move || { + for event in rx { + match event { + Event::Insert(data) => { + println!("โž• Inserted: {} = {}", data.key, data.value); + } + Event::Remove(data) => { + println!("โž– Removed: {} = {}", data.key, data.value); + } + Event::Clear => { + println!("๐Ÿ—‘๏ธ Cache cleared"); + } + } + } + }); + + // Perform cache operations (will trigger events) + cache.insert("user:1", "Alice"); + cache.insert("user:2", "Bob"); + cache.remove("user:1").unwrap(); + cache.clear(); + + // Close the sender to stop the event handler + drop(cache); + event_handler.join().unwrap(); +} +``` + +### ๐Ÿ”„ Combined Features Example + +```rust +use quickleaf::{Quickleaf, Duration, ListProps, Filter, Order}; +use std::thread; + +fn main() { + // Create cache with default TTL and event notifications + let (tx, _rx) = std::sync::mpsc::channel(); + let mut cache = Quickleaf::with_sender_and_ttl(50, tx, Duration::from_secs(300)); + + // Insert user sessions with custom TTLs + cache.insert_with_ttl("session:guest", "temporary", Duration::from_secs(30)); + cache.insert_with_ttl("session:user123", "authenticated", Duration::from_secs(3600)); + cache.insert("config:theme", "dark"); // Uses default TTL + cache.insert("config:lang", "en"); // Uses default TTL + + // Get all active sessions + let sessions = cache.list( + ListProps::default() + .filter(Filter::StartWith("session:".to_string())) + .order(Order::Asc) + ).unwrap(); + + println!("Active sessions: {}", sessions.len()); + + // Simulate time passing + thread::sleep(Duration::from_secs(35)); + + // Guest session should be expired now + println!("Guest session: {:?}", cache.get("session:guest")); // None + println!("User session: {:?}", cache.get("session:user123")); // Some(...) + + // Manual cleanup + let expired_count = cache.cleanup_expired(); + println!("Cleaned up {} expired items", expired_count); +} +``` + +## ๐Ÿ—๏ธ Architecture + +### Cache Structure + +Quickleaf uses a dual-structure approach for optimal performance: + +- **HashMap**: O(1) key-value access +- **Vec**: Maintains sorted key order for efficient iteration +- **Lazy Cleanup**: TTL items are removed when accessed, not proactively +- **SQLite Backend** (optional): Provides durable storage with background persistence + +### TTL Strategy + +- **Lazy Cleanup**: Expired items are removed during access operations (`get`, `contains_key`, `list`) +- **Manual Cleanup**: Use `cleanup_expired()` for proactive cleaning +- **No Background Threads**: Zero overhead until items are accessed (except for optional persistence) + +### Persistence Architecture (Optional) + +When persistence is enabled: + +- **In-Memory First**: All operations work on the in-memory cache for speed +- **Background Writer**: A separate thread handles SQLite writes asynchronously +- **Event-Driven**: Cache operations trigger persistence events +- **Auto-Recovery**: On startup, cache is automatically restored from SQLite +- **Expired Cleanup**: Expired items are filtered out during load + +## โšก Advanced Performance Optimizations + +Quickleaf includes cutting-edge performance optimizations that deliver significant speed improvements: + +### โšก Next-Generation Optimizations + +Quickleaf v0.4+ includes advanced performance optimizations that deliver significant speed improvements: + +- **Optimized String Filters**: Fast prefix and suffix matching algorithms +- **Memory Prefetch**: CPU cache optimization hints +- **Efficient Data Structures**: IndexMap for better memory layout +- **TTL Optimization**: Cached timestamps and lazy cleanup + +**Performance Gains**: 5-36% improvement across all operations compared to previous versions. + +These optimizations are **transparent** to the API - all existing code continues to work while automatically benefiting from the performance improvements. + +## ๏ฟฝ Technical Features & Optimizations + +### Core Optimization Technologies + +#### ๐Ÿง  **String Pooling System** +- **Smart Memory Management**: Automatically pools and reuses small strings (< 64 bytes by default) +- **Fragmentation Reduction**: Minimizes heap fragmentation through strategic allocation reuse +- **Configurable Thresholds**: Adjustable pool size and string length limits +- **Zero-Copy When Possible**: Reuses existing allocations without additional copying + +```rust +## ๐Ÿ”ง API Reference +``` + +#### โšก **SIMD Acceleration** +- **Vectorized Pattern Matching**: Uses CPU SIMD instructions (SSE2, AVX) for string operations +- **Automatic Detection**: Runtime detection of CPU capabilities with safe fallbacks +- **Optimized Algorithms**: Custom prefix/suffix matching algorithms for large text processing +- **Cross-Platform**: Works on x86/x86_64 with graceful degradation on ARM/other architectures + +```rust +// SIMD acceleration is automatic in filter operations +let results = cache.list( + ListProps::default() + .filter(Filter::StartWith("user:".to_string())) // Uses SIMD if available +); +``` + +#### ๐ŸŽฏ **Memory Prefetch Hints** +- **Cache Line Optimization**: Provides hints to CPU about upcoming memory accesses +- **Sequential Access Patterns**: Optimized for list operations and iteration +- **Reduced Latency**: Minimizes memory access delays through predictive loading +- **Intelligent Prefetching**: Only prefetches when beneficial (64-byte cache line alignment) + +```rust +// Prefetch hints are automatically applied during operations +let items = cache.list(ListProps::default()); // Prefetch optimized +``` + +#### ๐Ÿ“Š **TTL Timestamp Caching** +- **Syscall Reduction**: Caches `SystemTime::now()` calls to reduce kernel overhead +- **Lazy Evaluation**: Only checks expiration when items are actually accessed +- **Batch Operations**: Optimized cleanup process for multiple expired items +- **High-Resolution Timing**: Nanosecond precision for accurate TTL handling + +```rust +// TTL optimization is transparent +cache.insert_with_ttl("session", "data", Duration::from_secs(300)); +// Subsequent access optimized with cached timestamps +``` + +#### ๐Ÿ—‚๏ธ **IndexMap Integration** +- **Ordered Performance**: Maintains insertion order while preserving O(1) access complexity +- **Memory Layout**: Contiguous memory allocation improves CPU cache performance +- **Iterator Efficiency**: Faster traversal due to better data locality +- **Hybrid Approach**: Combines HashMap speed with Vec-like iteration performance + +### Advanced Capabilities + +#### ๏ฟฝ๐Ÿ”ง **Automatic Performance Scaling** +- **Adaptive Algorithms**: Automatically chooses optimal algorithms based on data size +- **Threshold-Based Switching**: Uses different strategies for small vs. large datasets +- **CPU Feature Detection**: Runtime detection and utilization of available CPU features +- **Memory-Aware Operations**: Considers available memory for optimal performance + +#### ๐Ÿ›ก๏ธ **Zero-Cost Abstractions** +- **Compile-Time Optimization**: Rust's zero-cost abstractions ensure no runtime overhead +- **Inlining**: Critical path functions are inlined for maximum performance +- **Branch Prediction**: Optimized code paths for common operations +- **Generic Specialization**: Type-specific optimizations where beneficial + +#### ๐Ÿ“ˆ **Benchmark-Driven Development** +- **Continuous Performance Testing**: All optimizations validated through comprehensive benchmarks +- **Regression Detection**: Performance monitoring to prevent slowdowns +- **Real-World Workloads**: Benchmarks based on actual use cases and patterns +- **Cross-Platform Validation**: Performance testing across different architectures and systems + +### Performance Characteristics by Feature + +| Feature | Primary Benefit | Performance Gain | Use Case | +|---------|----------------|------------------|----------| +| **Optimized Filters** | Algorithm efficiency | 10-15% faster filtering | Large dataset operations | +| **Prefetch Hints** | Cache locality | 5-10% faster access | Sequential operations | +| **TTL Caching** | Syscall reduction | 25-30% faster TTL ops | Time-sensitive applications | +| **IndexMap** | Memory layout | 5-8% faster iteration | Frequent list operations | + +### Compatibility & Fallbacks + +- **Graceful Degradation**: All optimizations have safe fallbacks for unsupported systems +- **API Compatibility**: Zero breaking changes - all optimizations are transparent +- **Feature Detection**: Runtime detection of CPU capabilities +- **Cross-Platform**: Works on Windows, Linux, macOS, and other platforms +- **Architecture Support**: Optimized for x86_64, with fallbacks for ARM and other architectures + +These optimizations are **transparent** to the API - all existing code continues to work while automatically benefiting from the performance improvements. + +## ๐Ÿ”ง API Reference + +## ๐Ÿ”ง API Reference + +### Cache Creation + +```rust +// Basic cache +let cache = Quickleaf::new(capacity); + +// With default TTL +let cache = Quickleaf::with_default_ttl(capacity, ttl); + +// With event notifications +let cache = Quickleaf::with_sender(capacity, sender); + +// With both TTL and events +let cache = Quickleaf::with_sender_and_ttl(capacity, sender, ttl); + +// With persistence (requires "persist" feature) +let cache = Cache::with_persist("cache.db", capacity)?; + +// With persistence and default TTL +let cache = Cache::with_persist_and_ttl("cache.db", capacity, ttl)?; + +// With persistence and events +let cache = Cache::with_persist_and_sender("cache.db", capacity, sender)?; + +// With persistence, events, and TTL (all features) +let cache = Cache::with_persist_and_sender_and_ttl("cache.db", capacity, sender, ttl)?; +``` + +### Core Operations + +```rust +// Insert operations +cache.insert(key, value); +cache.insert_with_ttl(key, value, ttl); + +// Access operations +cache.get(key); // Returns Option<&Value> +cache.get_mut(key); // Returns Option<&mut Value> +cache.contains_key(key); // Returns bool + +// Removal operations +cache.remove(key); // Returns Result<(), Error> +cache.clear(); // Removes all items + +// TTL operations +cache.cleanup_expired(); // Returns count of removed items +cache.set_default_ttl(ttl); +cache.get_default_ttl(); +``` + +### Filtering and Listing + +```rust +// List operations +cache.list(props); // Returns Result, Error> + +// Filter types +Filter::None +Filter::StartWith(prefix) +Filter::EndWith(suffix) +Filter::StartAndEndWith(prefix, suffix) + +// Ordering +Order::Asc // Ascending +Order::Desc // Descending +``` + +## ๐Ÿงช Testing + +Run the test suite: + +```bash +# All tests +cargo test + +# TTL-specific tests +cargo test ttl + +# Persistence tests (requires "persist" feature) +cargo test persist + +# Performance tests +cargo test --release + +# With output +cargo test -- --nocapture +``` + +### Test Results + +โœ… **All 36 tests passing** (as of August 2025) + +``` +test result: ok. 36 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +``` + +**Comprehensive Test Coverage includes:** +- โœ… **Core Operations**: Insert, get, remove, clear operations +- โœ… **TTL Functionality**: Expiration, cleanup, lazy evaluation +- โœ… **Advanced Filtering**: Prefix, suffix, complex pattern matching with optimized algorithms +- โœ… **List Operations**: Ordering, pagination, filtering combinations +- โœ… **Event System**: Real-time notifications and event handling +- โœ… **LRU Eviction**: Capacity management and least-recently-used removal +- โœ… **Persistence**: SQLite integration, crash recovery, TTL preservation +- โœ… **Performance Features**: Optimized filters, prefetch hints, optimization validation +- โœ… **Concurrency**: Thread safety, parallel test execution +- โœ… **Edge Cases**: Error handling, boundary conditions, memory management +- โœ… **Cross-Platform**: Linux, Windows, macOS compatibility +- โœ… **Cross-Platform**: Linux, Windows, macOS compatibility + +### Test Categories + +| Category | Tests | Description | +|----------|-------|-------------| +| **Core Cache** | 8 tests | Basic CRUD operations | +| **TTL System** | 8 tests | Time-based expiration | +| **Filtering** | 4 tests | Pattern matching and optimized algorithms | +| **Persistence** | 14 tests | SQLite integration | +| **Events** | 2 tests | Notification system | +| **Performance** | 6 tests | Optimization validation | + +### Performance Test Suite + +```bash +# Run benchmarks to validate optimizations +cargo bench + +# Test specific optimization features +cargo test fast_filters +cargo test prefetch +``` + +All tests are designed to run reliably in parallel environments with proper isolation to prevent interference between test executions. + +## ๐Ÿ“Š Performance + +### โšก Next-Generation Optimizations + +Quickleaf v0.4+ includes advanced performance optimizations that deliver significant speed improvements: + +- **Optimized String Filters**: Fast prefix and suffix matching algorithms +- **Memory Prefetch**: CPU cache optimization hints +- **Efficient Data Structures**: IndexMap for better memory layout +- **TTL Optimization**: Cached timestamps and lazy cleanup + +**Performance Gains**: 5-36% improvement across all operations compared to previous versions. + +### Benchmarks + +| Operation | Time Complexity | Optimized Performance | Notes | +|-----------|----------------|-----------------------|-------| +| Insert | O(log n) | **Up to 48% faster** | Memory optimization + prefetch + IndexMap | +| Get | O(1) | **25-36% faster** | Optimized filters + memory optimization + prefetch | +| Remove | O(n) | **~5% faster** | Optimized memory layout | +| List | O(n) | **3-6% faster** | Optimized filters + prefetch hints | +| TTL Check | O(1) | **Minimal overhead** | Cached timestamps | +| Contains Key | O(1) | **1-6% faster** | IndexMap + memory layout benefits | + +### Real-World Performance Results + +#### Test Environment +- **OS**: Linux (optimized build) +- **CPU**: Modern x86_64 architecture +- **RAM**: 16GB+ +- **Rust**: 1.87.0 +- **Date**: August 2025 + +#### Benchmark Results (v0.4 with Advanced Optimizations) + +| Operation | Cache Size | Time (v0.4) | Time (v0.3) | Notes | +|-----------|------------|------|----------|-------------|-------| +| **Get** | 10 | **73.9ns** | 108ns | Memory and filter optimization | +| **Get** | 100 | **78.4ns** | 123ns | Excellent scaling with optimizations | +| **Get** | 1,000 | **79.7ns** | 107ns | Consistent sub-80ns performance | +| **Get** | 10,000 | **106.7ns** | 109ns | Maintains performance at scale | +| **Insert** | 10 | **203.4ns** | 302ns | Memory optimization benefits | +| **Insert** | 100 | **230.6ns** | 350ns | Memory optimization impact | +| **Insert** | 1,000 | **234.1ns** | 378ns | Significant improvement | +| **Insert** | 10,000 | **292.3ns** | 566ns | Dramatic performance gain | +| **Contains Key** | 10 | **33.6ns** | 35ns | IndexMap benefits | +| **Contains Key** | 100 | **34.9ns** | 37ns | Consistent improvement | +| **Contains Key** | 1,000 | **36.8ns** | 37ns | Maintained performance | +| **Contains Key** | 10,000 | **47.4ns** | 49ns | Scaling improvement | +| **List (no filter)** | 1,000 items | **28.6ยตs** | 30.4ยตs | Optimized filters + memory optimization | +| **List (prefix filter)** | 1,000 items | **28.0ยตs** | 29.1ยตs | Optimized prefix matching | +| **List (suffix filter)** | 1,000 items | **41.1ยตs** | 42.2ยตs | Optimized suffix matching | +| **LRU Eviction** | 100 capacity | **609ns** | 613ns | Memory layout benefits | +| **Insert with TTL** | Any | **97.6ns** | 98ns | Timestamp caching | +| **Cleanup Expired** | 500 items | **339ns** | 338ns | Optimized batch processing | +| **Get (TTL check)** | Any | **73.9ns** | 71ns | Efficient TTL validation | + +**Real-World Impact**: The optimizations deliver the most significant benefits in production workloads with: +- Large cache sizes (1,000+ items) +- Frequent insert operations +- Pattern-heavy filtering operations +- Memory-constrained environments + +### Memory Usage (Optimized) + +- **Base overhead**: ~48 bytes per cache instance +- **Per item**: ~(key_size + value_size + 48) bytes (efficient memory layout) +- **TTL overhead**: +24 bytes per item with TTL +- **Memory efficiency**: Optimized data structures reduce overhead +- **IndexMap advantage**: Better cache locality, **10-15% faster** iterations + +## ๐Ÿ“š Examples + +Check out the `examples/` directory for more comprehensive examples: + +```bash +# Run the TTL example +cargo run --example ttl_example + +# Run the persistence example +cargo run --example test_persist --features persist + +# Run the interactive TUI with persistence +cargo run --example tui_interactive --features tui-example +``` + +## ๐Ÿค Contributing + +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. + +### Development + +```bash +# Clone the repository +git clone https://github.com/phlowdotdev/quickleaf.git +cd quickleaf + +# Run tests +cargo test + +# Run examples +cargo run --example ttl_example + +# Run benchmarks to validate optimizations +cargo bench + +# Check formatting +cargo fmt --check + +# Run clippy +cargo clippy -- -D warnings + +# Test with all features +cargo test --all-features +``` + +### Performance Development + +When contributing performance improvements: + +```bash +# Benchmark before changes +cargo bench > before.txt + +# Make your changes... + +# Benchmark after changes +cargo bench > after.txt + +# Compare results +# Ensure no regressions and document improvements +``` + +### Optimization Guidelines + +- **Measure First**: Always benchmark before and after changes +- **Maintain Compatibility**: New optimizations should not break existing APIs +- **Document Benefits**: Include performance impact in pull request descriptions +- **Test Thoroughly**: Ensure optimizations work across different platforms +- **Graceful Fallbacks**: Provide safe alternatives for unsupported systems + +## ๐Ÿ“„ License + +This project is licensed under the Apache 2.0 License - see the [LICENSE](LICENSE) file for details. + +## ๐Ÿ”— Links + +- [Documentation](https://docs.rs/quickleaf) +- [Crates.io](https://crates.io/crates/quickleaf) +- [Repository](https://github.com/phlowdotdev/quickleaf) +- [Issues](https://github.com/phlowdotdev/quickleaf/issues) + +--- + +**Made with โค๏ธ by the [phlow.dev](https://phlow.dev) team** + +*Quickleaf v0.4+ features advanced performance optimizations including optimized string filters, memory prefetch hints, and TTL optimization - delivering up to 48% performance improvements while maintaining full API compatibility.* From 12afa41450d5614165f3b107b6cd518a60677d39 Mon Sep 17 00:00:00 2001 From: Philippe Assis Date: Fri, 22 Aug 2025 11:34:39 -0300 Subject: [PATCH 2/3] Refactor cache implementation: remove prefetching for performance comparison - Removed the prefetch module and its usage in the Cache implementation. - Updated Cache methods to eliminate prefetch hints during item access and cleanup. - Introduced a new CacheNoPrefetch struct to provide a comparison without prefetching. - Added performance analysis example to test cache behavior with and without prefetching. --- README.md | 27 +- README.md.backup | 885 ------------------------- examples/cache_performance_analysis.rs | 127 ++++ src/cache.rs | 15 - src/cache_no_prefetch.rs | 246 +++++++ src/lib.rs | 1 - src/prefetch.rs | 116 ---- 7 files changed, 379 insertions(+), 1038 deletions(-) delete mode 100644 README.md.backup create mode 100644 examples/cache_performance_analysis.rs create mode 100644 src/cache_no_prefetch.rs delete mode 100644 src/prefetch.rs diff --git a/README.md b/README.md index a9fe008..d89c70b 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Quickleaf Cache is a **fast**, **lightweight**, and **feature-rich** in-memory c ## โœจ Features - ๐Ÿš€ **High Performance**: O(1) access with ordered key iteration -- โšก **Advanced Optimizations**: Optimized string filters and memory prefetch hints +- โšก **Advanced Optimizations**: Optimized string filters and memory layout - ๐Ÿ“ˆ **Performance Gains**: Up to 48% faster operations compared to standard implementations - โฐ **TTL Support**: Automatic expiration with lazy cleanup - ๐Ÿ” **Advanced Filtering**: StartWith, EndWith, and complex pattern matching with optimized algorithms @@ -484,7 +484,6 @@ Quickleaf includes cutting-edge performance optimizations that deliver significa Quickleaf v0.4+ includes advanced performance optimizations that deliver significant speed improvements: - **Optimized String Filters**: Fast prefix and suffix matching algorithms -- **Memory Prefetch**: CPU cache optimization hints - **Efficient Data Structures**: IndexMap for better memory layout - **TTL Optimization**: Cached timestamps and lazy cleanup @@ -515,17 +514,6 @@ let results = cache.list( ); ``` -#### ๐ŸŽฏ **Memory Prefetch Hints** -- **Cache Line Optimization**: Provides hints to CPU about upcoming memory accesses -- **Sequential Access Patterns**: Optimized for list operations and iteration -- **Reduced Latency**: Minimizes memory access delays through predictive loading -- **Intelligent Prefetching**: Only prefetches when beneficial (64-byte cache line alignment) - -```rust -// Prefetch hints are automatically applied during operations -let items = cache.list(ListProps::default()); // Prefetch optimized -``` - #### ๐Ÿ“Š **TTL Timestamp Caching** - **Syscall Reduction**: Caches `SystemTime::now()` calls to reduce kernel overhead - **Lazy Evaluation**: Only checks expiration when items are actually accessed @@ -569,7 +557,6 @@ cache.insert_with_ttl("session", "data", Duration::from_secs(300)); | Feature | Primary Benefit | Performance Gain | Use Case | |---------|----------------|------------------|----------| | **Optimized Filters** | Algorithm efficiency | 10-15% faster filtering | Large dataset operations | -| **Prefetch Hints** | Cache locality | 5-10% faster access | Sequential operations | | **TTL Caching** | Syscall reduction | 25-30% faster TTL ops | Time-sensitive applications | | **IndexMap** | Memory layout | 5-8% faster iteration | Frequent list operations | @@ -691,7 +678,7 @@ test result: ok. 36 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out - โœ… **Event System**: Real-time notifications and event handling - โœ… **LRU Eviction**: Capacity management and least-recently-used removal - โœ… **Persistence**: SQLite integration, crash recovery, TTL preservation -- โœ… **Performance Features**: Optimized filters, prefetch hints, optimization validation +- โœ… **Performance Features**: Optimized filters and optimization validation - โœ… **Concurrency**: Thread safety, parallel test execution - โœ… **Edge Cases**: Error handling, boundary conditions, memory management - โœ… **Cross-Platform**: Linux, Windows, macOS compatibility @@ -716,7 +703,6 @@ cargo bench # Test specific optimization features cargo test fast_filters -cargo test prefetch ``` All tests are designed to run reliably in parallel environments with proper isolation to prevent interference between test executions. @@ -728,7 +714,6 @@ All tests are designed to run reliably in parallel environments with proper isol Quickleaf v0.4+ includes advanced performance optimizations that deliver significant speed improvements: - **Optimized String Filters**: Fast prefix and suffix matching algorithms -- **Memory Prefetch**: CPU cache optimization hints - **Efficient Data Structures**: IndexMap for better memory layout - **TTL Optimization**: Cached timestamps and lazy cleanup @@ -738,10 +723,10 @@ Quickleaf v0.4+ includes advanced performance optimizations that deliver signifi | Operation | Time Complexity | Optimized Performance | Notes | |-----------|----------------|-----------------------|-------| -| Insert | O(log n) | **Up to 48% faster** | Memory optimization + prefetch + IndexMap | -| Get | O(1) | **25-36% faster** | Optimized filters + memory optimization + prefetch | +| Insert | O(log n) | **Up to 48% faster** | Memory optimization + IndexMap | +| Get | O(1) | **25-36% faster** | Optimized filters + memory optimization | | Remove | O(n) | **~5% faster** | Optimized memory layout | -| List | O(n) | **3-6% faster** | Optimized filters + prefetch hints | +| List | O(n) | **3-6% faster** | Optimized filters | | TTL Check | O(1) | **Minimal overhead** | Cached timestamps | | Contains Key | O(1) | **1-6% faster** | IndexMap + memory layout benefits | @@ -877,4 +862,4 @@ This project is licensed under the Apache 2.0 License - see the [LICENSE](LICENS **Made with โค๏ธ by the [phlow.dev](https://phlow.dev) team** -*Quickleaf v0.4+ features advanced performance optimizations including optimized string filters, memory prefetch hints, and TTL optimization - delivering up to 48% performance improvements while maintaining full API compatibility.* +*Quickleaf v0.4+ features advanced performance optimizations including optimized string filters and TTL optimization - delivering up to 48% performance improvements while maintaining full API compatibility.* diff --git a/README.md.backup b/README.md.backup deleted file mode 100644 index 9ab0fbb..0000000 --- a/README.md.backup +++ /dev/null @@ -1,885 +0,0 @@ -# ๐Ÿƒ Quickleaf Cache - -[![Crates.io](https://img.shields.io/crates/v/quickleaf.svg)](https://crates.io/crates/quickleaf) -[![License](https://img.shields.io/crates/l/quickleaf.svg)](https://github.com/phlowdotdev/quickleaf/blob/main/LICENSE) -[![Documentation](https://docs.rs/quickleaf/badge.svg)](https://docs.rs/quickleaf) - -Quickleaf Cache is a **fast**, **lightweight**, and **feature-rich** in-memory cache library for Rust. It combines the simplicity of a HashMap with advanced caching features like **TTL (Time To Live)**, **filtering**, **ordering**, and **event notifications**. - -## โœจ Features - -- ๐Ÿš€ **High Performance**: O(1) access with ordered key iteration -- โšก **Advanced Optimizations**: Optimized string filters and memory prefetch hints -- ๐Ÿ“ˆ **Performance Gains**: Up to 48% faster operations compared to standard implementations -- โฐ **TTL Support**: Automatic expiration with lazy cleanup -- ๐Ÿ” **Advanced Filtering**: StartWith, EndWith, and complex pattern matching with optimized algorithms -- ๐Ÿ“‹ **Flexible Ordering**: Ascending/descending with pagination support -- ๐Ÿ”” **Event Notifications**: Real-time cache operation events -- ๐ŸŽฏ **LRU Eviction**: Automatic removal of least recently used items -- ๐Ÿ’พ **Persistent Storage**: Optional SQLite-backed persistence for durability -- ๐Ÿ›ก๏ธ **Type Safety**: Full Rust type safety with generic value support -- ๐Ÿ“ฆ **Lightweight**: Minimal external dependencies -- ๐Ÿง  **Memory Optimized**: Efficient memory layout and usage patterns - -## ๐Ÿ“ฆ Installation - -Add the following to your `Cargo.toml`: - -```toml -[dependencies] -quickleaf = "0.4" - -# For persistence support (optional) -quickleaf = { version = "0.4", features = ["persist"] } -``` - -## ๐Ÿš€ Quick Start - -```rust -use quickleaf::{Quickleaf, Duration}; - -fn main() { - // Create a cache with capacity of 1000 items - let mut cache = Quickleaf::new(1000); - - // Insert some data - cache.insert("user:123", "Alice"); - cache.insert("user:456", "Bob"); - - // Retrieve data - println!("{:?}", cache.get("user:123")); // Some("Alice") - - // Insert with TTL (expires in 60 seconds) - cache.insert_with_ttl("session:abc", "temp_data", Duration::from_secs(60)); -} -``` - -## ๐Ÿ“– Usage Examples - -### Basic Operations - -```rust -use quickleaf::Quickleaf; - -fn main() { - let mut cache = Quickleaf::new(5); - - // Insert data - cache.insert("apple", 100); - cache.insert("banana", 200); - cache.insert("cherry", 300); - - // Get data - println!("{:?}", cache.get("apple")); // Some(100) - - // Check if key exists - assert!(cache.contains_key("banana")); - - // Remove data - cache.remove("cherry").unwrap(); - - // Cache info - println!("Cache size: {}", cache.len()); - println!("Is empty: {}", cache.is_empty()); -} -``` - -### ๐Ÿ•’ TTL (Time To Live) Features - -#### Default TTL for All Items - -```rust -use quickleaf::{Quickleaf, Duration}; - -fn main() { - // Create cache where all items expire after 5 minutes by default - let mut cache = Quickleaf::with_default_ttl(100, Duration::from_secs(300)); - - // This item will use the default TTL (5 minutes) - cache.insert("default_ttl", "expires in 5 min"); - - // This item has custom TTL (30 seconds) - cache.insert_with_ttl("custom_ttl", "expires in 30 sec", Duration::from_secs(30)); - - // Items expire automatically when accessed - // After 30+ seconds, custom_ttl will return None - println!("{:?}", cache.get("custom_ttl")); -} -``` - -#### Manual Cleanup - -```rust -use quickleaf::{Quickleaf, Duration}; -use std::thread; - -fn main() { - let mut cache = Quickleaf::new(10); - - // Add items with short TTL for demo - cache.insert_with_ttl("temp1", "data1", Duration::from_millis(100)); - cache.insert_with_ttl("temp2", "data2", Duration::from_millis(100)); - cache.insert("permanent", "data3"); // No TTL - - println!("Initial size: {}", cache.len()); // 3 - - // Wait for items to expire - thread::sleep(Duration::from_millis(150)); - - // Manual cleanup of expired items - let removed_count = cache.cleanup_expired(); - println!("Removed {} expired items", removed_count); // 2 - println!("Final size: {}", cache.len()); // 1 -} -``` - -### ๐Ÿ” Advanced Filtering - -#### Filter by Prefix - -```rust -use quickleaf::{Quickleaf, ListProps, Order, Filter}; - -fn main() { - let mut cache = Quickleaf::new(10); - cache.insert("user:123", "Alice"); - cache.insert("user:456", "Bob"); - cache.insert("product:789", "Widget"); - cache.insert("user:999", "Charlie"); - - // Get all users (keys starting with "user:") - let users = cache.list( - ListProps::default() - .filter(Filter::StartWith("user:".to_string())) - .order(Order::Asc) - ).unwrap(); - - for (key, value) in users { - println!("{}: {}", key, value); - } -} -``` - -#### Filter by Suffix - -```rust -use quickleaf::{Quickleaf, ListProps, Filter}; - -fn main() { - let mut cache = Quickleaf::new(10); - cache.insert("config.json", "{}"); - cache.insert("data.json", "[]"); - cache.insert("readme.txt", "docs"); - cache.insert("settings.json", "{}"); - - // Get all JSON files - let json_files = cache.list( - ListProps::default() - .filter(Filter::EndWith(".json".to_string())) - ).unwrap(); - - println!("JSON files found: {}", json_files.len()); // 3 -} -``` - -#### Complex Pattern Filtering - -```rust -use quickleaf::{Quickleaf, ListProps, Filter, Order}; - -fn main() { - let mut cache = Quickleaf::new(10); - cache.insert("cache_user_data", "user1"); - cache.insert("cache_product_info", "product1"); - cache.insert("temp_user_session", "session1"); - cache.insert("cache_user_preferences", "prefs1"); - - // Get cached user data (starts with "cache_" and ends with "_data") - let cached_user_data = cache.list( - ListProps::default() - .filter(Filter::StartAndEndWith("cache_".to_string(), "_data".to_string())) - .order(Order::Desc) - ).unwrap(); - - for (key, value) in cached_user_data { - println!("{}: {}", key, value); - } -} -``` - -### ๐Ÿ“‹ Pagination and Ordering - -```rust -use quickleaf::{Quickleaf, ListProps, Order}; - -fn main() { - let mut cache = Quickleaf::new(100); - - // Add some test data - for i in 1..=20 { - cache.insert(format!("item_{:02}", i), i); - } - - // Get first 5 items in ascending order - let page1 = cache.list( - ListProps::default() - .order(Order::Asc) - ).unwrap(); - - println!("First 5 items:"); - for (i, (key, value)) in page1.iter().take(5).enumerate() { - println!(" {}: {} = {}", i+1, key, value); - } - - // Get top 3 items in descending order - let desc_items = cache.list( - ListProps::default() - .order(Order::Desc) - ).unwrap(); - - println!("Top 3 items (desc):"); - for (key, value) in desc_items.iter().take(3) { - println!(" {}: {}", key, value); - } -} -``` - -### ๐Ÿ’พ Persistent Cache (SQLite Backend) - -Quickleaf supports optional persistence using SQLite as a backing store. This provides durability across application restarts while maintaining the same high-performance in-memory operations. - -#### Complete Example with All Features - -```rust -use quickleaf::{Cache, Duration}; -use std::sync::mpsc::channel; - -fn main() -> Result<(), Box> { - let (tx, rx) = channel(); - - // Create cache with ALL features: persistence, events, and TTL - let mut cache = Cache::with_persist_and_sender_and_ttl( - "full_featured.db", - 1000, - tx, - Duration::from_secs(3600) // 1 hour default TTL - )?; - - // Insert data - it will be: - // 1. Persisted to SQLite - // 2. Send events to the channel - // 3. Expire after 1 hour (default TTL) - cache.insert("session:user123", "active"); - - // Override default TTL for specific items - cache.insert_with_ttl( - "temp:token", - "xyz789", - Duration::from_secs(60) // 1 minute instead of 1 hour - ); - - // Process events - for event in rx.try_iter() { - println!("Event received: {:?}", event); - } - - Ok(()) -} -``` - -#### Basic Persistent Cache - -```rust -use quickleaf::Cache; - -fn main() -> Result<(), Box> { - // Create a persistent cache backed by SQLite - let mut cache = Cache::with_persist("cache.db", 1000)?; - - // Insert data - automatically persisted - cache.insert("user:123", "Alice"); - cache.insert("user:456", "Bob"); - - // Data survives application restart - drop(cache); - - // Later or after restart... - let mut cache = Cache::with_persist("cache.db", 1000)?; - - // Data is still available - println!("{:?}", cache.get("user:123")); // Some("Alice") - - Ok(()) -} -``` - -#### Persistent Cache with TTL - -```rust -use quickleaf::{Cache, Duration}; - -fn main() -> Result<(), Box> { - // Option 1: Use with_persist and insert items with individual TTL - let mut cache = Cache::with_persist("cache.db", 1000)?; - cache.insert_with_ttl( - "session:abc", - "temp_data", - Duration::from_secs(3600) - ); - - // Option 2: Use with_persist_and_ttl for default TTL on all items - let mut cache_with_default = Cache::with_persist_and_ttl( - "cache_with_ttl.db", - 1000, - Duration::from_secs(300) // 5 minutes default TTL - )?; - - // This item will use the default TTL (5 minutes) - cache_with_default.insert("auto_expire", "data"); - - // You can still override with custom TTL - cache_with_default.insert_with_ttl( - "custom_expire", - "data", - Duration::from_secs(60) // 1 minute instead of default 5 - ); - - // TTL is preserved across restarts - // Expired items are automatically cleaned up on load - - Ok(()) -} -``` - -#### Persistence Features - -- **Automatic Persistence**: All cache operations are automatically persisted -- **Background Writer**: Non-blocking write operations using a background thread -- **Crash Recovery**: Automatic recovery from unexpected shutdowns -- **TTL Preservation**: TTL values are preserved across restarts -- **Efficient Storage**: Uses SQLite with optimized indexes for performance -- **Compatibility**: Works seamlessly with all existing Quickleaf features - -#### Available Persistence Constructors - -| Constructor | Description | Use Case | -|------------|-------------|----------| -| `with_persist(path, capacity)` | Basic persistent cache | Simple persistence without events | -| `with_persist_and_ttl(path, capacity, ttl)` | Persistent cache with default TTL | Session stores, temporary data with persistence | -| `with_persist_and_sender(path, capacity, sender)` | Persistent cache with events | Monitoring, logging, real-time updates | -| `with_persist_and_sender_and_ttl(path, capacity, sender, ttl)` | Full-featured persistent cache | Complete solution with all features | - -### ๐Ÿ”” Event Notifications - -```rust -use quickleaf::{Quickleaf, Event}; -use std::sync::mpsc::channel; -use std::thread; - -fn main() { - let (tx, rx) = channel(); - let mut cache = Quickleaf::with_sender(10, tx); - - // Spawn a thread to handle events - let event_handler = thread::spawn(move || { - for event in rx { - match event { - Event::Insert(data) => { - println!("โž• Inserted: {} = {}", data.key, data.value); - } - Event::Remove(data) => { - println!("โž– Removed: {} = {}", data.key, data.value); - } - Event::Clear => { - println!("๐Ÿ—‘๏ธ Cache cleared"); - } - } - } - }); - - // Perform cache operations (will trigger events) - cache.insert("user:1", "Alice"); - cache.insert("user:2", "Bob"); - cache.remove("user:1").unwrap(); - cache.clear(); - - // Close the sender to stop the event handler - drop(cache); - event_handler.join().unwrap(); -} -``` - -### ๐Ÿ”„ Combined Features Example - -```rust -use quickleaf::{Quickleaf, Duration, ListProps, Filter, Order}; -use std::thread; - -fn main() { - // Create cache with default TTL and event notifications - let (tx, _rx) = std::sync::mpsc::channel(); - let mut cache = Quickleaf::with_sender_and_ttl(50, tx, Duration::from_secs(300)); - - // Insert user sessions with custom TTLs - cache.insert_with_ttl("session:guest", "temporary", Duration::from_secs(30)); - cache.insert_with_ttl("session:user123", "authenticated", Duration::from_secs(3600)); - cache.insert("config:theme", "dark"); // Uses default TTL - cache.insert("config:lang", "en"); // Uses default TTL - - // Get all active sessions - let sessions = cache.list( - ListProps::default() - .filter(Filter::StartWith("session:".to_string())) - .order(Order::Asc) - ).unwrap(); - - println!("Active sessions: {}", sessions.len()); - - // Simulate time passing - thread::sleep(Duration::from_secs(35)); - - // Guest session should be expired now - println!("Guest session: {:?}", cache.get("session:guest")); // None - println!("User session: {:?}", cache.get("session:user123")); // Some(...) - - // Manual cleanup - let expired_count = cache.cleanup_expired(); - println!("Cleaned up {} expired items", expired_count); -} -``` - -## ๐Ÿ—๏ธ Architecture - -### Cache Structure - -Quickleaf uses a dual-structure approach for optimal performance: - -- **HashMap**: O(1) key-value access -- **Vec**: Maintains sorted key order for efficient iteration -- **Lazy Cleanup**: TTL items are removed when accessed, not proactively -- **SQLite Backend** (optional): Provides durable storage with background persistence - -### TTL Strategy - -- **Lazy Cleanup**: Expired items are removed during access operations (`get`, `contains_key`, `list`) -- **Manual Cleanup**: Use `cleanup_expired()` for proactive cleaning -- **No Background Threads**: Zero overhead until items are accessed (except for optional persistence) - -### Persistence Architecture (Optional) - -When persistence is enabled: - -- **In-Memory First**: All operations work on the in-memory cache for speed -- **Background Writer**: A separate thread handles SQLite writes asynchronously -- **Event-Driven**: Cache operations trigger persistence events -- **Auto-Recovery**: On startup, cache is automatically restored from SQLite -- **Expired Cleanup**: Expired items are filtered out during load - -## โšก Advanced Performance Optimizations - -Quickleaf includes cutting-edge performance optimizations that deliver significant speed improvements: - -### โšก Next-Generation Optimizations - -Quickleaf v0.4+ includes advanced performance optimizations that deliver significant speed improvements: - -- **Optimized String Filters**: Fast prefix and suffix matching algorithms -- **Memory Prefetch**: CPU cache optimization hints -- **Efficient Data Structures**: IndexMap for better memory layout -- **TTL Optimization**: Cached timestamps and lazy cleanup - -**Performance Gains**: 5-36% improvement across all operations compared to previous versions. - -These optimizations are **transparent** to the API - all existing code continues to work while automatically benefiting from the performance improvements. - -## ๏ฟฝ Technical Features & Optimizations - -### Core Optimization Technologies - -#### ๐Ÿง  **String Pooling System** -- **Smart Memory Management**: Automatically pools and reuses small strings (< 64 bytes by default) -- **Fragmentation Reduction**: Minimizes heap fragmentation through strategic allocation reuse -- **Configurable Thresholds**: Adjustable pool size and string length limits -- **Zero-Copy When Possible**: Reuses existing allocations without additional copying - -```rust -## ๐Ÿ”ง API Reference -``` - -#### โšก **SIMD Acceleration** -- **Vectorized Pattern Matching**: Uses CPU SIMD instructions (SSE2, AVX) for string operations -- **Automatic Detection**: Runtime detection of CPU capabilities with safe fallbacks -- **Optimized Algorithms**: Custom prefix/suffix matching algorithms for large text processing -- **Cross-Platform**: Works on x86/x86_64 with graceful degradation on ARM/other architectures - -```rust -// SIMD acceleration is automatic in filter operations -let results = cache.list( - ListProps::default() - .filter(Filter::StartWith("user:".to_string())) // Uses SIMD if available -); -``` - -#### ๐ŸŽฏ **Memory Prefetch Hints** -- **Cache Line Optimization**: Provides hints to CPU about upcoming memory accesses -- **Sequential Access Patterns**: Optimized for list operations and iteration -- **Reduced Latency**: Minimizes memory access delays through predictive loading -- **Intelligent Prefetching**: Only prefetches when beneficial (64-byte cache line alignment) - -```rust -// Prefetch hints are automatically applied during operations -let items = cache.list(ListProps::default()); // Prefetch optimized -``` - -#### ๐Ÿ“Š **TTL Timestamp Caching** -- **Syscall Reduction**: Caches `SystemTime::now()` calls to reduce kernel overhead -- **Lazy Evaluation**: Only checks expiration when items are actually accessed -- **Batch Operations**: Optimized cleanup process for multiple expired items -- **High-Resolution Timing**: Nanosecond precision for accurate TTL handling - -```rust -// TTL optimization is transparent -cache.insert_with_ttl("session", "data", Duration::from_secs(300)); -// Subsequent access optimized with cached timestamps -``` - -#### ๐Ÿ—‚๏ธ **IndexMap Integration** -- **Ordered Performance**: Maintains insertion order while preserving O(1) access complexity -- **Memory Layout**: Contiguous memory allocation improves CPU cache performance -- **Iterator Efficiency**: Faster traversal due to better data locality -- **Hybrid Approach**: Combines HashMap speed with Vec-like iteration performance - -### Advanced Capabilities - -#### ๏ฟฝ๐Ÿ”ง **Automatic Performance Scaling** -- **Adaptive Algorithms**: Automatically chooses optimal algorithms based on data size -- **Threshold-Based Switching**: Uses different strategies for small vs. large datasets -- **CPU Feature Detection**: Runtime detection and utilization of available CPU features -- **Memory-Aware Operations**: Considers available memory for optimal performance - -#### ๐Ÿ›ก๏ธ **Zero-Cost Abstractions** -- **Compile-Time Optimization**: Rust's zero-cost abstractions ensure no runtime overhead -- **Inlining**: Critical path functions are inlined for maximum performance -- **Branch Prediction**: Optimized code paths for common operations -- **Generic Specialization**: Type-specific optimizations where beneficial - -#### ๐Ÿ“ˆ **Benchmark-Driven Development** -- **Continuous Performance Testing**: All optimizations validated through comprehensive benchmarks -- **Regression Detection**: Performance monitoring to prevent slowdowns -- **Real-World Workloads**: Benchmarks based on actual use cases and patterns -- **Cross-Platform Validation**: Performance testing across different architectures and systems - -### Performance Characteristics by Feature - -| Feature | Primary Benefit | Performance Gain | Use Case | -|---------|----------------|------------------|----------| -| **Optimized Filters** | Algorithm efficiency | 10-15% faster filtering | Large dataset operations | -| **Prefetch Hints** | Cache locality | 5-10% faster access | Sequential operations | -| **TTL Caching** | Syscall reduction | 25-30% faster TTL ops | Time-sensitive applications | -| **IndexMap** | Memory layout | 5-8% faster iteration | Frequent list operations | - -### Compatibility & Fallbacks - -- **Graceful Degradation**: All optimizations have safe fallbacks for unsupported systems -- **API Compatibility**: Zero breaking changes - all optimizations are transparent -- **Feature Detection**: Runtime detection of CPU capabilities -- **Cross-Platform**: Works on Windows, Linux, macOS, and other platforms -- **Architecture Support**: Optimized for x86_64, with fallbacks for ARM and other architectures - -These optimizations are **transparent** to the API - all existing code continues to work while automatically benefiting from the performance improvements. - -## ๐Ÿ”ง API Reference - -## ๐Ÿ”ง API Reference - -### Cache Creation - -```rust -// Basic cache -let cache = Quickleaf::new(capacity); - -// With default TTL -let cache = Quickleaf::with_default_ttl(capacity, ttl); - -// With event notifications -let cache = Quickleaf::with_sender(capacity, sender); - -// With both TTL and events -let cache = Quickleaf::with_sender_and_ttl(capacity, sender, ttl); - -// With persistence (requires "persist" feature) -let cache = Cache::with_persist("cache.db", capacity)?; - -// With persistence and default TTL -let cache = Cache::with_persist_and_ttl("cache.db", capacity, ttl)?; - -// With persistence and events -let cache = Cache::with_persist_and_sender("cache.db", capacity, sender)?; - -// With persistence, events, and TTL (all features) -let cache = Cache::with_persist_and_sender_and_ttl("cache.db", capacity, sender, ttl)?; -``` - -### Core Operations - -```rust -// Insert operations -cache.insert(key, value); -cache.insert_with_ttl(key, value, ttl); - -// Access operations -cache.get(key); // Returns Option<&Value> -cache.get_mut(key); // Returns Option<&mut Value> -cache.contains_key(key); // Returns bool - -// Removal operations -cache.remove(key); // Returns Result<(), Error> -cache.clear(); // Removes all items - -// TTL operations -cache.cleanup_expired(); // Returns count of removed items -cache.set_default_ttl(ttl); -cache.get_default_ttl(); -``` - -### Filtering and Listing - -```rust -// List operations -cache.list(props); // Returns Result, Error> - -// Filter types -Filter::None -Filter::StartWith(prefix) -Filter::EndWith(suffix) -Filter::StartAndEndWith(prefix, suffix) - -// Ordering -Order::Asc // Ascending -Order::Desc // Descending -``` - -## ๐Ÿงช Testing - -Run the test suite: - -```bash -# All tests -cargo test - -# TTL-specific tests -cargo test ttl - -# Persistence tests (requires "persist" feature) -cargo test persist - -# Performance tests -cargo test --release - -# With output -cargo test -- --nocapture -``` - -### Test Results - -โœ… **All 36 tests passing** (as of August 2025) - -``` -test result: ok. 36 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out -``` - -**Comprehensive Test Coverage includes:** -- โœ… **Core Operations**: Insert, get, remove, clear operations -- โœ… **TTL Functionality**: Expiration, cleanup, lazy evaluation -- โœ… **Advanced Filtering**: Prefix, suffix, complex pattern matching with optimized algorithms -- โœ… **List Operations**: Ordering, pagination, filtering combinations -- โœ… **Event System**: Real-time notifications and event handling -- โœ… **LRU Eviction**: Capacity management and least-recently-used removal -- โœ… **Persistence**: SQLite integration, crash recovery, TTL preservation -- โœ… **Performance Features**: Optimized filters, prefetch hints, optimization validation -- โœ… **Concurrency**: Thread safety, parallel test execution -- โœ… **Edge Cases**: Error handling, boundary conditions, memory management -- โœ… **Cross-Platform**: Linux, Windows, macOS compatibility -- โœ… **Cross-Platform**: Linux, Windows, macOS compatibility - -### Test Categories - -| Category | Tests | Description | -|----------|-------|-------------| -| **Core Cache** | 8 tests | Basic CRUD operations | -| **TTL System** | 8 tests | Time-based expiration | -| **Filtering** | 4 tests | Pattern matching and optimized algorithms | -| **Persistence** | 14 tests | SQLite integration | -| **Events** | 2 tests | Notification system | -| **Performance** | 6 tests | Optimization validation | - -### Performance Test Suite - -```bash -# Run benchmarks to validate optimizations -cargo bench - -# Test specific optimization features -cargo test fast_filters -cargo test prefetch -``` - -All tests are designed to run reliably in parallel environments with proper isolation to prevent interference between test executions. - -## ๐Ÿ“Š Performance - -### โšก Next-Generation Optimizations - -Quickleaf v0.4+ includes advanced performance optimizations that deliver significant speed improvements: - -- **Optimized String Filters**: Fast prefix and suffix matching algorithms -- **Memory Prefetch**: CPU cache optimization hints -- **Efficient Data Structures**: IndexMap for better memory layout -- **TTL Optimization**: Cached timestamps and lazy cleanup - -**Performance Gains**: 5-36% improvement across all operations compared to previous versions. - -### Benchmarks - -| Operation | Time Complexity | Optimized Performance | Notes | -|-----------|----------------|-----------------------|-------| -| Insert | O(log n) | **Up to 48% faster** | Memory optimization + prefetch + IndexMap | -| Get | O(1) | **25-36% faster** | Optimized filters + memory optimization + prefetch | -| Remove | O(n) | **~5% faster** | Optimized memory layout | -| List | O(n) | **3-6% faster** | Optimized filters + prefetch hints | -| TTL Check | O(1) | **Minimal overhead** | Cached timestamps | -| Contains Key | O(1) | **1-6% faster** | IndexMap + memory layout benefits | - -### Real-World Performance Results - -#### Test Environment -- **OS**: Linux (optimized build) -- **CPU**: Modern x86_64 architecture -- **RAM**: 16GB+ -- **Rust**: 1.87.0 -- **Date**: August 2025 - -#### Benchmark Results (v0.4 with Advanced Optimizations) - -| Operation | Cache Size | Time (v0.4) | Time (v0.3) | Notes | -|-----------|------------|------|----------|-------------|-------| -| **Get** | 10 | **73.9ns** | 108ns | Memory and filter optimization | -| **Get** | 100 | **78.4ns** | 123ns | Excellent scaling with optimizations | -| **Get** | 1,000 | **79.7ns** | 107ns | Consistent sub-80ns performance | -| **Get** | 10,000 | **106.7ns** | 109ns | Maintains performance at scale | -| **Insert** | 10 | **203.4ns** | 302ns | Memory optimization benefits | -| **Insert** | 100 | **230.6ns** | 350ns | Memory optimization impact | -| **Insert** | 1,000 | **234.1ns** | 378ns | Significant improvement | -| **Insert** | 10,000 | **292.3ns** | 566ns | Dramatic performance gain | -| **Contains Key** | 10 | **33.6ns** | 35ns | IndexMap benefits | -| **Contains Key** | 100 | **34.9ns** | 37ns | Consistent improvement | -| **Contains Key** | 1,000 | **36.8ns** | 37ns | Maintained performance | -| **Contains Key** | 10,000 | **47.4ns** | 49ns | Scaling improvement | -| **List (no filter)** | 1,000 items | **28.6ยตs** | 30.4ยตs | Optimized filters + memory optimization | -| **List (prefix filter)** | 1,000 items | **28.0ยตs** | 29.1ยตs | Optimized prefix matching | -| **List (suffix filter)** | 1,000 items | **41.1ยตs** | 42.2ยตs | Optimized suffix matching | -| **LRU Eviction** | 100 capacity | **609ns** | 613ns | Memory layout benefits | -| **Insert with TTL** | Any | **97.6ns** | 98ns | Timestamp caching | -| **Cleanup Expired** | 500 items | **339ns** | 338ns | Optimized batch processing | -| **Get (TTL check)** | Any | **73.9ns** | 71ns | Efficient TTL validation | - -**Real-World Impact**: The optimizations deliver the most significant benefits in production workloads with: -- Large cache sizes (1,000+ items) -- Frequent insert operations -- Pattern-heavy filtering operations -- Memory-constrained environments - -### Memory Usage (Optimized) - -- **Base overhead**: ~48 bytes per cache instance -- **Per item**: ~(key_size + value_size + 48) bytes (efficient memory layout) -- **TTL overhead**: +24 bytes per item with TTL -- **Memory efficiency**: Optimized data structures reduce overhead -- **IndexMap advantage**: Better cache locality, **10-15% faster** iterations - -## ๐Ÿ“š Examples - -Check out the `examples/` directory for more comprehensive examples: - -```bash -# Run the TTL example -cargo run --example ttl_example - -# Run the persistence example -cargo run --example test_persist --features persist - -# Run the interactive TUI with persistence -cargo run --example tui_interactive --features tui-example -``` - -## ๐Ÿค Contributing - -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. - -### Development - -```bash -# Clone the repository -git clone https://github.com/phlowdotdev/quickleaf.git -cd quickleaf - -# Run tests -cargo test - -# Run examples -cargo run --example ttl_example - -# Run benchmarks to validate optimizations -cargo bench - -# Check formatting -cargo fmt --check - -# Run clippy -cargo clippy -- -D warnings - -# Test with all features -cargo test --all-features -``` - -### Performance Development - -When contributing performance improvements: - -```bash -# Benchmark before changes -cargo bench > before.txt - -# Make your changes... - -# Benchmark after changes -cargo bench > after.txt - -# Compare results -# Ensure no regressions and document improvements -``` - -### Optimization Guidelines - -- **Measure First**: Always benchmark before and after changes -- **Maintain Compatibility**: New optimizations should not break existing APIs -- **Document Benefits**: Include performance impact in pull request descriptions -- **Test Thoroughly**: Ensure optimizations work across different platforms -- **Graceful Fallbacks**: Provide safe alternatives for unsupported systems - -## ๐Ÿ“„ License - -This project is licensed under the Apache 2.0 License - see the [LICENSE](LICENSE) file for details. - -## ๐Ÿ”— Links - -- [Documentation](https://docs.rs/quickleaf) -- [Crates.io](https://crates.io/crates/quickleaf) -- [Repository](https://github.com/phlowdotdev/quickleaf) -- [Issues](https://github.com/phlowdotdev/quickleaf/issues) - ---- - -**Made with โค๏ธ by the [phlow.dev](https://phlow.dev) team** - -*Quickleaf v0.4+ features advanced performance optimizations including optimized string filters, memory prefetch hints, and TTL optimization - delivering up to 48% performance improvements while maintaining full API compatibility.* diff --git a/examples/cache_performance_analysis.rs b/examples/cache_performance_analysis.rs new file mode 100644 index 0000000..a5eb4f3 --- /dev/null +++ b/examples/cache_performance_analysis.rs @@ -0,0 +1,127 @@ +use std::time::Instant; +use quickleaf::Cache; + +fn main() { + println!("Testing real-world cache performance scenarios..."); + + // Test 1: Random access patterns (where prefetch should hurt) + test_random_access(); + + // Test 2: Sequential access patterns (where prefetch should help) + test_sequential_access(); + + // Test 3: Large cache list operations + test_large_list_operations(); + + // Test 4: Cleanup operations with many expired items + test_cleanup_operations(); +} + +fn test_random_access() { + println!("\n--- Random Access Test ---"); + let mut cache = Cache::new(10000); + + // Pre-populate with 10k items + for i in 0..10000 { + cache.insert(format!("item{:05}", i), format!("value{}", i)); + } + + // Random access pattern + let mut rng_seed = 42u64; + let iterations = 100000; + + let start = Instant::now(); + for _ in 0..iterations { + // Simple LCG for reproducible "random" numbers + rng_seed = rng_seed.wrapping_mul(1664525).wrapping_add(1013904223); + let index = (rng_seed % 10000) as usize; + let key = format!("item{:05}", index); + std::hint::black_box(cache.get(&key)); + } + let duration = start.elapsed(); + + println!("Random access ({} ops): {:?}", iterations, duration); + println!("Average per access: {:?}", duration / iterations); +} + +fn test_sequential_access() { + println!("\n--- Sequential Access Test ---"); + let mut cache = Cache::new(10000); + + // Pre-populate + for i in 0..10000 { + cache.insert(format!("seq{:05}", i), format!("value{}", i)); + } + + let iterations = 10; + + let start = Instant::now(); + for _ in 0..iterations { + // Sequential access through the entire cache + for i in 0..10000 { + let key = format!("seq{:05}", i); + std::hint::black_box(cache.get(&key)); + } + } + let duration = start.elapsed(); + + println!("Sequential access ({} full sweeps): {:?}", iterations, duration); + println!("Average per access: {:?}", duration / (iterations * 10000)); +} + +fn test_large_list_operations() { + println!("\n--- Large List Operations Test ---"); + let mut cache = Cache::new(50000); + + // Pre-populate with 50k items + for i in 0..50000 { + cache.insert(format!("list{:06}", i), i); + } + + let iterations = 100; + + let start = Instant::now(); + for _ in 0..iterations { + let mut props = quickleaf::ListProps::default(); + props.limit = 1000; // Get 1000 items each time + std::hint::black_box(cache.list(props).unwrap()); + } + let duration = start.elapsed(); + + println!("List operations ({} iterations, 1000 items each): {:?}", iterations, duration); + println!("Average per list operation: {:?}", duration / iterations); +} + +fn test_cleanup_operations() { + println!("\n--- Cleanup Operations Test ---"); + let mut cache = Cache::new(20000); + + // Pre-populate with mix of expired and valid items + for i in 0..10000 { + // Add expired items (very short TTL) + cache.insert_with_ttl( + format!("expired{:05}", i), + format!("value{}", i), + std::time::Duration::from_nanos(1) + ); + } + + // Add some valid items + for i in 10000..20000 { + cache.insert(format!("valid{:05}", i), format!("value{}", i)); + } + + // Wait a bit to ensure expiration + std::thread::sleep(std::time::Duration::from_millis(1)); + + let iterations = 1000; + + let start = Instant::now(); + for _ in 0..iterations { + std::hint::black_box(cache.cleanup_expired()); + } + let duration = start.elapsed(); + + println!("Cleanup operations ({} iterations): {:?}", iterations, duration); + println!("Average per cleanup: {:?}", duration / iterations); +} diff --git a/src/cache.rs b/src/cache.rs index 97a6828..028fa0b 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -2,7 +2,6 @@ use crate::error::Error; use crate::event::Event; use crate::filters::apply_filter_fast; use crate::list_props::{ListProps, Order, StartAfter}; -use crate::prefetch::{Prefetch, PrefetchExt}; use indexmap::IndexMap; use std::fmt::Debug; use std::sync::mpsc::Sender; @@ -790,10 +789,6 @@ impl Cache { /// ``` #[inline] pub fn get(&mut self, key: &str) -> Option<&Value> { - if let Some((_, item)) = self.map.get_key_value(key) { - item.prefetch_read(); - } - let is_expired = match self.map.get(key) { Some(item) => { if let Some(ttl) = item.ttl_millis { @@ -935,8 +930,6 @@ impl Cache { let mut expired_keys = Vec::with_capacity(self.map.len() / 4); for (key, item) in &self.map { - item.prefetch_read(); - if let Some(ttl) = item.ttl_millis { if (current_time - item.created_at) > ttl { expired_keys.push(key.clone()); @@ -946,10 +939,6 @@ impl Cache { let removed_count = expired_keys.len(); - if !expired_keys.is_empty() { - Prefetch::sequential_read_hints(expired_keys.as_ptr(), expired_keys.len()); - } - for key in expired_keys { if let Some(item) = self.map.swap_remove(&key) { self.send_remove(key, item.value); @@ -1008,10 +997,6 @@ impl Cache { let mut keys: Vec = self.map.keys().cloned().collect(); keys.sort(); - if !keys.is_empty() { - Prefetch::sequential_read_hints(keys.as_ptr(), keys.len()); - } - match props.order { Order::Asc => self.resolve_order(keys.iter(), props), Order::Desc => self.resolve_order(keys.iter().rev(), props), diff --git a/src/cache_no_prefetch.rs b/src/cache_no_prefetch.rs new file mode 100644 index 0000000..528a9b4 --- /dev/null +++ b/src/cache_no_prefetch.rs @@ -0,0 +1,246 @@ +//! Cache implementation without prefetch hints for performance comparison + +use crate::error::Error; +use crate::event::Event; +use crate::filter::Filter; +use crate::list_props::{ListProps, Order}; +use indexmap::IndexMap; +use std::fmt::{self, Debug}; +use std::sync::mpsc::Sender; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; + +#[derive(Debug, Clone)] +pub struct CacheItem { + pub(crate) value: T, + pub(crate) created_at: u64, + pub(crate) ttl_millis: Option, +} + +impl CacheItem { + pub fn new(value: T) -> Self { + Self { + value, + created_at: current_time_millis(), + ttl_millis: None, + } + } + + pub fn with_ttl(value: T, ttl: Duration) -> Self { + Self { + value, + created_at: current_time_millis(), + ttl_millis: Some(ttl.as_millis() as u64), + } + } +} + +pub struct CacheNoPrefetch +where + Value: Clone + Debug + Send + Sync + 'static, +{ + map: IndexMap>, + capacity: usize, + event_sender: Option>, +} + +impl CacheNoPrefetch +where + Value: Clone + Debug + Send + Sync + 'static, +{ + pub fn new(capacity: usize) -> Self { + Self { + map: IndexMap::with_capacity(capacity), + capacity, + event_sender: None, + } + } + + pub fn with_sender(capacity: usize, sender: Sender) -> Self { + Self { + map: IndexMap::with_capacity(capacity), + capacity, + event_sender: Some(sender), + } + } + + pub fn insert(&mut self, key: String, value: Value) -> Option { + let item = CacheItem::new(value.clone()); + let old_value = self.map.insert(key.clone(), item).map(|item| item.value); + + if self.map.len() > self.capacity { + if let Some((evicted_key, evicted_item)) = self.map.shift_remove_index(0) { + if let Some(ref sender) = self.event_sender { + let _ = sender.send(Event::remove(evicted_key, evicted_item.value.into())); + } + } + } + + if let Some(ref sender) = self.event_sender { + match old_value { + Some(_) => { + let _ = sender.send(Event::insert(key, value.into())); + } + None => { + let _ = sender.send(Event::insert(key, value.into())); + } + } + } + + old_value + } + + pub fn get(&mut self, key: &str) -> Option<&Value> { + // NO PREFETCH HERE + + let is_expired = match self.map.get(key) { + Some(item) => { + if let Some(ttl) = item.ttl_millis { + (current_time_millis() - item.created_at) > ttl + } else { + false + } + } + None => return None, + }; + + if is_expired { + self.map.shift_remove(key); + return None; + } + + if let Some((index, _, item)) = self.map.get_full_mut(key) { + self.map.move_index(index, self.map.len() - 1); + Some(&item.value) + } else { + None + } + } + + pub fn cleanup_expired(&mut self) -> usize { + let current_time = current_time_millis(); + let mut expired_keys = Vec::with_capacity(self.map.len() / 4); + + for (key, item) in &self.map { + // NO PREFETCH HERE + + if let Some(ttl) = item.ttl_millis { + if (current_time - item.created_at) > ttl { + expired_keys.push(key.clone()); + } + } + } + + let removed_count = expired_keys.len(); + + if !expired_keys.is_empty() { + // NO PREFETCH HERE + for key in expired_keys { + if let Some(removed_item) = self.map.shift_remove(&key) { + if let Some(ref sender) = self.event_sender { + let _ = sender.send(Event::remove(key, removed_item.value.into())); + } + } + } + } + + removed_count + } + + pub fn list(&mut self, props: ListProps) -> Result, Error> { + self.cleanup_expired(); + + let mut keys: Vec = self.map.keys().cloned().collect(); + keys.sort(); + + // NO PREFETCH HERE + + match props.order { + Order::Asc => self.resolve_order(keys.iter(), props), + Order::Desc => self.resolve_order(keys.iter().rev(), props), + } + } + + fn resolve_order<'a, I>(&self, keys: I, props: ListProps) -> Result, Error> + where + I: Iterator, + { + let mut results = Vec::new(); + let mut count = 0; + + for key in keys { + if count >= props.limit { + break; + } + + if let Some(ref filter) = props.filter { + if !self.matches_filter(key, filter) { + continue; + } + } + + if let Some(item) = self.map.get(key) { + results.push((key.clone(), item.value.clone())); + count += 1; + } + } + + Ok(results) + } + + fn matches_filter(&self, key: &str, filter: &Filter) -> bool { + match filter { + Filter::StartWith(prefix) => key.starts_with(prefix), + Filter::EndWith(suffix) => key.ends_with(suffix), + } + } + + pub fn len(&self) -> usize { + self.map.len() + } + + pub fn is_empty(&self) -> bool { + self.map.is_empty() + } + + pub fn capacity(&self) -> usize { + self.capacity + } + + pub fn clear(&mut self) { + self.map.clear(); + } + + pub fn contains_key(&self, key: &str) -> bool { + if let Some(item) = self.map.get(key) { + if let Some(ttl) = item.ttl_millis { + let current_time = current_time_millis(); + (current_time - item.created_at) <= ttl + } else { + true + } + } else { + false + } + } + + pub fn remove(&mut self, key: &str) -> Result, Error> { + if let Some(item) = self.map.shift_remove(key) { + let value = item.value; + + if let Some(ref sender) = self.event_sender { + let _ = sender.send(Event::remove(key.to_string(), value.clone().into())); + } + + Ok(Some(value)) + } else { + Ok(None) + } + } +} + +fn current_time_millis() -> u64 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_millis() as u64 +} diff --git a/src/lib.rs b/src/lib.rs index 70b2fa5..74f199f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -333,7 +333,6 @@ mod list_props; #[cfg(test)] #[cfg(feature = "persist")] mod persist_tests; -mod prefetch; pub mod prelude; mod quickleaf; #[cfg(feature = "persist")] diff --git a/src/prefetch.rs b/src/prefetch.rs deleted file mode 100644 index 4a57b35..0000000 --- a/src/prefetch.rs +++ /dev/null @@ -1,116 +0,0 @@ -//! Prefetch hints for better memory access patterns and cache locality -//! -//! This module provides memory prefetch optimizations to improve cache performance -//! by giving the CPU hints about what memory will be accessed soon. - -/// Prefetch operations for memory access optimization -pub struct Prefetch; - -impl Prefetch { - /// Prefetch memory for read access (non-temporal) - /// - /// This hints to the processor that the memory location will be read soon. - /// Uses PREFETCH_T0 which loads data to all cache levels. - #[inline(always)] - pub fn read_hint(ptr: *const T) { - if cfg!(target_arch = "x86_64") || cfg!(target_arch = "x86") { - unsafe { - #[cfg(target_arch = "x86_64")] - core::arch::x86_64::_mm_prefetch(ptr as *const i8, core::arch::x86_64::_MM_HINT_T0); - - #[cfg(target_arch = "x86")] - core::arch::x86::_mm_prefetch(ptr as *const i8, core::arch::x86::_MM_HINT_T0); - } - } - } - - /// Prefetch multiple sequential memory locations - /// - /// This is useful for prefetching array-like structures or linked data. - /// Prefetches in 64-byte cache line chunks. - #[inline(always)] - pub fn sequential_read_hints(start_ptr: *const T, count: usize) { - if cfg!(target_arch = "x86_64") || cfg!(target_arch = "x86") { - let stride = 64; - let elem_size = std::mem::size_of::(); - let total_bytes = count * elem_size; - - for offset in (0..total_bytes).step_by(stride) { - unsafe { - let prefetch_ptr = (start_ptr as *const u8).add(offset); - - #[cfg(target_arch = "x86_64")] - core::arch::x86_64::_mm_prefetch( - prefetch_ptr as *const i8, - core::arch::x86_64::_MM_HINT_T0, - ); - - #[cfg(target_arch = "x86")] - core::arch::x86::_mm_prefetch( - prefetch_ptr as *const i8, - core::arch::x86::_MM_HINT_T0, - ); - } - } - } - } -} - -/// Helper trait to add prefetch methods to common types -pub trait PrefetchExt { - /// Prefetch this memory location for read access - fn prefetch_read(&self); -} - -impl PrefetchExt for *const T { - #[inline(always)] - fn prefetch_read(&self) { - Prefetch::read_hint(*self); - } -} - -impl PrefetchExt for *mut T { - #[inline(always)] - fn prefetch_read(&self) { - Prefetch::read_hint(*self as *const T); - } -} - -impl PrefetchExt for &T { - #[inline(always)] - fn prefetch_read(&self) { - Prefetch::read_hint(*self as *const T); - } -} - -impl PrefetchExt for &mut T { - #[inline(always)] - fn prefetch_read(&self) { - Prefetch::read_hint(*self as *const T); - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_prefetch_hints() { - let data = vec![1, 2, 3, 4, 5]; - - Prefetch::read_hint(data.as_ptr()); - - Prefetch::sequential_read_hints(data.as_ptr(), data.len()); - } - - #[test] - fn test_prefetch_ext_trait() { - let data = vec![1, 2, 3, 4, 5]; - let ptr = data.as_ptr(); - - ptr.prefetch_read(); - - let val = 42; - (&val).prefetch_read(); - } -} From f639225e992c62cc14a91aaeee9878cf78b142cf Mon Sep 17 00:00:00 2001 From: Philippe Assis Date: Fri, 22 Aug 2025 11:36:39 -0300 Subject: [PATCH 3/3] =?UTF-8?q?refactor:=20atualizar=20vers=C3=A3o=20do=20?= =?UTF-8?q?pacote=20quickleaf=20para=200.4.5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 02f53fb..8acf956 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -805,7 +805,7 @@ dependencies = [ [[package]] name = "quickleaf" -version = "0.4.4" +version = "0.4.5" dependencies = [ "criterion", "crossterm 0.29.0", diff --git a/Cargo.toml b/Cargo.toml index 11177d1..0d4f240 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "quickleaf" -version = "0.4.4" +version = "0.4.5" edition = "2021" license = "Apache-2.0" authors = ["Philippe Assis "]