Skip to content

Commit

Permalink
ids: Add IdSetSeq
Browse files Browse the repository at this point in the history
This is an often more efficient replacement for a `IdVec<I, HashSet<T>>`
implemented on top of a `SetSeq<T>`.
  • Loading branch information
jix committed Sep 29, 2024
1 parent 887feaf commit c96d8b9
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions ids/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ workspace = true
hashbrown = { version = "0.14.5", default-features = false, features = ["inline-more"] }
imctk-derive = { path = "../derive" }
imctk-transparent = { path = "../transparent" }
table_seq = { path = "../table_seq" }
zwohash = "0.1.2"

[dev-dependencies]
Expand Down
94 changes: 94 additions & 0 deletions ids/src/id_set_seq.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
//! Id indexed sequence of hash sets.
use std::{hash::BuildHasherDefault, marker::PhantomData};

use table_seq::set_seq::{SetSeq, SetSeqSet, SetSeqSetMut};
use zwohash::ZwoHasher;

use crate::Id;

/// Indexed sequence of hash sets.
///
/// This type serves as a memory and runtime efficient replacement for `IdVec<I, HashSet<T>>`.
pub struct IdSetSeq<I: Id, T, S = BuildHasherDefault<ZwoHasher>> {
set_seq: SetSeq<T, S>,
_phantom: PhantomData<I>,
}

impl<I: Id, T, S> std::ops::Deref for IdSetSeq<I, T, S> {
type Target = SetSeq<T, S>;

#[inline(always)]
fn deref(&self) -> &Self::Target {
&self.set_seq
}
}

impl<I: Id, T, S> IdSetSeq<I, T, S> {
/// Discards all sets in the sequence.
#[inline(always)]
pub fn clear(&mut self) {
self.set_seq.clear();
}

/// Resizes the sequence by appending empty sets or discarding trailing sets.
#[inline(always)]
pub fn resize(&mut self, len: usize) {
self.set_seq.resize(len);
}

/// Ensures that the sequence contains a set for the given id by appending emtpy sets if the
/// sequence was too short.
///
/// Provides mutable access to the set for the given id.
#[inline(always)]
pub fn grow_for(&mut self, id: I) -> SetSeqSetMut<T, S> {
self.set_seq.grow_for(id.id_index())
}

/// Provides shared access to the set for a given id, panics if the id is out-of-bounds.
///
/// This is used instead of [`std::ops::Index`], as it returns a value of the custom
/// reference-like [`SetSeqSet`] type.
///
/// Panics if `id.id_index() >= self.len()`.
#[inline(always)]
pub fn at(&self, id: I) -> SetSeqSet<T, S> {
self.set_seq.at(id.id_index())
}

/// Provides mutable access to the set for a given id, panics if the id is out-of-bounds.
///
/// This is used instead of [`std::ops::IndexMut`], as it returns a value of the custom
/// reference-like [`SetSeqSetMut`] type.
///
/// Panics if `id.id_index() >= self.len()`.
#[inline(always)]
pub fn at_mut(&mut self, id: I) -> SetSeqSetMut<T, S> {
self.set_seq.at_mut(id.id_index())
}

/// Provides shared access to the set for a given id.
///
/// This returns `None` if `id.id_index() >= self.len()`.
#[inline(always)]
pub fn get(&self, id: I) -> Option<SetSeqSet<T, S>> {
self.set_seq.get(id.id_index())
}

/// Provides mutable access to the set for a given id.
///
/// This returns `None` if `id.id_index() >= self.len()`.
#[inline(always)]
pub fn get_mut(&mut self, id: I) -> Option<SetSeqSetMut<T, S>> {
self.set_seq.get_mut(id.id_index())
}
}

impl<I: Id, T, S: Default> Default for IdSetSeq<I, T, S> {
fn default() -> Self {
Self {
set_seq: Default::default(),
_phantom: PhantomData,
}
}
}
2 changes: 2 additions & 0 deletions ids/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ mod id_range;
pub mod id_vec;
pub mod indexed_id_vec;

pub mod id_set_seq;

/// Derives an [`Id`] instance for a newtype wrapper around an existing [`Id`] type.
///
/// Deriving an [`Id`] instance requires the `#[repr(transparent)]` attribute on the target struct.
Expand Down

0 comments on commit c96d8b9

Please sign in to comment.