Skip to content

Commit 7e198f3

Browse files
author
Mykyta Zotov
committed
docs: enhance README.md with improved structure and content, adding table of contents, visual aids, and sections for configuration and contribution guidelines
1 parent 2116864 commit 7e198f3

1 file changed

Lines changed: 198 additions & 56 deletions

File tree

README.md

Lines changed: 198 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,36 @@
11
# Sliding Window Cache
22

3-
**A read-only, range-based, sequential-optimized cache with background rebalancing and cancellation-aware prefetching.**
3+
**A read-only, range-based, sequential-optimized cac~~~~he with background rebalancing and cancellation-aware prefetching.**
44

55
---
66

7-
## Overview
7+
[![CI/CD](https://github.com/blaze6950/SlidingWindowCache/actions/workflows/slidingwindowcache.yml/badge.svg)](https://github.com/blaze6950/SlidingWindowCache/actions/workflows/slidingwindowcache.yml)
8+
[![NuGet](https://img.shields.io/nuget/v/SlidingWindowCache.svg)](https://www.nuget.org/packages/SlidingWindowCache/)
9+
[![NuGet Downloads](https://img.shields.io/nuget/dt/SlidingWindowCache.svg)](https://www.nuget.org/packages/SlidingWindowCache/)
10+
[![codecov](https://codecov.io/gh/blaze6950/SlidingWindowCache/graph/badge.svg?token=RFQBNX7MMD)](https://codecov.io/gh/blaze6950/SlidingWindowCache)
11+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
12+
[![.NET 8.0](https://img.shields.io/badge/.NET-8.0-blue.svg)](https://dotnet.microsoft.com/download/dotnet/8.0)
13+
14+
---
15+
16+
## 📑 Table of Contents
17+
18+
- [Overview](#-overview)
19+
- [Sliding Window Cache Concept](#-sliding-window-cache-concept)
20+
- [Understanding the Sliding Window](#-understanding-the-sliding-window)
21+
- [Materialization for Fast Access](#-materialization-for-fast-access)
22+
- [Usage Example](#-usage-example)
23+
- [Configuration](#-configuration)
24+
- [Optional Diagnostics](#-optional-diagnostics)
25+
- [Documentation](#-documentation)
26+
- [Performance Considerations](#-performance-considerations)
27+
- [CI/CD & Package Information](#-cicd--package-information)
28+
- [Contributing & Feedback](#-contributing--feedback)
29+
- [License](#license)
30+
31+
---
32+
33+
## 📦 Overview
834

935
The Sliding Window Cache is a high-performance caching library designed for scenarios where data is accessed in sequential or predictable patterns across ranges. It automatically prefetches and maintains a "window" of data around the most recently requested range, significantly reducing the need for repeated data source queries.
1036

@@ -19,7 +45,7 @@ The Sliding Window Cache is a high-performance caching library designed for scen
1945

2046
---
2147

22-
## Sliding Window Cache Concept
48+
## 🎯 Sliding Window Cache Concept
2349

2450
Traditional caches work with individual keys. A sliding window cache, in contrast, operates on **continuous ranges** of data:
2551

@@ -29,14 +55,74 @@ Traditional caches work with individual keys. A sliding window cache, in contras
2955
4. **Window automatically rebalances** when the user moves outside threshold boundaries
3056

3157
This pattern is ideal for:
58+
3259
- Time-series data (sensor readings, logs, metrics)
3360
- Paginated datasets with forward/backward navigation
3461
- Sequential data processing (video frames, audio samples)
3562
- Any scenario with high spatial or temporal locality of access
3663

3764
---
3865

39-
## Materialization for Fast Access
66+
## 🔍 Understanding the Sliding Window
67+
68+
### Visual: Requested Range vs. Cache Window
69+
70+
When you request a range, the cache actually fetches and stores a larger window:
71+
72+
```
73+
Requested Range (what user asks for):
74+
[======== USER REQUEST ========]
75+
76+
Actual Cache Window (what cache stores):
77+
[=== LEFT BUFFER ===][======== USER REQUEST ========][=== RIGHT BUFFER ===]
78+
← leftCacheSize requestedRange size rightCacheSize →
79+
```
80+
81+
The **left** and **right buffers** are calculated as multiples of the requested range size using the `leftCacheSize` and `rightCacheSize` coefficients.
82+
83+
### Visual: Rebalance Trigger
84+
85+
Rebalancing occurs when a new request moves outside the threshold boundaries:
86+
87+
```
88+
Current Cache Window:
89+
[========*===================== CACHE ======================*=======]
90+
↑ ↑
91+
Left Threshold (20%) Right Threshold (20%)
92+
93+
Scenario 1: Request within thresholds → No rebalance
94+
[========*===================== CACHE ======================*=======]
95+
[---- new request ----] ✓ Served from cache
96+
97+
Scenario 2: Request outside threshold → Rebalance triggered
98+
[========*===================== CACHE ======================*=======]
99+
[---- new request ----]
100+
101+
🔄 Rebalance: Shift window right
102+
```
103+
104+
### Visual: Configuration Impact
105+
106+
How coefficients control the cache window size:
107+
108+
```
109+
Example: User requests range of size 100
110+
111+
leftCacheSize = 1.0, rightCacheSize = 2.0
112+
[==== 100 ====][======= 100 =======][============ 200 ============]
113+
Left Buffer Requested Range Right Buffer
114+
115+
Total Cache Window = 100 + 100 + 200 = 400 items
116+
117+
leftThreshold = 0.2 (20% of 400 = 80 items)
118+
rightThreshold = 0.2 (20% of 400 = 80 items)
119+
```
120+
121+
**Key insight:** Threshold percentages are calculated based on the **total cache window size**, not individual buffer sizes.
122+
123+
---
124+
125+
## 💾 Materialization for Fast Access
40126

41127
### Why Materialization?
42128

@@ -108,7 +194,7 @@ The cache supports two materialization strategies, configured at creation time v
108194

109195
---
110196

111-
## Usage Example
197+
## 🚀 Usage Example
112198

113199
```csharp
114200
using SlidingWindowCache;
@@ -147,16 +233,87 @@ foreach (var item in data.Span)
147233

148234
---
149235

150-
## Configuration
236+
## ⚙️ Configuration
237+
238+
The `WindowCacheOptions` class provides fine-grained control over cache behavior. Understanding these parameters is essential for optimal performance.
239+
240+
### Configuration Parameters
241+
242+
#### Cache Size Coefficients
243+
244+
**`leftCacheSize`** (double, default: 1.0)
245+
- **Definition**: Multiplier applied to the requested range size to determine the left buffer size
246+
- **Practical meaning**: How much data to prefetch *before* the requested range
247+
- **Example**: If user requests 100 items and `leftCacheSize = 1.5`, the cache prefetches 150 items to the left
248+
- **Typical values**: 0.5 to 2.0 (depending on backward navigation patterns)
249+
250+
**`rightCacheSize`** (double, default: 2.0)
251+
- **Definition**: Multiplier applied to the requested range size to determine the right buffer size
252+
- **Practical meaning**: How much data to prefetch *after* the requested range
253+
- **Example**: If user requests 100 items and `rightCacheSize = 2.0`, the cache prefetches 200 items to the right
254+
- **Typical values**: 1.0 to 3.0 (higher for forward-scrolling scenarios)
255+
256+
#### Threshold Policies
257+
258+
**`leftThreshold`** (double, default: 0.2)
259+
- **Definition**: Percentage of the **total cache window size** that triggers rebalancing when crossed on the left
260+
- **Calculation**: `leftThreshold × (Left Buffer + Requested Range + Right Buffer)`
261+
- **Example**: With total window of 400 items and `leftThreshold = 0.2`, rebalance triggers when user moves within 80 items of the left edge
262+
- **Typical values**: 0.15 to 0.3 (lower = more aggressive rebalancing)
151263

152-
See `WindowCacheOptions` for detailed configuration parameters:
153-
- **Left/Right Cache Coefficients**: Control how much extra data to prefetch
154-
- **Threshold Policies**: Define when rebalancing should occur
155-
- **Debounce Delay**: Prevent thrashing during rapid access pattern changes
264+
**`rightThreshold`** (double, default: 0.2)
265+
- **Definition**: Percentage of the **total cache window size** that triggers rebalancing when crossed on the right
266+
- **Calculation**: `rightThreshold × (Left Buffer + Requested Range + Right Buffer)`
267+
- **Example**: With total window of 400 items and `rightThreshold = 0.2`, rebalance triggers when user moves within 80 items of the right edge
268+
- **Typical values**: 0.15 to 0.3 (lower = more aggressive rebalancing)
269+
270+
**⚠️ Critical Understanding**: Thresholds are **NOT** calculated against individual buffer sizes. They represent a percentage of the **entire cache window** (left buffer + requested range + right buffer). See [Understanding the Sliding Window](#-understanding-the-sliding-window) for visual examples.
271+
272+
#### Debouncing
273+
274+
**`debounceDelay`** (TimeSpan, default: 50ms)
275+
- **Definition**: Minimum time delay before executing a rebalance operation after it's triggered
276+
- **Purpose**: Prevents cache thrashing when user rapidly changes access patterns
277+
- **Behavior**: If multiple rebalance requests occur within the debounce window, only the last one executes
278+
- **Typical values**: 20ms to 200ms (depending on data source latency)
279+
- **Trade-off**: Higher values reduce rebalance frequency but may delay cache optimization
280+
281+
### Configuration Examples
282+
283+
**Forward-heavy scrolling** (e.g., log viewer, video player):
284+
```csharp
285+
var options = new WindowCacheOptions(
286+
leftCacheSize: 0.5, // Minimal backward buffer
287+
rightCacheSize: 3.0, // Aggressive forward prefetching
288+
leftThreshold: 0.25,
289+
rightThreshold: 0.15 // Trigger rebalance earlier when moving forward
290+
);
291+
```
292+
293+
**Bidirectional navigation** (e.g., paginated data grid):
294+
```csharp
295+
var options = new WindowCacheOptions(
296+
leftCacheSize: 1.5, // Balanced backward buffer
297+
rightCacheSize: 1.5, // Balanced forward buffer
298+
leftThreshold: 0.2,
299+
rightThreshold: 0.2
300+
);
301+
```
302+
303+
**Aggressive prefetching with stability** (e.g., high-latency data source):
304+
```csharp
305+
var options = new WindowCacheOptions(
306+
leftCacheSize: 2.0,
307+
rightCacheSize: 3.0,
308+
leftThreshold: 0.1, // Rebalance early to maintain large buffers
309+
rightThreshold: 0.1,
310+
debounceDelay: TimeSpan.FromMilliseconds(100) // Wait for access pattern to stabilize
311+
);
312+
```
156313

157314
---
158315

159-
## Optional Diagnostics
316+
## 📊 Optional Diagnostics
160317

161318
The cache supports optional diagnostics for monitoring behavior, measuring performance, and validating system invariants. This is useful for:
162319
- **Testing and validation**: Verify cache behavior meets expected patterns
@@ -221,60 +378,24 @@ var cache = new WindowCache<int, string, IntegerFixedStepDomain>(
221378

222379
// Access diagnostic counters
223380
Console.WriteLine($"Full cache hits: {diagnostics.UserRequestFullCacheHit}");
224-
Console.WriteLine($"Partial cache hits: {diagnostics.UserRequestPartialCacheHit}");
225-
Console.WriteLine($"Full cache misses: {diagnostics.UserRequestFullCacheMiss}");
226381
Console.WriteLine($"Rebalances completed: {diagnostics.RebalanceExecutionCompleted}");
227382
```
228383

229-
### Available Metrics
230-
231-
**User Path Metrics:**
232-
- `UserRequestServed` - Total requests completed
233-
- `UserRequestFullCacheHit` - Requests served entirely from cache
234-
- `UserRequestPartialCacheHit` - Requests requiring partial fetch from data source
235-
- `UserRequestFullCacheMiss` - Requests requiring complete fetch (cold start or jump)
236-
- `CacheExpanded` - Range analysis determined expansion needed (called by shared service during planning)
237-
- `CacheReplaced` - Range analysis determined replacement needed (called by shared service during planning)
238-
239-
**Note**: `CacheExpanded` and `CacheReplaced` are incremented during range analysis by `CacheDataExtensionService`
240-
(used by both User Path and Rebalance Path) when determining what data needs to be fetched. They indicate that
241-
cache extension/replacement will occur, not that the actual mutation (via `Rematerialize`) has happened.
242-
Actual cache mutations only occur in Rebalance Execution (single-writer architecture).
243-
244-
**Data Source Interaction:**
245-
- `DataSourceFetchSingleRange` - Single-range fetches from data source
246-
- `DataSourceFetchMissingSegments` - Multi-segment fetches (gap filling)
247-
248-
**Rebalance Lifecycle:**
249-
- `RebalanceIntentPublished` - Rebalance intents published by User Path
250-
- `RebalanceIntentCancelled` - Intents cancelled due to new user requests
251-
- `RebalanceExecutionStarted` - Rebalance executions started
252-
- `RebalanceExecutionCompleted` - Rebalance executions completed successfully
253-
- `RebalanceExecutionCancelled` - Rebalance executions cancelled mid-flight
254-
- `RebalanceExecutionFailed` - **⚠️ CRITICAL**: Rebalance execution failures (MUST be logged)
255-
- `RebalanceSkippedNoRebalanceRange` - Rebalances skipped due to threshold policy
256-
- `RebalanceSkippedSameRange` - Rebalances skipped due to same-range optimization
257-
258384
### Zero-Cost Abstraction
259385

260386
If no diagnostics instance is provided (default), the cache uses `NoOpDiagnostics` - a zero-overhead implementation with empty method bodies that the JIT compiler can optimize away completely. This ensures diagnostics add zero performance overhead when not used.
261387

262-
```csharp
263-
// No diagnostics - zero overhead
264-
var cache = new WindowCache<int, string, IntegerFixedStepDomain>(
265-
dataSource: myDataSource,
266-
domain: new IntegerFixedStepDomain(),
267-
options: options
268-
// cacheDiagnostics parameter omitted - uses NoOpDiagnostics
269-
);
270-
```
388+
**For complete metric descriptions, custom implementations, and advanced patterns, see [Diagnostics Guide](docs/diagnostics.md).**
271389

272390
---
273391

274-
## Documentation
392+
## 📚 Documentation
275393

276394
For detailed architectural documentation, see:
277395

396+
### Mathematical Foundations
397+
- **[Intervals.NET](https://github.com/blaze6950/Intervals.NET)** - Robust interval and range handling library that underpins cache logic. See README and documentation for core concepts like `Range`, `Domain`, `RangeData`, and interval operations.
398+
278399
### Core Architecture
279400

280401
- **[Invariants](docs/invariants.md)** - Complete list of system invariants and guarantees
@@ -315,7 +436,7 @@ For detailed architectural documentation, see:
315436

316437
---
317438

318-
## Performance Considerations
439+
## Performance Considerations
319440

320441
- **Snapshot mode**: O(1) reads, but O(n) rebalance with array allocation
321442
- **CopyOnRead mode**: O(n) reads (copy cost), but cheaper rebalance operations
@@ -325,7 +446,7 @@ For detailed architectural documentation, see:
325446

326447
---
327448

328-
## CI/CD & Package Information
449+
## 🔧 CI/CD & Package Information
329450

330451
### Continuous Integration
331452

@@ -342,8 +463,6 @@ This project uses GitHub Actions for automated testing and deployment:
342463
- Publishes to NuGet.org with skip-duplicate
343464
- Stores package artifacts in workflow runs
344465

345-
See [.github/workflows/README.md](.github/workflows/README.md) for detailed workflow documentation.
346-
347466
### WebAssembly Support
348467

349468
SlidingWindowCache is validated for WebAssembly compatibility:
@@ -379,6 +498,29 @@ Install-Package SlidingWindowCache
379498

380499
---
381500

501+
## 🤝 Contributing & Feedback
502+
503+
This project is a **personal R&D and engineering exploration** focused on cache design patterns, concurrent systems architecture, and performance optimization. While it's primarily a research endeavor, feedback and community input are highly valued and welcomed.
504+
505+
### We Welcome
506+
507+
- **Bug reports** - Found an issue? Please open a GitHub issue with reproduction steps
508+
- **Feature suggestions** - Have ideas for improvements? Start a discussion or open an issue
509+
- **Performance insights** - Benchmarked the cache in your scenario? Share your findings
510+
- **Architecture feedback** - Thoughts on the design patterns or implementation? Let's discuss
511+
- **Documentation improvements** - Found something unclear? Contributions to docs are appreciated
512+
- **Positive feedback** - If the library is useful to you, that's great to know!
513+
514+
### How to Contribute
515+
516+
- **Issues**: Use [GitHub Issues](https://github.com/blaze6950/SlidingWindowCache/issues) for bugs, feature requests, or questions
517+
- **Discussions**: Use [GitHub Discussions](https://github.com/blaze6950/SlidingWindowCache/discussions) for broader topics, ideas, or design conversations
518+
- **Pull Requests**: Code contributions are welcome, but please open an issue first to discuss significant changes
519+
520+
This project benefits from community feedback while maintaining a focused research direction. All constructive input helps improve the library's design, implementation, and documentation.
521+
522+
---
523+
382524
## License
383525

384526
MIT

0 commit comments

Comments
 (0)