Gcoder.Collections
1.1.1
See the version list below for details.
dotnet add package Gcoder.Collections --version 1.1.1
NuGet\Install-Package Gcoder.Collections -Version 1.1.1
<PackageReference Include="Gcoder.Collections" Version="1.1.1" />
<PackageVersion Include="Gcoder.Collections" Version="1.1.1" />
<PackageReference Include="Gcoder.Collections" />
paket add Gcoder.Collections --version 1.1.1
#r "nuget: Gcoder.Collections, 1.1.1"
#:package Gcoder.Collections@1.1.1
#addin nuget:?package=Gcoder.Collections&version=1.1.1
#tool nuget:?package=Gcoder.Collections&version=1.1.1
Gcoder.Collections
Thư viện collection hiệu năng cao cho .NET 9, cung cấp hai cấu trúc dữ liệu chuyên biệt: Sorted Dictionary (giống Redis ZSET) và Timed Collection (hybrid time wheel + skip list expiration).
Tính năng
1. ISortedDictionary<TKey, TValue>
Sorted dictionary sử dụng Skip List + Hash Map bên trong, mô phỏng Redis Sorted Set (ZSET). Hỗ trợ đầy đủ thao tác rank, range by score, range by rank.
| Thao tác | Độ phức tạp |
|---|---|
Add / Remove |
O(log n) |
GetScore / TryGetScore / ContainsKey |
O(1) |
GetRank / GetReverseRank |
O(log n) |
Min / Max |
O(log n) |
RangeByScore / RangeByRank |
O(log n + k) |
CountByScore |
O(log n) |
RemoveRangeByScore / RemoveRangeByRank |
O(log n + k) |
Count / Keys |
O(1) |
Ví dụ:
using Gcoder.Collections;
var dict = ISortedDictionary<string, int>.Create();
dict.Add("player1", 1500);
dict.Add("player2", 2000);
dict.Add("player3", 1200);
// Lấy top 2 người chơi điểm cao nhất
var top2 = dict.RangeByRank(0, 1); // (player3,1200), (player1,1500)
// Đếm số người chơi trong khoảng điểm [1200, 1800]
int count = dict.CountByScore(1200, 1800); // 2
// Xoá người chơi có điểm < 1500
int removed = dict.RemoveRangeByScore(int.MinValue, 1499); // 1
2. ITimedCollection<TKey, TValue>
Timed collection với cơ chế tự động hết hạn (expiration). Sử dụng Hybrid Time Wheel + DictionaryScore:
- Timer gần (diff < ~2.9 giờ) → Hierarchical Time Wheel 3 tầng, O(1)
- Timer xa (diff >= ~2.9 giờ) → DictionaryScore (Skip List), O(log N)
- Khi timer xa đủ gần, tự động chuyển từ DictionaryScore xuống Wheel
Không giới hạn thời gian expiration — hỗ trợ timer từ vài mili-giây đến nhiều ngày, nhiều tháng.
Add Timer
|
expireTick - currentTick
|
+--------+--------+
| |
diff < W2_RANGE diff >= W2_RANGE
| |
v v
Wheel 0/1/2 DictionaryScore
^ |
| khi đủ gần |
+------<----------+
| Tham số wheel | Giá trị |
|---|---|
| Tick | 10ms |
| Wheel 0 (ms) | 256 slots x 10ms = 2.56s |
| Wheel 1 (sec) | 64 slots x 2.56s = ~2.73 phút |
| Wheel 2 (min) | 64 slots x 2.73m = ~2.9 giờ |
| Far timers | DictionaryScore (Skip List) — không giới hạn |
| Thao tác | Timer gần | Timer xa |
|---|---|---|
AddOrUpdate |
O(1) | O(log N) |
Remove |
O(1) | O(log N) |
Tick |
O(1) per expired object | — |
| Expire callback | O(1) mỗi object | — |
Constraint:
TKeyphải implementIComparable<TKey>(để hỗ trợ DictionaryScore cho far timers).
Có 2 phiên bản:
a) Phiên bản Thread-Safe (NewTimeSortSet)
- Sử dụng
ReaderWriterLockSlim+ background timer thread 10ms - An toàn cho đa luồng
OnExpired/OnRemovedfire từ background threadTick()không có tác dụng (no-op) — timer đã tự chạy
using Gcoder.Collections;
using var collection = ITimedCollection<string, string>.NewTimeSortSet();
// Callback khi object hết hạn
collection.OnExpired += items =>
{
foreach (var (key, value) in items)
Console.WriteLine($"Expired: {key}");
};
// Timer gần — hết hạn sau 5 giây
collection.AddOrUpdate("session:123", "data", TimeSpan.FromSeconds(5));
// Timer xa — hết hạn sau 30 ngày (tự động vào DictionaryScore)
collection.AddOrUpdate("backup:001", "data", TimeSpan.FromDays(30));
// Xoá chủ động (kích hoạt OnRemoved)
collection.Remove("session:123");
b) Phiên bản Single-Thread (NewTimeSortSetSingleThread)
- Không
ReaderWriterLockSlim, không background timer → zero lock overhead - Expiration lười (lazy): kiểm tra trên mỗi
AddOrUpdate/Remove/Count/Tick OnExpired/OnRemovedfire đồng bộ trên thread gọi- Chỉ dùng khi toàn bộ truy cập từ 1 thread
- Cần gọi
Tick()định kỳ (vd: mỗi frame trong game loop) nếu collection có thể idle lâu
using Gcoder.Collections;
using var collection = ITimedCollection<string, string>.NewTimeSortSetSingleThread();
collection.OnExpired += items =>
{
foreach (var (key, value) in items)
Console.WriteLine($"Expired: {key}");
};
collection.AddOrUpdate("session:123", "data", TimeSpan.FromSeconds(5));
// Timer xa — 7 ngày
collection.AddOrUpdate("weekly:task", "data", TimeSpan.FromDays(7));
// Trong game loop / update loop
while (running)
{
collection.Tick(); // ← đẩy wheel, dọn expire mà không cần add/remove
// ... logic game
}
So sánh 2 phiên bản:
| Thread-Safe | Single-Thread | |
|---|---|---|
| Lock | ReaderWriterLockSlim |
Không |
| Timer | Background thread 10ms | Lazy (trên thread gọi) |
Tick() |
No-op | Tích cực đẩy wheel |
OnExpired context |
Background thread | Thread gọi |
| Hiệu suất đơn luồng | Trung bình | Tối ưu |
| Đa luồng | ✓ | ✗ |
| Timer xa (DictionaryScore) | ✓ | ✓ |
Cài đặt
dotnet add package Gcoder.Collections --version 1.1.1
Hoặc tham khảo source trực tiếp từ GitHub.
Yêu cầu
- .NET 9+
TKey:notnull,IComparable<TKey>
Thread Safety
ISortedDictionary(DictionaryScore): Không thread-safe. Cần lock bên ngoài nếu truy cập đa luồng.ITimedCollection(NewTimeSortSet): Có thread-safe. DùngReaderWriterLockSlim+ background timer.ITimedCollection(NewTimeSortSetSingleThread): Không thread-safe. Tối ưu đơn luồng, lazy expiration.
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- No dependencies.
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Gcoder.Collections:
| Package | Downloads |
|---|---|
|
PubSubLib
Package Description |
|
|
Natify
Micro-batching library for NATS messaging with deduplication, TTL-based dedup wheel, reliable ACK/Retry, and zero-copy serialization. |
GitHub repositories
This package is not used by any popular GitHub repositories.