Commit 7f07183e authored by SirBlueRabbit's avatar SirBlueRabbit
Browse files

cleanup collections.rs

parent 88c765e2
......@@ -33,7 +33,8 @@ impl Triangulation {
fn sample_shard(&self, shard_probs: &[f32]) -> Step {
let seed = fastrand::f32();
let label = self.half_edge_bag.sample();
let label_index = fastrand::usize(0..(self.half_edge_bag.size()));
let label = self.half_edge_bag[label_index].unwrap();
let vol = self.volume();
let prob = shard_probs[vol];
......@@ -46,7 +47,8 @@ impl Triangulation {
fn sample_stars(&self, stars_probs: &[f32]) -> Step {
let seed = fastrand::f32();
let label = self.half_edge_bag.sample();
let label_index = fastrand::usize(0..(self.half_edge_bag.size()));
let label = self.half_edge_bag[label_index].unwrap();
let vol = self.volume();
let prob = stars_probs[vol];
......
......@@ -4,21 +4,28 @@ use std::{
ops::{Index, IndexMut},
};
#[derive(Debug, Clone, Copy, PartialEq)]
enum Element<T: Copy> {
#[derive(Clone, Copy, Debug, PartialEq)]
enum Element<T> {
Object(T),
Hole(usize),
}
#[derive(Clone, Copy)]
pub struct Label<T> {
pub value: usize,
value: usize,
object_type: std::marker::PhantomData<T>,
}
impl<T> PartialEq for Label<T> {
fn eq(&self, other: &Self) -> bool {
self.value == other.value
impl<T> Label<T> {
pub fn value(&self) -> usize {
self.value
}
}
impl<T> Copy for Label<T> {}
impl<T> Clone for Label<T> {
fn clone(&self) -> Label<T> {
*self
}
}
......@@ -28,6 +35,12 @@ impl<T> fmt::Debug for Label<T> {
}
}
impl<T> fmt::Display for Label<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.value)
}
}
impl<T> From<usize> for Label<T> {
fn from(value: usize) -> Self {
Label {
......@@ -37,21 +50,21 @@ impl<T> From<usize> for Label<T> {
}
}
impl<T> fmt::Display for Label<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.value)
impl<T> PartialEq for Label<T> {
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
}
// todo: baai baai => slotmap
#[derive(Debug, Clone)]
pub struct Pool<T: Copy> {
#[derive(Clone, Debug)]
pub struct Pool<T> {
elements: Box<[Element<T>]>,
current_hole: usize,
size: usize,
}
impl<T: Copy> Pool<T> {
impl<T> Pool<T> {
/// Construct a `Pool` with a given `capacity`.
pub fn with_capacity(capacity: usize) -> Self {
Pool {
elements: (0..capacity).map(|i| Element::Hole(i + 1)).collect(),
......@@ -60,36 +73,38 @@ impl<T: Copy> Pool<T> {
}
}
pub fn next_label_value(&self) -> usize {
self.current_hole
}
/// `insert` an object into the `Pool`, and return its `Label`.
/// Insert an `object`, and return its `Label`.
pub fn insert(&mut self, object: T) -> Label<T> {
let label = self.current_hole;
let next_hole = match self.elements[label] {
Element::Hole(next) => next,
Element::Object(_) => panic!("Current hole label ({}) is not a hole!", label),
};
self.elements[label] = Element::Object(object);
self.current_hole = next_hole;
self.size += 1;
Label {
value: label,
object_type: std::marker::PhantomData,
if let Element::Hole(next) = self.elements[label] {
self.elements[label] = Element::Object(object);
self.current_hole = next;
self.size += 1;
Label::from(label)
} else {
unreachable!();
}
}
/// Remove an object with a given `Label`.
pub fn remove(&mut self, label: Label<T>) {
let index = label.value;
debug_assert!(matches!(self.elements[index], Element::Object(_)));
self.elements[index] = Element::Hole(self.current_hole);
self.current_hole = index;
self.size -= 1;
}
/// Check if the `Pool` `contains` an object with some `Label`.
/// Retun the index of the current hole.
pub fn current_hole(&self) -> usize {
self.current_hole
}
/// Return the total number of objects in the `Pool`.
pub fn size(&self) -> usize {
self.size
}
/// Check if the `Pool` contains an object with a given `Label`.
#[cfg(test)]
pub fn contains(&self, label: Label<T>) -> bool {
match self.elements[label.value] {
......@@ -97,14 +112,24 @@ impl<T: Copy> Pool<T> {
Element::Hole(_) => false,
}
}
}
/// Return the total number of objects in the `Pool`.
pub fn size(&self) -> usize {
self.size
impl<T: fmt::Display> fmt::Display for Pool<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.elements
.iter()
.enumerate()
.try_for_each(|(i, element)| match element {
Element::Hole(_) => Ok(()),
Element::Object(obj) => {
writeln!(f, "\t[{}]: \t{}", i, obj)
}
})?;
Ok(())
}
}
impl<T: Copy> Index<Label<T>> for Pool<T> {
impl<T> Index<Label<T>> for Pool<T> {
type Output = T;
fn index(&self, label: Label<T>) -> &Self::Output {
......@@ -115,7 +140,7 @@ impl<T: Copy> Index<Label<T>> for Pool<T> {
}
}
impl<T: Copy> IndexMut<Label<T>> for Pool<T> {
impl<T> IndexMut<Label<T>> for Pool<T> {
fn index_mut(&mut self, label: Label<T>) -> &mut Self::Output {
match &mut self.elements[label.value] {
Element::Object(object) => object,
......@@ -124,21 +149,6 @@ impl<T: Copy> IndexMut<Label<T>> for Pool<T> {
}
}
impl<T: Copy + fmt::Display> fmt::Display for Pool<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.elements
.iter()
.enumerate()
.try_for_each(|(i, element)| match element {
Element::Hole(_) => Ok(()),
Element::Object(obj) => {
writeln!(f, "\t[{}]: \t{}", i, obj)
}
})?;
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct Bag<T> {
indices: Box<[Option<usize>]>,
......@@ -146,7 +156,8 @@ pub struct Bag<T> {
size: usize,
}
impl<T: Copy> Bag<T> {
impl<T> Bag<T> {
/// Construct a `Bag` with a given `capacity`.
pub fn with_capacity(capacity: usize) -> Bag<T> {
Bag {
indices: (0..capacity).map(|_| None).collect(),
......@@ -155,17 +166,14 @@ impl<T: Copy> Bag<T> {
}
}
/// Insert a `Label`.
pub fn insert(&mut self, label: Label<T>) {
debug_assert_eq!(
self.indices[label.value], None,
"Label ({}) already in bag!",
label.value
);
self.indices[label.value] = Some(self.size);
self.labels[self.size] = Some(label);
self.size += 1;
}
/// Remove a `Label`.
pub fn remove(&mut self, label: Label<T>) {
self.size -= 1;
let index = self.indices[label.value].unwrap();
......@@ -175,19 +183,19 @@ impl<T: Copy> Bag<T> {
self.labels[self.size] = None;
}
// todo: replace this sampling withan index impl
pub fn sample(&self) -> Label<T> {
let seed = fastrand::usize(0..(self.size));
self.labels[seed].unwrap()
/// Return the total number of objects in the `Bag`.
pub fn size(&self) -> usize {
self.size
}
/// Check if the `Bag` contains a given `Label`.
#[cfg(test)]
pub fn contains(&self, label: Label<T>) -> bool {
self.indices[label.value].is_some()
}
}
impl<T: Copy + fmt::Display> fmt::Display for Bag<T> {
impl<T: fmt::Display> fmt::Display for Bag<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.labels.iter().try_for_each(|element| match element {
None => Ok(()),
......@@ -199,6 +207,14 @@ impl<T: Copy + fmt::Display> fmt::Display for Bag<T> {
}
}
impl<T> Index<usize> for Bag<T> {
type Output = Option<Label<T>>;
fn index(&self, index: usize) -> &Self::Output {
&self.labels[index]
}
}
#[cfg(test)]
mod tests {
use super::*;
......
......@@ -69,7 +69,7 @@ impl Triangulation {
}
pub fn insert_tet(&mut self, tet_vertices: [Label<Vertex>; 4]) -> Label<HalfEdge> {
let index = self.half_edges.next_label_value();
let index = self.half_edges.current_hole();
(0..12).for_each(|i| {
let adj_ext = Label::<HalfEdge>::from(index + ADJ_EXT[i]);
let vertex_tail = tet_vertices[VERTICES[i][0]];
......@@ -86,7 +86,7 @@ impl Triangulation {
}
pub fn remove_tet(&mut self, label: Label<HalfEdge>) {
let index = (label.value / 12) * 12;
let index = (label.value() / 12) * 12;
(0..12).rev().for_each(|i| {
let label = Label::<HalfEdge>::from(index + i);
self.half_edges.remove(label);
......@@ -126,12 +126,12 @@ pub struct HalfEdge {
impl Label<HalfEdge> {
pub fn next(&self) -> Label<HalfEdge> {
let val = self.value;
let val = self.value();
Label::<HalfEdge>::from((val / 12) * 12 + NEXT[val % 12])
}
pub fn adj_int(&self) -> Label<HalfEdge> {
let val = self.value;
let val = self.value();
Label::<HalfEdge>::from((val / 12) * 12 + ADJ_INT[val % 12])
}
......@@ -141,7 +141,7 @@ impl Label<HalfEdge> {
#[cfg(test)]
pub fn vertices(&self, half_edges: &Pool<HalfEdge>) -> [Label<Vertex>; 4] {
let val = (self.value / 12) * 12;
let val = (self.value() / 12) * 12;
let label01 = Label::<HalfEdge>::from(val);
let label23 = Label::<HalfEdge>::from(val + 6);
let v0 = half_edges[label01].vertex_tail;
......@@ -152,7 +152,7 @@ impl Label<HalfEdge> {
}
pub fn same_tetrahedron(&self, other: Label<HalfEdge>) -> bool {
self.value / 12 == other.value / 12
self.value() / 12 == other.value() / 12
}
}
......@@ -272,7 +272,8 @@ mod tests {
println!("checked {}!", i);
});
(0..500).for_each(|i| {
let label = triangulation.half_edge_bag.sample();
let label_index = fastrand::usize(0..(triangulation.half_edge_bag.size()));
let label = triangulation.half_edge_bag[label_index].unwrap();
let vertices = label.vertices(&triangulation.half_edges);
let label_v0 = vertices[0];
let label_v1 = vertices[2];
......@@ -294,7 +295,8 @@ mod tests {
println!("checked {}!", i);
});
(0..800).for_each(|i| {
let label = triangulation.half_edge_bag.sample();
let label_index = fastrand::usize(0..(triangulation.half_edge_bag.size()));
let label = triangulation.half_edge_bag[label_index].unwrap();
let vertices = label.vertices(&triangulation.half_edges);
let label_v0 = vertices[0];
let label_v1 = vertices[2];
......
......@@ -36,7 +36,8 @@ impl Triangulation {
}
fn tetrahedron_distance(&self) -> DistanceProfile {
let _origin = self.half_edge_bag.sample();
let label_index = fastrand::usize(0..(self.half_edge_bag.size()));
let _origin = self.half_edge_bag[label_index].unwrap();
DistanceProfile {
profile: vec![1, 2, 3],
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment