v2.0.0
What's Changed
- Split
ICache
intoICache
,IAsyncCache
,IScopedCache
andIScopedAsyncCache
interfaces. Mixing sync and async code paths is problematic and generally discouraged. Splitting sync/async enables the most optimized code for each case. Scoped caches returnLifetime<T>
instead of values, and internally have all the boilerplate code to safely resolve races. - Added
ConcurrentLruBuilder
, providing a fluent builder API to ease creation of different cache configurations. Each cache option comes with a small performance overhead. The builder enables the developer to choose the exact combination of options needed, without any penalty from unused features. - Cache interfaces have optional metrics, events and policy objects depending on the options chosen when constructing the cache.
- Implemented optional support for atomic GetOrAdd methods (configurable via ConcurrentLruBuilder), mitigating cache stampede.
- ConcurrentLru now has configurable hot, warm and cold queue size via
ICapacityPartition
. Default partition scheme changed from equal to 80% warm viaFavorWarmPartition
, improving hit rate across all tests. - Fixed ConcurrentLru warmup, allowing items to enter the warm queue until warm is full. Improves hit rate across all tests.
- Added hit rate analysis tests for real world traces from Wikibench, ARC and glimpse workloads. This replicates the test suite used for Java's Caffeine.
- Async get methods now return
ValueTask
, reducing memory allocations. - Added eviction count to cache metrics
Full changelog: v1.1.0...v2.0.0