use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
#[derive(Debug, Clone)]
enum DenseMapBucket<K, V> {
Empty,
Tombstone,
Full { key: K, value: V },
}
impl<K, V> DenseMapBucket<K, V> {
fn value(&self) -> Option<&V> {
match self {
DenseMapBucket::Full { value, .. } => Some(value),
_ => None,
}
}
fn value_mut(&mut self) -> Option<&mut V> {
match self {
DenseMapBucket::Full { value, .. } => Some(value),
_ => None,
}
}
fn take(&mut self) -> Option<(K, V)> {
match self {
DenseMapBucket::Full { .. } => {
let old = std::mem::replace(self, DenseMapBucket::Tombstone);
match old {
DenseMapBucket::Full { key, value } => Some((key, value)),
_ => unreachable!(),
}
}
_ => None,
}
}
}
pub struct DenseMap<K, V>
where
K: Eq + Hash + Clone,
V: Clone,
{
buckets: Vec<DenseMapBucket<K, V>>,
num_entries: usize,
num_tombstones: usize,
}
impl<K, V> DenseMap<K, V>
where
K: Eq + Hash + Clone,
V: Clone,
{
fn hash_key(key: &K) -> u64 {
let mut hasher = DefaultHasher::new();
key.hash(&mut hasher);
hasher.finish()
}
const MIN_CAPACITY: usize = 8;
fn needs_grow(&self) -> bool {
let cap = self.buckets.len();
if cap == 0 {
return true;
}
(self.num_entries + self.num_tombstones) * 4 > cap * 3
}
fn next_capacity(desired: usize) -> usize {
let min = Self::MIN_CAPACITY;
let target = std::cmp::max(desired, min);
if target.is_power_of_two() {
target
} else {
target.next_power_of_two()
}
}
fn rehash(&mut self, new_capacity: usize) {
debug_assert!(new_capacity.is_power_of_two());
debug_assert!(new_capacity >= self.num_entries);
let mut new_buckets: Vec<DenseMapBucket<K, V>> =
(0..new_capacity).map(|_| DenseMapBucket::Empty).collect();
for bucket in self.buckets.iter_mut() {
if let DenseMapBucket::Full { .. } = bucket {
if let Some((key, value)) = bucket.take() {
let hash = Self::hash_key(&key);
let mask = new_capacity - 1;
let mut idx = (hash as usize) & mask;
loop {
match &new_buckets[idx] {
DenseMapBucket::Empty => {
new_buckets[idx] = DenseMapBucket::Full { key, value };
break;
}
_ => {
idx = (idx + 1) & mask;
}
}
}
}
}
}
self.buckets = new_buckets;
self.num_tombstones = 0;
}
fn find_bucket(&self, key: &K) -> (usize, bool) {
let cap = self.buckets.len();
if cap == 0 {
return (0, false);
}
let hash = Self::hash_key(key);
let mask = cap - 1;
let mut idx = (hash as usize) & mask;
let mut first_tombstone: Option<usize> = None;
loop {
match &self.buckets[idx] {
DenseMapBucket::Empty => {
let slot = first_tombstone.unwrap_or(idx);
return (slot, false);
}
DenseMapBucket::Tombstone => {
if first_tombstone.is_none() {
first_tombstone = Some(idx);
}
}
DenseMapBucket::Full { key: k, .. } => {
if *k == *key {
return (idx, true);
}
}
}
idx = (idx + 1) & mask;
}
}
fn ensure_capacity(&mut self, additional: usize) {
let needed = self.num_entries + additional;
if self.buckets.len() == 0 || needed * 4 > self.buckets.len() * 3 {
let new_cap = Self::next_capacity(needed * 4 / 3 + 1);
self.rehash(new_cap);
} else if self.needs_grow() {
self.rehash(self.buckets.len());
}
}
}
impl<K, V> DenseMap<K, V>
where
K: Eq + Hash + Clone,
V: Clone,
{
#[inline]
pub fn new() -> Self {
DenseMap {
buckets: Vec::new(),
num_entries: 0,
num_tombstones: 0,
}
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
let cap = Self::next_capacity(capacity);
DenseMap {
buckets: (0..cap).map(|_| DenseMapBucket::Empty).collect(),
num_entries: 0,
num_tombstones: 0,
}
}
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
if self.buckets.is_empty() {
self.buckets = (0..Self::MIN_CAPACITY)
.map(|_| DenseMapBucket::Empty)
.collect();
}
if self.needs_grow() {
let new_cap = if self.buckets.is_empty() {
Self::MIN_CAPACITY
} else {
self.buckets.len() * 2
};
self.rehash(new_cap);
}
let (idx, present) = self.find_bucket(&key);
if present {
match &mut self.buckets[idx] {
DenseMapBucket::Full {
value: existing, ..
} => {
let old = existing.clone();
*existing = value;
Some(old)
}
_ => unreachable!(),
}
} else {
match &self.buckets[idx] {
DenseMapBucket::Tombstone => {
self.num_tombstones -= 1;
}
_ => {}
}
self.buckets[idx] = DenseMapBucket::Full { key, value };
self.num_entries += 1;
None
}
}
pub fn get(&self, key: &K) -> Option<&V> {
let (idx, present) = self.find_bucket(key);
if present {
self.buckets[idx].value()
} else {
None
}
}
pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
let (idx, present) = self.find_bucket(key);
if present {
self.buckets[idx].value_mut()
} else {
None
}
}
pub fn remove(&mut self, key: &K) -> Option<V> {
let (idx, present) = self.find_bucket(key);
if present {
match self.buckets[idx].take() { Some((_key, value)) => {
self.num_entries -= 1;
self.num_tombstones += 1;
Some(value)
} _ => {
None
}}
} else {
None
}
}
#[inline]
pub fn contains_key(&self, key: &K) -> bool {
self.get(key).is_some()
}
#[inline]
pub fn len(&self) -> usize {
self.num_entries
}
#[inline]
pub fn is_empty(&self) -> bool {
self.num_entries == 0
}
#[inline]
pub fn capacity(&self) -> usize {
self.buckets.len()
}
pub fn clear(&mut self) {
self.buckets.clear();
self.num_entries = 0;
self.num_tombstones = 0;
}
pub fn reserve(&mut self, additional: usize) {
self.ensure_capacity(additional);
}
pub fn shrink_to_fit(&mut self) {
if self.num_entries == 0 {
self.buckets.clear();
self.num_tombstones = 0;
return;
}
let new_cap = Self::next_capacity(self.num_entries);
if new_cap < self.buckets.len() {
self.rehash(new_cap);
}
}
#[inline]
pub fn iter(&self) -> DenseMapIter<'_, K, V> {
DenseMapIter {
buckets: &self.buckets,
index: 0,
}
}
pub fn keys(&self) -> impl Iterator<Item = &K> {
self.iter().map(|(k, _)| k)
}
pub fn values(&self) -> impl Iterator<Item = &V> {
self.iter().map(|(_, v)| v)
}
pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
DenseMapIterMut {
buckets: &mut self.buckets,
index: 0,
}
}
}
impl<K, V> Default for DenseMap<K, V>
where
K: Eq + Hash + Clone,
V: Clone,
{
fn default() -> Self {
Self::new()
}
}
impl<K, V> std::fmt::Debug for DenseMap<K, V>
where
K: Eq + Hash + Clone + std::fmt::Debug,
V: Clone + std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_map().entries(self.iter()).finish()
}
}
impl<K, V> PartialEq for DenseMap<K, V>
where
K: Eq + Hash + Clone,
V: Clone + PartialEq,
{
fn eq(&self, other: &Self) -> bool {
if self.len() != other.len() {
return false;
}
for (k, v) in self.iter() {
match other.get(k) {
Some(other_v) if *v == *other_v => {}
_ => return false,
}
}
true
}
}
impl<K, V> IntoIterator for DenseMap<K, V>
where
K: Eq + Hash + Clone,
V: Clone,
{
type Item = (K, V);
type IntoIter = DenseMapIntoIter<K, V>;
fn into_iter(self) -> Self::IntoIter {
DenseMapIntoIter {
buckets: self.buckets,
index: 0,
}
}
}
pub struct DenseMapIntoIter<K, V> {
buckets: Vec<DenseMapBucket<K, V>>,
index: usize,
}
impl<K, V> Iterator for DenseMapIntoIter<K, V> {
type Item = (K, V);
fn next(&mut self) -> Option<Self::Item> {
while self.index < self.buckets.len() {
match self.buckets[self.index].take() {
Some((key, value)) => {
self.index += 1;
return Some((key, value));
}
None => {
self.index += 1;
}
}
}
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.buckets.len() - self.index;
(0, Some(remaining))
}
}
pub struct DenseMapIter<'a, K, V> {
buckets: &'a [DenseMapBucket<K, V>],
index: usize,
}
impl<'a, K, V> Iterator for DenseMapIter<'a, K, V> {
type Item = (&'a K, &'a V);
fn next(&mut self) -> Option<Self::Item> {
while self.index < self.buckets.len() {
match &self.buckets[self.index] {
DenseMapBucket::Full { key, value } => {
self.index += 1;
return Some((key, value));
}
_ => {
self.index += 1;
}
}
}
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.buckets.len() - self.index;
(0, Some(remaining))
}
}
pub struct DenseMapIterMut<'a, K, V> {
buckets: &'a mut [DenseMapBucket<K, V>],
index: usize,
}
impl<'a, K, V> Iterator for DenseMapIterMut<'a, K, V> {
type Item = &'a mut V;
fn next(&mut self) -> Option<Self::Item> {
while self.index < self.buckets.len() {
let ptr = self.buckets.as_mut_ptr();
unsafe {
let bucket = &mut *ptr.add(self.index);
match bucket {
DenseMapBucket::Full { value, .. } => {
self.index += 1;
return Some(value);
}
_ => {
self.index += 1;
}
}
}
}
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.buckets.len() - self.index;
(0, Some(remaining))
}
}
impl<'a, K, V> IntoIterator for &'a DenseMap<K, V>
where
K: Eq + Hash + Clone,
V: Clone,
{
type Item = (&'a K, &'a V);
type IntoIter = DenseMapIter<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, K, V> IntoIterator for &'a mut DenseMap<K, V>
where
K: Eq + Hash + Clone,
V: Clone,
{
type Item = (&'a K, &'a mut V);
type IntoIter = DenseMapIterMutRef<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
DenseMapIterMutRef {
buckets: &mut self.buckets,
index: 0,
}
}
}
pub struct DenseMapIterMutRef<'a, K, V> {
buckets: &'a mut [DenseMapBucket<K, V>],
index: usize,
}
impl<'a, K, V> Iterator for DenseMapIterMutRef<'a, K, V> {
type Item = (&'a K, &'a mut V);
fn next(&mut self) -> Option<Self::Item> {
while self.index < self.buckets.len() {
let ptr = self.buckets.as_mut_ptr();
unsafe {
let bucket = &mut *ptr.add(self.index);
match bucket {
DenseMapBucket::Full { key, value } => {
self.index += 1;
return Some((&*key, value));
}
_ => {
self.index += 1;
}
}
}
}
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.buckets.len() - self.index;
(0, Some(remaining))
}
}
impl<K, V> Clone for DenseMap<K, V>
where
K: Eq + Hash + Clone,
V: Clone,
{
fn clone(&self) -> Self {
DenseMap {
buckets: self.buckets.clone(),
num_entries: self.num_entries,
num_tombstones: self.num_tombstones,
}
}
}
pub struct DenseSet<T>
where
T: Eq + Hash + Clone,
{
map: DenseMap<T, ()>,
}
impl<T> DenseSet<T>
where
T: Eq + Hash + Clone,
{
#[inline]
pub fn new() -> Self {
DenseSet {
map: DenseMap::new(),
}
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
DenseSet {
map: DenseMap::with_capacity(capacity),
}
}
#[inline]
pub fn insert(&mut self, value: T) -> bool {
self.map.insert(value, ()).is_none()
}
#[inline]
pub fn remove(&mut self, value: &T) -> bool {
self.map.remove(value).is_some()
}
#[inline]
pub fn contains(&self, value: &T) -> bool {
self.map.contains_key(value)
}
#[inline]
pub fn len(&self) -> usize {
self.map.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
#[inline]
pub fn clear(&mut self) {
self.map.clear();
}
#[inline]
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.map.keys()
}
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.map.reserve(additional);
}
#[inline]
pub fn capacity(&self) -> usize {
self.map.capacity()
}
}
impl<T> Default for DenseSet<T>
where
T: Eq + Hash + Clone,
{
fn default() -> Self {
Self::new()
}
}
impl<T> IntoIterator for DenseSet<T>
where
T: Eq + Hash + Clone,
{
type Item = T;
type IntoIter = DenseSetIntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
DenseSetIntoIter {
inner: self.map.into_iter(),
}
}
}
pub struct DenseSetIntoIter<T> {
inner: DenseMapIntoIter<T, ()>,
}
impl<T> Iterator for DenseSetIntoIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(k, _)| k)
}
}
impl<'a, T> IntoIterator for &'a DenseSet<T>
where
T: Eq + Hash + Clone,
{
type Item = &'a T;
type IntoIter = DenseSetIter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
DenseSetIter {
inner: self.map.iter(),
}
}
}
pub struct DenseSetIter<'a, T> {
inner: DenseMapIter<'a, T, ()>,
}
impl<'a, T> Iterator for DenseSetIter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(k, _)| k)
}
}
impl<T> std::fmt::Debug for DenseSet<T>
where
T: Eq + Hash + Clone + std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}
impl<T> PartialEq for DenseSet<T>
where
T: Eq + Hash + Clone,
{
fn eq(&self, other: &Self) -> bool {
if self.len() != other.len() {
return false;
}
for item in self.iter() {
if !other.contains(item) {
return false;
}
}
true
}
}
impl<T> Clone for DenseSet<T>
where
T: Eq + Hash + Clone,
{
fn clone(&self) -> Self {
DenseSet {
map: self.map.clone(),
}
}
}
pub struct SmallDenseMap<K, V, const N: usize>
where
K: Eq + Hash + Clone,
V: Clone,
{
inner: DenseMap<K, V>,
}
impl<K, V, const N: usize> SmallDenseMap<K, V, N>
where
K: Eq + Hash + Clone,
V: Clone,
{
pub fn new() -> Self {
SmallDenseMap {
inner: DenseMap::with_capacity(N),
}
}
#[inline]
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
self.inner.insert(key, value)
}
#[inline]
pub fn get(&self, key: &K) -> Option<&V> {
self.inner.get(key)
}
#[inline]
pub fn contains_key(&self, key: &K) -> bool {
self.inner.contains_key(key)
}
#[inline]
pub fn len(&self) -> usize {
self.inner.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
}
impl<K, V, const N: usize> Default for SmallDenseMap<K, V, N>
where
K: Eq + Hash + Clone,
V: Clone,
{
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_map_is_empty() {
let map: DenseMap<i32, i32> = DenseMap::new();
assert!(map.is_empty());
assert_eq!(map.len(), 0);
}
#[test]
fn test_with_capacity() {
let map: DenseMap<i32, i32> = DenseMap::with_capacity(16);
assert!(map.is_empty());
assert!(map.capacity() >= 16);
}
#[test]
fn test_insert_and_get() {
let mut map = DenseMap::new();
assert_eq!(map.insert("hello", 42), None);
assert_eq!(map.get(&"hello"), Some(&42));
assert_eq!(map.get(&"world"), None);
}
#[test]
fn test_insert_replace() {
let mut map = DenseMap::new();
map.insert("key", 1);
assert_eq!(map.insert("key", 2), Some(1));
assert_eq!(map.get(&"key"), Some(&2));
assert_eq!(map.len(), 1);
}
#[test]
fn test_insert_many() {
let mut map = DenseMap::new();
for i in 0..1000 {
map.insert(i, i * 2);
}
assert_eq!(map.len(), 1000);
for i in 0..1000 {
assert_eq!(map.get(&i), Some(&(i * 2)));
}
}
#[test]
fn test_contains_key() {
let mut map = DenseMap::new();
map.insert("a", 1);
assert!(map.contains_key(&"a"));
assert!(!map.contains_key(&"b"));
}
#[test]
fn test_remove() {
let mut map = DenseMap::new();
map.insert("a", 1);
map.insert("b", 2);
assert_eq!(map.remove(&"a"), Some(1));
assert_eq!(map.get(&"a"), None);
assert_eq!(map.len(), 1);
assert_eq!(map.get(&"b"), Some(&2));
}
#[test]
fn test_remove_nonexistent() {
let mut map: DenseMap<i32, i32> = DenseMap::new();
assert_eq!(map.remove(&42), None);
}
#[test]
fn test_remove_then_reinsert() {
let mut map = DenseMap::new();
map.insert("key", 1);
map.remove(&"key");
assert_eq!(map.insert("key", 2), None);
assert_eq!(map.get(&"key"), Some(&2));
assert_eq!(map.len(), 1);
}
#[test]
fn test_remove_tombstone_probe_chain() {
let mut map = DenseMap::new();
map.insert(1, "one");
map.insert(17, "seventeen"); map.remove(&1);
assert_eq!(map.get(&17), Some(&"seventeen"));
}
#[test]
fn test_clear() {
let mut map = DenseMap::new();
map.insert("a", 1);
map.insert("b", 2);
map.clear();
assert!(map.is_empty());
assert_eq!(map.len(), 0);
assert_eq!(map.get(&"a"), None);
}
#[test]
fn test_len_and_capacity() {
let mut map = DenseMap::with_capacity(8);
assert_eq!(map.len(), 0);
assert_eq!(map.capacity(), 8);
map.insert(1, "a");
assert_eq!(map.len(), 1);
assert!(!map.is_empty());
}
#[test]
fn test_iter() {
let mut map = DenseMap::new();
map.insert("a", 1);
map.insert("b", 2);
map.insert("c", 3);
let mut collected: Vec<(&str, i32)> = map.iter().map(|(k, v)| (*k, *v)).collect();
collected.sort_by_key(|(k, _)| *k);
assert_eq!(collected, vec![("a", 1), ("b", 2), ("c", 3)]);
}
#[test]
fn test_keys_and_values() {
let mut map = DenseMap::new();
map.insert("x", 10);
map.insert("y", 20);
let mut keys: Vec<&&str> = map.keys().collect();
keys.sort();
assert_eq!(keys, vec![&"x", &"y"]);
let mut values: Vec<&i32> = map.values().collect();
values.sort();
assert_eq!(values, vec![&10, &20]);
}
#[test]
fn test_values_mut() {
let mut map = DenseMap::new();
map.insert("a", 1);
map.insert("b", 2);
for v in map.values_mut() {
*v *= 10;
}
let mut values: Vec<i32> = map.values().copied().collect();
values.sort();
assert_eq!(values, vec![10, 20]);
}
#[test]
fn test_iter_empty() {
let map: DenseMap<i32, i32> = DenseMap::new();
assert_eq!(map.iter().count(), 0);
}
#[test]
fn test_into_iter_owned() {
let mut map = DenseMap::new();
map.insert(1, "one");
map.insert(2, "two");
let mut collected: Vec<(i32, &str)> = map.into_iter().collect();
collected.sort_by_key(|(k, _)| *k);
assert_eq!(collected, vec![(1, "one"), (2, "two")]);
}
#[test]
fn test_into_iter_ref() {
let mut map = DenseMap::new();
map.insert("a", 1);
map.insert("b", 2);
let mut collected: Vec<(&str, &i32)> = (&map).into_iter().map(|(k, v)| (*k, v)).collect();
collected.sort_by_key(|(k, _)| *k);
assert_eq!(collected, vec![("a", &1), ("b", &2)]);
}
#[test]
fn test_into_iter_mut() {
let mut map = DenseMap::new();
map.insert("a", 1);
map.insert("b", 2);
for (k, v) in &mut map {
*v *= 10;
}
assert_eq!(map.get(&"a"), Some(&10));
assert_eq!(map.get(&"b"), Some(&20));
}
#[test]
fn test_reserve() {
let mut map: DenseMap<i32, i32> = DenseMap::new();
let cap_before = map.capacity();
map.reserve(100);
assert!(map.capacity() >= 100);
}
#[test]
fn test_shrink_to_fit() {
let mut map = DenseMap::with_capacity(64);
map.insert(1, "a");
map.insert(2, "b");
map.shrink_to_fit();
assert!(map.capacity() <= 16); assert_eq!(map.len(), 2);
}
#[test]
fn test_shrink_to_fit_empty() {
let mut map: DenseMap<i32, i32> = DenseMap::with_capacity(64);
map.shrink_to_fit();
assert_eq!(map.capacity(), 0);
}
#[test]
fn test_clone() {
let mut map = DenseMap::new();
map.insert("a", 1);
map.insert("b", 2);
let cloned = map.clone();
assert_eq!(cloned.len(), map.len());
assert_eq!(cloned.get(&"a"), Some(&1));
assert_eq!(cloned.get(&"b"), Some(&2));
drop(cloned);
assert_eq!(map.get(&"a"), Some(&1));
}
#[test]
fn test_eq() {
let mut a = DenseMap::new();
a.insert("x", 1);
a.insert("y", 2);
let mut b = DenseMap::new();
b.insert("y", 2);
b.insert("x", 1);
assert_eq!(a, b);
let mut c = DenseMap::new();
c.insert("x", 1);
c.insert("y", 3);
assert_ne!(a, c);
}
#[test]
fn test_debug() {
let mut map = DenseMap::new();
map.insert("key", 42);
let debug_str = format!("{:?}", map);
assert!(debug_str.contains("key"));
assert!(debug_str.contains("42"));
}
#[test]
fn test_stress_insert_remove() {
let mut map = DenseMap::new();
let n = 500;
for i in 0..n {
map.insert(i, format!("val-{}", i));
}
assert_eq!(map.len(), n);
for i in 0..n {
assert_eq!(
map.get(&i).map(|s| s.as_str()),
Some(format!("val-{}", i).as_str())
);
}
for i in 0..n / 2 {
map.remove(&i);
}
assert_eq!(map.len(), n - n / 2);
for i in n / 2..n {
assert!(map.contains_key(&i));
}
for i in 0..n / 2 {
map.insert(i, format!("new-{}", i));
}
assert_eq!(map.len(), n);
}
#[test]
fn test_many_tombstones() {
let mut map = DenseMap::new();
for i in 0..100 {
map.insert(i, i);
}
for i in 0..100 {
map.remove(&i);
}
assert_eq!(map.len(), 0);
assert!(map.is_empty());
for i in 0..100 {
map.insert(i, i + 100);
}
assert_eq!(map.len(), 100);
for i in 0..100 {
assert_eq!(map.get(&i), Some(&(i + 100)));
}
}
#[test]
fn test_dense_set_basic() {
let mut set = DenseSet::new();
assert!(set.is_empty());
assert!(set.insert(1));
assert!(!set.insert(1)); assert!(set.insert(2));
assert_eq!(set.len(), 2);
assert!(set.contains(&1));
assert!(set.contains(&2));
assert!(!set.contains(&3));
}
#[test]
fn test_dense_set_remove() {
let mut set = DenseSet::new();
set.insert("a");
set.insert("b");
assert!(set.remove(&"a"));
assert!(!set.contains(&"a"));
assert!(set.contains(&"b"));
assert!(!set.remove(&"a")); }
#[test]
fn test_dense_set_iter() {
let mut set = DenseSet::new();
set.insert(3);
set.insert(1);
set.insert(2);
let mut collected: Vec<i32> = set.iter().copied().collect();
collected.sort();
assert_eq!(collected, vec![1, 2, 3]);
}
#[test]
fn test_dense_set_clear() {
let mut set = DenseSet::new();
set.insert(1);
set.insert(2);
set.clear();
assert!(set.is_empty());
assert!(!set.contains(&1));
}
#[test]
fn test_dense_set_eq() {
let mut a = DenseSet::new();
a.insert("x");
a.insert("y");
let mut b = DenseSet::new();
b.insert("y");
b.insert("x");
assert_eq!(a, b);
let mut c = DenseSet::new();
c.insert("x");
assert_ne!(a, c);
}
#[test]
fn test_dense_set_into_iter() {
let mut set = DenseSet::new();
set.insert("a");
set.insert("b");
let mut collected: Vec<&str> = set.into_iter().collect();
collected.sort();
assert_eq!(collected, vec!["a", "b"]);
}
#[test]
fn test_dense_set_capacity() {
let set: DenseSet<i32> = DenseSet::with_capacity(32);
assert!(set.capacity() >= 32);
assert!(set.is_empty());
}
#[test]
fn test_dense_set_debug() {
let mut set = DenseSet::new();
set.insert(1);
set.insert(2);
let debug_str = format!("{:?}", set);
assert!(debug_str.contains('1'));
assert!(debug_str.contains('2'));
}
#[test]
fn test_small_dense_map_basic() {
let mut map: SmallDenseMap<&str, i32, 4> = SmallDenseMap::new();
assert!(map.is_empty());
map.insert("a", 1);
map.insert("b", 2);
assert_eq!(map.len(), 2);
assert!(map.contains_key(&"a"));
assert_eq!(map.get(&"a"), Some(&1));
assert_eq!(map.get(&"b"), Some(&2));
assert_eq!(map.get(&"c"), None);
}
#[test]
fn test_small_dense_map_insert_replace() {
let mut map: SmallDenseMap<i32, i32, 8> = SmallDenseMap::new();
assert_eq!(map.insert(1, 100), None);
assert_eq!(map.insert(1, 200), Some(100));
assert_eq!(map.get(&1), Some(&200));
}
#[test]
fn test_small_dense_map_over_inline() {
let mut map: SmallDenseMap<i32, i32, 2> = SmallDenseMap::new();
for i in 0..10 {
map.insert(i, i * 10);
}
assert_eq!(map.len(), 10);
for i in 0..10 {
assert_eq!(map.get(&i), Some(&(i * 10)));
}
}
#[test]
fn test_small_dense_map_default() {
let map: SmallDenseMap<i32, i32, 8> = SmallDenseMap::default();
assert!(map.is_empty());
}
#[test]
fn test_string_keys() {
let mut map = DenseMap::new();
map.insert("hello".to_string(), 1);
map.insert("world".to_string(), 2);
assert_eq!(map.get(&"hello".to_string()), Some(&1));
assert_eq!(map.remove(&"world".to_string()), Some(2));
assert!(!map.contains_key(&"world".to_string()));
}
#[test]
fn test_get_mut() {
let mut map = DenseMap::new();
map.insert("key", vec![1, 2, 3]);
if let Some(v) = map.get_mut(&"key") {
v.push(4);
}
assert_eq!(map.get(&"key"), Some(&vec![1, 2, 3, 4]));
}
#[test]
fn test_growth_on_insert() {
let mut map: DenseMap<i32, i32> = DenseMap::with_capacity(4);
let initial_cap = map.capacity();
for i in 0..100 {
map.insert(i, i);
}
assert!(map.capacity() > initial_cap);
assert_eq!(map.len(), 100);
}
}