English | 简体中文 |
Starshard:高性能、延迟初始化分片的并发 HashMap
同步 + 异步 + 可选 Rayon 并行 + 可选 Serde 序列化
早期阶段(核心语义趋稳,接口命名仍可能微调)。欢迎试用与反馈。
常见方案与痛点:
RwLock<HashMap<..>>
:中高写入并发时锁冲突放大。Starshard 目标:
len()
O(1))。rayon
)。Feature | 说明 | 备注 |
---|---|---|
async |
提供 AsyncShardedHashMap (Tokio RwLock ) |
独立启用 |
rayon |
大体量迭代时分片快照并行扁平化 | 内部加速 |
serde |
同步版序列化/反序列化;异步版提供快照封装 | 不持久化 hasher |
(空) | 仅同步核心 | 依赖面最小 |
docs.rs
展示全部:
[package.metadata.docs.rs]
all-features = true
[dependencies]
starshard = { version = "0.5", features = ["async", "rayon", "serde"] }
# 最小:
# starshard = "0.5"
开发/测试:
[dev-dependencies]
serde_json = "1"
use starshard::ShardedHashMap;
use rustc_hash::FxBuildHasher;
let map: ShardedHashMap<String, i32, FxBuildHasher> = ShardedHashMap::new(64);
map.insert("a".into(), 1);
assert_eq!(map.get(&"a".into()), Some(1));
assert_eq!(map.len(), 1);
use starshard::ShardedHashMap;
use std::collections::hash_map::RandomState;
let secure = ShardedHashMap::<String,u64,RandomState>
::with_shards_and_hasher(128, RandomState::default ());
secure.insert("k".into(), 7);
#[cfg(feature = "async")]
#[tokio::main]
async fn main() {
use starshard::AsyncShardedHashMap;
let m: AsyncShardedHashMap<String, u32> = AsyncShardedHashMap::new(64);
m.insert("x".into(), 42).await;
assert_eq!(m.get(&"x".into()).await, Some(42));
}
rayon
)#[cfg(feature = "rayon")]
{
use starshard::ShardedHashMap;
let m: ShardedHashMap<String,u32> = ShardedHashMap::new(32);
for i in 0..50_000 {
m.insert(format ! ("k{i}"), i);
}
let count = m.iter().count();
assert_eq!(count, 50_000);
}
同步:
{ shard_count: usize, entries: [[K,V], ...] }
S::default()
K: Eq + Hash + Clone + Serialize + Deserialize
,V: Clone + Serialize + Deserialize
,
S: BuildHasher + Default + Clone
异步:
#[cfg(all(feature = "async", feature = "serde"))]
{
let snap = async_map.async_snapshot_serializable().await;
let json = serde_json::to_string( & snap).unwrap();
}
恢复:新建空异步 map 后逐条插入。
len()
为结构性更新后的原子值;进行中的未完成操作不可见。场景 | 说明 |
---|---|
读多写少 vs 全局单锁 | 写冲突显著下降 |
大量快照迭代 + rayon |
3~4 倍扁平化速度 (100k+ 元素) |
稀疏访问 | 仅访问分片分配内存 |
请基准测试你的真实负载(键分布、核心数、缓存行为)。
Vec
。Arc -> RwLock<Vec<Option<Arc<RwLock<HashMap<K,V,S>>>>>> + AtomicUsize(len)
目标 | 代码 |
---|---|
基础插入/读取 | 快速上手 |
异步操作 | 异步示例 |
并行迭代 | 并行迭代 |
Serde 同步 | serde_json::to_string(&map) |
异步快照序列化 | async_snapshot_serializable() |
自定义 hasher | with_shards_and_hasher |
MIT OR Apache-2.0 双许可。
欢迎 Issue / PR:
cargo clippy --all-features -- -D warnings
cargo test --all-features
提交前确保:
use starshard::{ShardedHashMap, AsyncShardedHashMap};
#[cfg(feature = "async")]
#[tokio::main]
async fn main() {
let sync_map: ShardedHashMap<u64, u64> = ShardedHashMap::new(32);
sync_map.insert(1, 10);
#[cfg(feature = "serde")]
{
let json = serde_json::to_string(&sync_map).unwrap();
let _de: ShardedHashMap<u64, u64> = serde_json::from_str(&json).unwrap();
}
let async_map: AsyncShardedHashMap<u64, u64> = AsyncShardedHashMap::new(32);
async_map.insert(2, 20).await;
}
性能数据仅作参考;生产使用请结合自身压测验证。