Skip to content

Commit c96d8b9

Browse files
committed
ids: Add IdSetSeq
This is an often more efficient replacement for a `IdVec<I, HashSet<T>>` implemented on top of a `SetSeq<T>`.
1 parent 887feaf commit c96d8b9

File tree

4 files changed

+98
-0
lines changed

4 files changed

+98
-0
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ids/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ workspace = true
1212
hashbrown = { version = "0.14.5", default-features = false, features = ["inline-more"] }
1313
imctk-derive = { path = "../derive" }
1414
imctk-transparent = { path = "../transparent" }
15+
table_seq = { path = "../table_seq" }
1516
zwohash = "0.1.2"
1617

1718
[dev-dependencies]

ids/src/id_set_seq.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
//! Id indexed sequence of hash sets.
2+
use std::{hash::BuildHasherDefault, marker::PhantomData};
3+
4+
use table_seq::set_seq::{SetSeq, SetSeqSet, SetSeqSetMut};
5+
use zwohash::ZwoHasher;
6+
7+
use crate::Id;
8+
9+
/// Indexed sequence of hash sets.
10+
///
11+
/// This type serves as a memory and runtime efficient replacement for `IdVec<I, HashSet<T>>`.
12+
pub struct IdSetSeq<I: Id, T, S = BuildHasherDefault<ZwoHasher>> {
13+
set_seq: SetSeq<T, S>,
14+
_phantom: PhantomData<I>,
15+
}
16+
17+
impl<I: Id, T, S> std::ops::Deref for IdSetSeq<I, T, S> {
18+
type Target = SetSeq<T, S>;
19+
20+
#[inline(always)]
21+
fn deref(&self) -> &Self::Target {
22+
&self.set_seq
23+
}
24+
}
25+
26+
impl<I: Id, T, S> IdSetSeq<I, T, S> {
27+
/// Discards all sets in the sequence.
28+
#[inline(always)]
29+
pub fn clear(&mut self) {
30+
self.set_seq.clear();
31+
}
32+
33+
/// Resizes the sequence by appending empty sets or discarding trailing sets.
34+
#[inline(always)]
35+
pub fn resize(&mut self, len: usize) {
36+
self.set_seq.resize(len);
37+
}
38+
39+
/// Ensures that the sequence contains a set for the given id by appending emtpy sets if the
40+
/// sequence was too short.
41+
///
42+
/// Provides mutable access to the set for the given id.
43+
#[inline(always)]
44+
pub fn grow_for(&mut self, id: I) -> SetSeqSetMut<T, S> {
45+
self.set_seq.grow_for(id.id_index())
46+
}
47+
48+
/// Provides shared access to the set for a given id, panics if the id is out-of-bounds.
49+
///
50+
/// This is used instead of [`std::ops::Index`], as it returns a value of the custom
51+
/// reference-like [`SetSeqSet`] type.
52+
///
53+
/// Panics if `id.id_index() >= self.len()`.
54+
#[inline(always)]
55+
pub fn at(&self, id: I) -> SetSeqSet<T, S> {
56+
self.set_seq.at(id.id_index())
57+
}
58+
59+
/// Provides mutable access to the set for a given id, panics if the id is out-of-bounds.
60+
///
61+
/// This is used instead of [`std::ops::IndexMut`], as it returns a value of the custom
62+
/// reference-like [`SetSeqSetMut`] type.
63+
///
64+
/// Panics if `id.id_index() >= self.len()`.
65+
#[inline(always)]
66+
pub fn at_mut(&mut self, id: I) -> SetSeqSetMut<T, S> {
67+
self.set_seq.at_mut(id.id_index())
68+
}
69+
70+
/// Provides shared access to the set for a given id.
71+
///
72+
/// This returns `None` if `id.id_index() >= self.len()`.
73+
#[inline(always)]
74+
pub fn get(&self, id: I) -> Option<SetSeqSet<T, S>> {
75+
self.set_seq.get(id.id_index())
76+
}
77+
78+
/// Provides mutable access to the set for a given id.
79+
///
80+
/// This returns `None` if `id.id_index() >= self.len()`.
81+
#[inline(always)]
82+
pub fn get_mut(&mut self, id: I) -> Option<SetSeqSetMut<T, S>> {
83+
self.set_seq.get_mut(id.id_index())
84+
}
85+
}
86+
87+
impl<I: Id, T, S: Default> Default for IdSetSeq<I, T, S> {
88+
fn default() -> Self {
89+
Self {
90+
set_seq: Default::default(),
91+
_phantom: PhantomData,
92+
}
93+
}
94+
}

ids/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ mod id_range;
1717
pub mod id_vec;
1818
pub mod indexed_id_vec;
1919

20+
pub mod id_set_seq;
21+
2022
/// Derives an [`Id`] instance for a newtype wrapper around an existing [`Id`] type.
2123
///
2224
/// Deriving an [`Id`] instance requires the `#[repr(transparent)]` attribute on the target struct.

0 commit comments

Comments
 (0)