use HashSet internally inside SelectorHashSet

This commit is contained in:
Connor Skees 2020-07-03 20:55:02 -04:00
parent 192d18c2ac
commit c66ecdd57d

View File

@ -1,8 +1,8 @@
use std::{ use std::{
cell::RefCell, cell::RefCell,
collections::{hash_set::IntoIter, HashSet},
hash::{Hash, Hasher}, hash::{Hash, Hasher},
rc::Rc, rc::Rc,
vec::IntoIter
}; };
use crate::selector::{Selector, SelectorList}; use crate::selector::{Selector, SelectorList};
@ -38,23 +38,23 @@ impl ExtendedSelector {
} }
} }
/// We could use a `HashSet` here, but since selectors are /// There is the potential for danger here by modifying the hash
/// in a `RefCell`, we may unintentionally cause (library) UB. /// through `RefCell`, but I haven't come up with a good solution
/// for this yet (we can't just use a `Vec` because linear insert)
/// is too big of a penalty
/// ///
/// Initial benchmarking found that a `Vec` was actually *faster* /// In pratice, I have yet to find a test case that can demonstrate
/// than a `HashSet`, the reason for which I am unsure. /// an issue with storing a `RefCell`.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub(crate) struct SelectorHashSet(Vec<ExtendedSelector>); pub(crate) struct SelectorHashSet(HashSet<ExtendedSelector>);
impl SelectorHashSet { impl SelectorHashSet {
pub const fn new() -> Self { pub fn new() -> Self {
Self(Vec::new()) Self(HashSet::new())
} }
pub fn insert(&mut self, selector: ExtendedSelector) { pub fn insert(&mut self, selector: ExtendedSelector) {
if !self.0.contains(&selector) { self.0.insert(selector);
self.0.push(selector);
}
} }
pub fn into_iter(self) -> IntoIter<ExtendedSelector> { pub fn into_iter(self) -> IntoIter<ExtendedSelector> {