![]() |
VOOZH | about |
dotnet add package Soenneker.Deduplication.SlidingWindow --version 4.0.61
NuGet\Install-Package Soenneker.Deduplication.SlidingWindow -Version 4.0.61
<PackageReference Include="Soenneker.Deduplication.SlidingWindow" Version="4.0.61" />
<PackageVersion Include="Soenneker.Deduplication.SlidingWindow" Version="4.0.61" />Directory.Packages.props
<PackageReference Include="Soenneker.Deduplication.SlidingWindow" />Project file
paket add Soenneker.Deduplication.SlidingWindow --version 4.0.61
#r "nuget: Soenneker.Deduplication.SlidingWindow, 4.0.61"
#:package Soenneker.Deduplication.SlidingWindow@4.0.61
#addin nuget:?package=Soenneker.Deduplication.SlidingWindow&version=4.0.61Install as a Cake Addin
#tool nuget:?package=Soenneker.Deduplication.SlidingWindow&version=4.0.61Install as a Cake Tool
👁 alternate text is missing from this package README image
👁 alternate text is missing from this package README image
👁 alternate text is missing from this package README image
👁 alternate text is missing from this package README image
dotnet add package Soenneker.Deduplication.SlidingWindow
Soenneker.Deduplication.SlidingWindow provides a thread-safe sliding time window deduplication utility designed for extremely high throughput workloads.
It allows you to efficiently determine whether a value has been seen recently within a time window without storing the original input values.
Inputs are hashed using XXH3 (XxHash3) and only the resulting ulong is stored internally, keeping memory usage low while maintaining high performance.
Typical usage pattern:
TryMarkSeen() returns truefalsetrue againInternally it uses a bucketed concurrent set with rotating expiration, allowing expired entries to fall out automatically as the window advances.
using Soenneker.Deduplication.SlidingWindow;
var dedupe = new SlidingWindowXxHashDedupe(
window: TimeSpan.FromMinutes(5),
rotationInterval: TimeSpan.FromSeconds(10)
);
if (dedupe.TryMarkSeen("user:123"))
{
// First occurrence in the last 5 minutes
}
else
{
// Duplicate within the window
}
After the window expires, the same value will again return true.
Checks if the value was seen recently and records it if not.
bool added = dedupe.TryMarkSeen("value");
bool added2 = dedupe.TryMarkSeen("value".AsSpan());
bool added3 = dedupe.TryMarkSeenUtf8(utf8Bytes);
Return value:
| Result | Meaning |
|---|---|
true |
Value was not seen recently and was added |
false |
Value already exists within the sliding window |
Checks if a value exists within the current window.
bool exists = dedupe.Contains("value");
bool exists2 = dedupe.Contains("value".AsSpan());
bool exists3 = dedupe.ContainsUtf8(utf8Bytes);
These methods are pure checks and do not modify the set.
Manually removes a value if present.
bool removed = dedupe.TryRemove("value");
bool removed2 = dedupe.TryRemove("value".AsSpan());
bool removed3 = dedupe.TryRemoveUtf8(utf8Bytes);
Approximate number of items currently in the window.
int count = dedupe.Count;
This value is intended for diagnostics/monitoring, not strict accounting.
var dedupe = new SlidingWindowXxHashDedupe(
window: TimeSpan.FromMinutes(10),
rotationInterval: TimeSpan.FromSeconds(30),
capacityHint: 100_000,
seed: 12345
);
| Parameter | Description |
|---|---|
window |
Total deduplication duration |
rotationInterval |
How frequently buckets rotate |
capacityHint |
Optional size hint to reduce resizing |
seed |
Optional XXH3 seed for hash partitioning |
The sliding window works by rotating buckets at the specified rotationInterval.
Example:
window = 10 minutes
rotationInterval = 30 seconds
Results in ~20 rotating buckets.
Expired buckets are automatically cleared as the window advances.
Values are stored as 64-bit hashes instead of full strings.
Example approximate memory usage:
| Entries | Approx Memory |
|---|---|
| 1,000 | ~8 KB |
| 10,000 | ~80 KB |
| 100,000 | ~800 KB |
Actual usage depends on dictionary overhead.
Inputs are deduplicated using 64-bit XXH3 hashes.
This provides extremely fast hashing with a very low collision probability.
However, collisions are theoretically possible since only hashes are stored. For most event deduplication, ingestion pipelines, and telemetry scenarios, this is more than sufficient.
SlidingWindowXxHashDedupe maintains an internal background rotation timer and therefore supports disposal.
dedupe.Dispose();
or
await dedupe.DisposeAsync();
Disposing stops the internal rotation loop and releases resources.
Ideal for:
Not recommended if:
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
Showing the top 1 NuGet packages that depend on Soenneker.Deduplication.SlidingWindow:
| Package | Downloads |
|---|---|
|
Soenneker.Deduplication.SlidingWindow.Registry
A keyed registry of sliding window dedupe instances. |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.0.61 | 0 | 6/19/2026 |
| 4.0.60 | 0 | 6/19/2026 |
| 4.0.59 | 98 | 6/16/2026 |
| 4.0.58 | 112 | 6/10/2026 |
| 4.0.57 | 171 | 6/10/2026 |
| 4.0.56 | 185 | 6/6/2026 |
| 4.0.55 | 100 | 6/6/2026 |
| 4.0.54 | 97 | 6/6/2026 |
| 4.0.53 | 139 | 6/6/2026 |
| 4.0.52 | 128 | 6/5/2026 |
| 4.0.51 | 136 | 6/5/2026 |
| 4.0.50 | 100 | 6/5/2026 |
| 4.0.49 | 237 | 5/13/2026 |
| 4.0.48 | 338 | 5/3/2026 |
| 4.0.47 | 219 | 4/24/2026 |
| 4.0.46 | 99 | 4/23/2026 |
| 4.0.45 | 160 | 4/23/2026 |
| 4.0.44 | 108 | 4/23/2026 |
| 4.0.43 | 116 | 4/22/2026 |
| 4.0.42 | 150 | 4/21/2026 |
Update dependency Soenneker.Hashing.XxHash to 4.0.60 (#120)