36 releases (4 breaking)
0.5.9 | Nov 17, 2024 |
---|---|
0.4.2 |
|
0.3.7 | Jul 30, 2024 |
0.3.0 | Mar 31, 2024 |
#372 in Data structures
1,703 downloads per month
Used in liberty-db
70KB
967 lines
mut_set
Use the idea of readonly to implement HashSet with iter_mut
and get_mut
.
Add crates by following command
cargo add mut_set mut_set_derive
or add it into Cargo.toml
[dependencies]
mut_set = "0.3"
mut_set_derive = "0.3"
Demo
#[derive(Debug)]
#[mut_set_derive::item]
pub(super) struct MyItem<T1, T2>
where
T1: Sized,
{
#[id]
pub id1: usize,
pub ctx1: T1,
pub(in crate::derive) ctx2: T2,
#[id]
pub id2: String,
}
#[test]
fn test() {
let mut set = mut_set::MutSet::new();
println!("{:?}", set);
set.insert(MyItem {
id1: 2,
id2: "www".to_string(),
ctx1: -1,
ctx2: "ccc".to_string(),
});
set.insert(MyItem {
id1: 1,
id2: "ww".to_string(),
ctx1: -2,
ctx2: "cc".to_string(),
});
println!("{:?}", set);
for v in set.iter() {
println!("{:?}", v);
}
for v in set.iter_mut() {
v.ctx1 = 0;
println!("{:?}", v.id1);
// In `iter_mut` IDs write will be prohibited
// v.id1 = 0;
}
println!("{:?}", set);
let id1 = MyItem::id(2, "www".to_string());
println!("{:?}", set.get(&id1));
for v in set.into_iter() {
println!("{:?}", v);
}
}
How does mut_set
work
The macro will implement all stuffs in tests/src/basic_expand.rs.
Take Xxx
as an example:
- Create two struct
ImmutIdXxx
, andXxxId
. WhereImmutIdXxx
is same toXxx
with private id fields, andXxxId
only contains id fields. - Do rearrangement so that all id fields are located at beginning of the structure. By the help of
#[repr(C)]
, we can use raw pointer operations to (zero-cost?) convertXxx
,ImmutIdXxx
, andXxxId
. impl mut_set::Item for Xxx<ImmutIdItem = ImmutIdXxx>
MutSet<T: Item> = HashMap<u64, T::ImmutIdItem>
, where theu64
is the hash value.- Wrap the iteration function
iter(&self) -> Iter<&Xxx>
into_iter(self) -> Iter<Xxx>
iter_mut(&mut self) -> Iter<&mut ImmutIdXxx>
Other features
-
If you want to add some
derive
/proc_macro
toImmutIdXxx
/XxxId
. You can add arguments tomut_set_derive::item
, to specify whichderive
should add toImmutIdXxx
/XxxId
, and the filter for fileds attribute. e.g.,#[mut_set_derive::item( macro(derive(Debug, Clone); derive(derivative::Derivative); derivative(Default);), attr_filter(derivative;) )] struct Xxx { #[id] id: usize, #[derivative(Default(value = "8"))] #[some_attr] ctx: usize, }
will impl
#[derive(Debug, Clone)] #[derive(derivative::Derivative)] #[derivative(Default)] struct ImmutIdXxx { id: usize, #[derivative(Default(value = "8"))] ctx: usize, } #[derive(Debug, Clone)] #[derive(derivative::Derivative)] #[derivative(Default)] struct XxxId { id: usize, }
Here
some_attr
is not inattr_filter()
, so it will be removed. See more at tests/src/derive.rs and tests/src/derive_expand.rs.
Dependencies
~0.3–1MB
~21K SLoC