use std::{
fmt,
iter::{self, FusedIterator},
marker::PhantomData,
ops::{Index, IndexMut},
slice,
};
use serde::{Deserialize, Serialize};
use smol_bitmap::SmolBitmap;
use crate::{sparse_index::TrySparseIndex, sparse_set::SparseSet};
pub struct SparseMap<K, V> {
bits: SmolBitmap,
values: Vec<V>,
_phantom: PhantomData<K>,
}
impl<K, V: Clone> Clone for SparseMap<K, V> {
fn clone(&self) -> Self {
Self { bits: self.bits.clone(), values: self.values.clone(), _phantom: PhantomData }
}
}
impl<K: TrySparseIndex + fmt::Debug, V: fmt::Debug> fmt::Debug for SparseMap<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut s = f.debug_map();
for (index, value) in self {
s.entry(&index, &value);
}
s.finish()
}
}
impl<K: TrySparseIndex + Serialize, V: Serialize> Serialize for SparseMap<K, V> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if serializer.is_human_readable() {
use serde::ser::SerializeSeq;
let mut seq = serializer.serialize_seq(Some(self.len()))?;
for (index, value) in self {
seq.serialize_element(&(index, value))?;
}
seq.end()
} else {
use serde::ser::SerializeTuple;
let mut tuple = serializer.serialize_tuple(2)?;
tuple.serialize_element(&self.bits)?;
tuple.serialize_element(&self.values)?;
tuple.end()
}
}
}
impl<'de, K: TrySparseIndex + Deserialize<'de>, V: Deserialize<'de>> Deserialize<'de>
for SparseMap<K, V>
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
if deserializer.is_human_readable() {
use std::fmt;
use serde::de::{SeqAccess, Visitor};
struct SparseMapVisitor<K, V> {
_phantom: PhantomData<(K, V)>,
}
impl<'de, K: TrySparseIndex + Deserialize<'de>, V: Deserialize<'de>> Visitor<'de>
for SparseMapVisitor<K, V>
{
type Value = SparseMap<K, V>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence of (index, value) pairs")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut map = SparseMap::new();
if let Some(len) = seq.size_hint() {
map.reserve(len);
}
let mut prev_index = None;
while let Some((index, value)) = seq.next_element::<(K, V)>()? {
let index = index.index();
if prev_index.is_some_and(|prev| prev >= index) {
return Err(serde::de::Error::invalid_value(
serde::de::Unexpected::Unsigned(index as u64),
&"indices must be in ascending order",
));
}
prev_index = Some(index);
map.bits.insert(index);
map.values.push(value);
}
Ok(map)
}
}
deserializer.deserialize_seq(SparseMapVisitor { _phantom: PhantomData })
} else {
let (bits, values): (SmolBitmap, Vec<V>) = Deserialize::deserialize(deserializer)?;
if bits.count_ones() != values.len() {
return Err(serde::de::Error::invalid_length(
values.len(),
&"as many values as set bits in the occupancy bitmap",
));
}
K::validate_sorted(bits.iter()).map_err(serde::de::Error::custom)?;
Ok(Self { bits, values, _phantom: PhantomData })
}
}
}
impl<K, V> Default for SparseMap<K, V> {
fn default() -> Self {
Self::new()
}
}
impl<K, V: PartialEq> PartialEq for SparseMap<K, V> {
fn eq(&self, other: &Self) -> bool {
self.bits == other.bits && self.values == other.values
}
}
impl<K, V: Eq> Eq for SparseMap<K, V> {}
impl<K, V> SparseMap<K, V> {
pub fn from_sequence(values: Vec<V>) -> Self {
let len = values.len();
let mut bits = SmolBitmap::with_capacity(len);
for i in 0..len {
bits.insert(i);
}
Self { bits, values, _phantom: PhantomData }
}
pub const fn new() -> Self {
Self { bits: SmolBitmap::new(), values: Vec::new(), _phantom: PhantomData }
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
bits: SmolBitmap::with_capacity(capacity),
values: Vec::with_capacity(capacity),
_phantom: PhantomData,
}
}
#[inline]
pub const fn len(&self) -> usize {
self.values.len()
}
#[inline]
pub const fn is_empty(&self) -> bool {
self.values.is_empty()
}
#[inline]
pub const fn capacity(&self) -> usize {
self.bits.capacity()
}
pub fn clear(&mut self) {
self.bits.clear();
self.values.clear();
}
pub fn shrink_to_fit(&mut self) {
self.bits.shrink_to_fit();
self.values.shrink_to_fit();
}
pub fn reserve(&mut self, additional: usize) {
self.bits.reserve(additional);
self.values.reserve(additional);
}
pub const fn key_set(&self) -> &SparseSet<K> {
unsafe { &*(&raw const self.bits).cast::<SparseSet<K>>() }
}
#[inline]
pub fn into_parts(self) -> (SmolBitmap, Vec<V>) {
(self.bits, self.values)
}
#[inline]
pub fn from_parts(bits: SmolBitmap, values: Vec<V>) -> Self {
assert_eq!(bits.count_ones(), values.len(), "bitmap and values length mismatch");
Self { bits, values, _phantom: PhantomData }
}
}
impl<K: TrySparseIndex, V> SparseMap<K, V> {
#[inline]
pub fn get(&self, key: K) -> Option<&V> {
let index = key.index();
if self.bits.get(index) {
self.values.get(self.bits.rank(index))
} else {
None
}
}
#[inline]
pub fn get_mut(&mut self, key: K) -> Option<&mut V> {
let index = key.index();
if self.bits.get(index) {
let pos = self.bits.rank(index);
self.values.get_mut(pos)
} else {
None
}
}
#[inline]
pub fn get_or_insert(&mut self, key: K, value: V) -> &mut V {
let index = key.index();
let pos = if self.bits.insert(index) {
let pos = self.bits.rank(index);
self.values.insert(pos, value);
pos
} else {
self.bits.rank(index)
};
&mut self.values[pos]
}
#[inline]
pub fn get_or_insert_with<F>(&mut self, key: K, f: F) -> &mut V
where
F: FnOnce() -> V,
{
let index = key.index();
let pos = if self.bits.insert(index) {
let pos = self.bits.rank(index);
self.values.insert(pos, f());
pos
} else {
self.bits.rank(index)
};
&mut self.values[pos]
}
#[inline]
pub fn contains_key(&self, key: K) -> bool {
self.bits.get(key.index())
}
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
let index = key.index();
let pos = self.bits.rank(index);
if self.bits.insert(index) {
self.values.insert(pos, value);
None
} else {
Some(std::mem::replace(&mut self.values[pos], value))
}
}
pub fn remove(&mut self, key: K) -> Option<V> {
let index = key.index();
if self.bits.remove(index) {
let pos = self.bits.rank(index);
Some(self.values.remove(pos))
} else {
None
}
}
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(K, &mut V) -> bool,
{
let mut write_idx = 0;
let mut read_idx = 0;
self.bits.retain(|idx| {
let key = K::from_index(idx);
let should_retain = f(key, &mut self.values[read_idx]);
if should_retain {
if write_idx != read_idx {
self.values.swap(write_idx, read_idx);
}
write_idx += 1;
}
read_idx += 1;
should_retain
});
self.values.truncate(write_idx);
}
#[define_opaque(Iter)]
pub fn iter(&self) -> Iter<'_, K, V> {
iter::zip(self.bits.iter().map(K::from_index), self.values.iter())
}
#[define_opaque(IterMut)]
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
iter::zip(self.bits.iter().map(K::from_index), self.values.iter_mut())
}
#[define_opaque(KeyIter)]
pub fn keys(&self) -> KeyIter<'_, K> {
self.bits.iter().map(K::from_index)
}
#[inline]
pub fn values(&self) -> slice::Iter<'_, V> {
self.values.iter()
}
#[inline]
pub fn values_mut(&mut self) -> slice::IterMut<'_, V> {
self.values.iter_mut()
}
#[inline]
pub fn rank(&self, key: K) -> usize {
self.bits.rank(key.index())
}
pub fn first(&self) -> Option<(K, &V)> {
self
.bits
.first()
.and_then(|idx| self.values.first().map(|v| (K::from_index(idx), v)))
}
pub fn last(&self) -> Option<(K, &V)> {
self
.bits
.last()
.and_then(|idx| self.values.last().map(|v| (K::from_index(idx), v)))
}
pub fn is_sparse(&self) -> bool {
match (self.bits.first(), self.bits.last()) {
(Some(first), Some(last)) => {
self.len() < (last - first + 1)
},
_ => false, }
}
}
pub type Iter<'a, K: TrySparseIndex, V: 'a> =
impl DoubleEndedIterator<Item = (K, &'a V)> + ExactSizeIterator + FusedIterator + Clone;
pub type IterMut<'a, K: TrySparseIndex, V: 'a> =
impl DoubleEndedIterator<Item = (K, &'a mut V)> + ExactSizeIterator + FusedIterator;
pub type KeyIter<'a, K: TrySparseIndex> =
impl DoubleEndedIterator<Item = K> + ExactSizeIterator + FusedIterator + Clone;
pub type IntoIter<K: TrySparseIndex, V> =
impl DoubleEndedIterator<Item = (K, V)> + ExactSizeIterator + FusedIterator;
impl<K: TrySparseIndex, V> Index<K> for SparseMap<K, V> {
type Output = V;
fn index(&self, key: K) -> &Self::Output {
self.get(key).expect("key not found in SparseMap")
}
}
impl<K: TrySparseIndex, V> IndexMut<K> for SparseMap<K, V> {
fn index_mut(&mut self, key: K) -> &mut Self::Output {
self.get_mut(key).expect("key not found in SparseMap")
}
}
impl<'a, K: TrySparseIndex, V> IntoIterator for &'a SparseMap<K, V> {
type IntoIter = Iter<'a, K, V>;
type Item = (K, &'a V);
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, K: TrySparseIndex, V> IntoIterator for &'a mut SparseMap<K, V> {
type IntoIter = IterMut<'a, K, V>;
type Item = (K, &'a mut V);
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<K: TrySparseIndex, V> IntoIterator for SparseMap<K, V> {
type IntoIter = IntoIter<K, V>;
type Item = (K, V);
#[define_opaque(IntoIter)]
fn into_iter(self) -> Self::IntoIter {
let indices = self.bits.into_iter().map(K::from_index);
let values = self.values.into_iter();
indices.zip(values)
}
}
impl<K: TrySparseIndex, V> FromIterator<(K, V)> for SparseMap<K, V> {
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
let iter = iter.into_iter();
let mut map = Self::with_capacity(iter.size_hint().0);
let mut hi = None;
for (key, value) in iter {
let ix = key.index();
match hi {
Some(hi) if ix == hi => {
*map.values.last_mut().expect("can't have key without value") = value;
},
Some(hi) if ix < hi => {
map.insert(K::from_index(ix), value);
},
_ => {
map.bits.insert(ix);
map.values.push(value);
hi = Some(ix);
},
}
}
map
}
}
impl<K: TrySparseIndex, V> Extend<(K, V)> for SparseMap<K, V> {
fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
let mut hi = self.bits.last();
for (key, value) in iter {
let ix = key.index();
match hi {
Some(hi) if ix == hi => {
*self
.values
.last_mut()
.expect("can't have key without value") = value;
},
Some(hi) if ix < hi => {
self.insert(K::from_index(ix), value);
},
_ => {
self.bits.insert(ix);
self.values.push(value);
hi = Some(ix);
},
}
}
}
}