Import upstream v0.16.22, stripped
Upstream commit: 474dd0229cb20cf513036619781ed97bd8073c3f Enterprise-only files removed or emptied: 63 Enterprise-only snippets removed: 117 in 50 files Dangling module declarations removed: 5 Cargo edits turning enterprise off: 14 Verification: clean Enterprise feature gates left for rebuilt features: 19 in 18 files Produced by tools/fork/strip.py. The full report is in docs/fork/strip-reports/ on main.
This commit is contained in:
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use std::ops::Deref;
|
||||
|
||||
#[derive(
|
||||
Debug,
|
||||
rkyv::Archive,
|
||||
rkyv::Deserialize,
|
||||
rkyv::Serialize,
|
||||
serde::Serialize,
|
||||
serde::Deserialize,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
PartialEq,
|
||||
Eq,
|
||||
Hash,
|
||||
)]
|
||||
#[rkyv(compare(PartialEq), derive(Debug))]
|
||||
#[repr(transparent)]
|
||||
pub struct Bitmap<T: BitmapItem> {
|
||||
pub bitmap: u64,
|
||||
#[serde(skip)]
|
||||
#[rkyv(omit_bounds)]
|
||||
_state: std::marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
pub trait BitmapItem: From<u64> + Into<u64> + Sized + Copy {
|
||||
fn max() -> u64;
|
||||
fn is_valid(&self) -> bool;
|
||||
}
|
||||
|
||||
pub trait BitPop {
|
||||
fn bit_push(&mut self, item: u8);
|
||||
fn bit_pop(&mut self) -> Option<u8>;
|
||||
}
|
||||
|
||||
impl<T: BitmapItem> Bitmap<T> {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn all() -> Self {
|
||||
Self {
|
||||
bitmap: u64::MAX >> (64 - T::max()),
|
||||
_state: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn union(&mut self, items: &Bitmap<T>) {
|
||||
self.bitmap |= items.bitmap;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn union_raw(&mut self, items: impl Into<u64>) {
|
||||
self.bitmap |= items.into();
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn intersection(&mut self, items: &Bitmap<T>) {
|
||||
self.bitmap &= items.bitmap;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn insert(&mut self, item: T) {
|
||||
debug_assert!(item.is_valid());
|
||||
self.bitmap |= 1 << item.into();
|
||||
}
|
||||
|
||||
pub fn insert_many(&mut self, items: impl IntoIterator<Item = T>) {
|
||||
for item in items.into_iter() {
|
||||
self.insert(item);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_many(&mut self, items: impl IntoIterator<Item = T>) {
|
||||
for item in items.into_iter() {
|
||||
debug_assert!(item.is_valid());
|
||||
self.bitmap &= !(1 << item.into());
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn with_item(mut self, item: T) -> Self {
|
||||
self.insert(item);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn remove(&mut self, item: T) {
|
||||
debug_assert!(item.is_valid());
|
||||
self.bitmap ^= 1 << item.into();
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn pop(&mut self) -> Option<T> {
|
||||
if self.bitmap != 0 {
|
||||
let item = 63 - self.bitmap.leading_zeros();
|
||||
self.bitmap ^= 1 << item;
|
||||
Some((item as u64).into())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn contains(&self, item: T) -> bool {
|
||||
self.bitmap & (1 << item.into()) != 0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn contains_any(&self, items: impl Iterator<Item = T>) -> bool {
|
||||
for item in items {
|
||||
if self.bitmap & (1 << item.into()) != 0 {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn contains_all(&self, items: impl Iterator<Item = T>) -> bool {
|
||||
if !self.is_empty() {
|
||||
for item in items {
|
||||
if self.bitmap & (1 << item.into()) == 0 {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.bitmap == 0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn clear(&mut self) -> Self {
|
||||
let bitmap = self.bitmap;
|
||||
self.bitmap = 0;
|
||||
Bitmap {
|
||||
bitmap,
|
||||
_state: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_inner(self) -> u64 {
|
||||
self.bitmap
|
||||
}
|
||||
}
|
||||
|
||||
impl BitPop for u32 {
|
||||
fn bit_push(&mut self, item: u8) {
|
||||
*self |= 1 << item;
|
||||
}
|
||||
|
||||
fn bit_pop(&mut self) -> Option<u8> {
|
||||
if *self != 0 {
|
||||
let item = 31 - self.leading_zeros();
|
||||
*self ^= 1 << item;
|
||||
Some(item as u8)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BitPop for u64 {
|
||||
fn bit_push(&mut self, item: u8) {
|
||||
*self |= 1 << item;
|
||||
}
|
||||
|
||||
fn bit_pop(&mut self) -> Option<u8> {
|
||||
if *self != 0 {
|
||||
let item = 63 - self.leading_zeros();
|
||||
*self ^= 1 << item;
|
||||
Some(item as u8)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BitmapItem> From<ArchivedBitmap<T>> for Bitmap<T> {
|
||||
fn from(value: ArchivedBitmap<T>) -> Self {
|
||||
Self {
|
||||
bitmap: value.bitmap.into(),
|
||||
_state: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BitmapItem> From<&ArchivedBitmap<T>> for Bitmap<T> {
|
||||
fn from(value: &ArchivedBitmap<T>) -> Self {
|
||||
Self {
|
||||
bitmap: value.bitmap.into(),
|
||||
_state: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BitmapItem> From<u64> for Bitmap<T> {
|
||||
fn from(value: u64) -> Self {
|
||||
Self {
|
||||
bitmap: value,
|
||||
_state: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BitmapItem> AsRef<u64> for Bitmap<T> {
|
||||
fn as_ref(&self) -> &u64 {
|
||||
&self.bitmap
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BitmapItem> Deref for Bitmap<T> {
|
||||
type Target = u64;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.bitmap
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BitmapItem> From<Bitmap<T>> for u64 {
|
||||
fn from(value: Bitmap<T>) -> Self {
|
||||
value.bitmap
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BitmapItem> Iterator for Bitmap<T> {
|
||||
type Item = T;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.bitmap != 0 {
|
||||
let item = 63 - self.bitmap.leading_zeros();
|
||||
self.bitmap ^= 1 << item;
|
||||
Some((item as u64).into())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BitmapItem> From<Vec<T>> for Bitmap<T> {
|
||||
fn from(values: Vec<T>) -> Self {
|
||||
let mut bitmap = Bitmap::default();
|
||||
for value in values {
|
||||
if value.is_valid() {
|
||||
bitmap.insert(value);
|
||||
}
|
||||
}
|
||||
bitmap
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BitmapItem> FromIterator<T> for Bitmap<T> {
|
||||
fn from_iter<U: IntoIterator<Item = T>>(iter: U) -> Self {
|
||||
let mut bitmap = Bitmap::new();
|
||||
for value in iter {
|
||||
if value.is_valid() {
|
||||
bitmap.insert(value);
|
||||
}
|
||||
}
|
||||
bitmap
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BitmapItem> From<&Vec<T>> for Bitmap<T> {
|
||||
fn from(values: &Vec<T>) -> Self {
|
||||
let mut bitmap = Bitmap::default();
|
||||
for value in values {
|
||||
if value.is_valid() {
|
||||
bitmap.insert(*value);
|
||||
}
|
||||
}
|
||||
bitmap
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BitmapItem> From<T> for Bitmap<T> {
|
||||
fn from(value: T) -> Self {
|
||||
let mut bitmap = Bitmap::default();
|
||||
bitmap.insert(value);
|
||||
bitmap
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BitmapItem> From<Bitmap<T>> for Vec<T> {
|
||||
fn from(values: Bitmap<T>) -> Self {
|
||||
let mut list = Vec::new();
|
||||
for item in values {
|
||||
list.push(item);
|
||||
}
|
||||
list
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BitmapItem> Default for Bitmap<T> {
|
||||
fn default() -> Self {
|
||||
Bitmap {
|
||||
bitmap: 0,
|
||||
_state: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
pub mod bitmap;
|
||||
pub mod mutex_map;
|
||||
pub mod vec_map;
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use core::hash::Hash;
|
||||
use std::hash::Hasher;
|
||||
|
||||
use ahash::AHasher;
|
||||
use tokio::sync::{Mutex, MutexGuard};
|
||||
|
||||
pub struct MutexMap<T: Default> {
|
||||
map: Box<[Mutex<T>]>,
|
||||
mask: u64,
|
||||
hasher: AHasher,
|
||||
}
|
||||
|
||||
pub struct MutexMapLockError;
|
||||
pub type Result<T> = std::result::Result<T, MutexMapLockError>;
|
||||
|
||||
#[allow(clippy::mutex_atomic)]
|
||||
impl<T: Default> MutexMap<T> {
|
||||
pub fn with_capacity(size: usize) -> MutexMap<T> {
|
||||
let size = size.next_power_of_two();
|
||||
MutexMap {
|
||||
map: (0..size)
|
||||
.map(|_| T::default().into())
|
||||
.collect::<Vec<Mutex<T>>>()
|
||||
.into_boxed_slice(),
|
||||
mask: (size - 1) as u64,
|
||||
hasher: AHasher::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn lock<U>(&self, key: U) -> MutexGuard<'_, T>
|
||||
where
|
||||
U: Into<u64> + Copy,
|
||||
{
|
||||
let hash = key.into() & self.mask;
|
||||
self.map[hash as usize].lock().await
|
||||
}
|
||||
|
||||
/*pub async fn try_lock<U>(&self, key: U, timeout: Duration) -> Option<MutexGuard<'_, T>>
|
||||
where
|
||||
U: Into<u64> + Copy,
|
||||
{
|
||||
let hash = key.into() & self.mask;
|
||||
self.map[hash as usize].try_lock(timeout).await
|
||||
}*/
|
||||
|
||||
pub async fn lock_hash<U>(&self, key: U) -> MutexGuard<'_, T>
|
||||
where
|
||||
U: Hash,
|
||||
{
|
||||
let mut hasher = self.hasher.clone();
|
||||
key.hash(&mut hasher);
|
||||
let hash = hasher.finish() & self.mask;
|
||||
self.map[hash as usize].lock().await
|
||||
}
|
||||
|
||||
/*pub async fn try_lock_hash<U>(&self, key: U, timeout: Duration) -> Option<MutexGuard<'_, T>>
|
||||
where
|
||||
U: Hash,
|
||||
{
|
||||
let mut hasher = self.hasher.clone();
|
||||
key.hash(&mut hasher);
|
||||
let hash = hasher.finish() & self.mask;
|
||||
self.map[hash as usize].try_lock_for(timeout).await
|
||||
}*/
|
||||
}
|
||||
@@ -0,0 +1,396 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use rkyv::Archive;
|
||||
use serde::{Deserialize, Serialize, ser::SerializeMap};
|
||||
use std::{borrow::Borrow, cmp::Ordering, fmt, hash::Hash};
|
||||
|
||||
// A map implemented using vectors
|
||||
// used for small datasets of less than 20 items
|
||||
// and when deserializing from JSON
|
||||
|
||||
#[derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize, Debug, Clone, PartialEq, Eq)]
|
||||
pub struct VecMap<K: Eq + PartialEq, V> {
|
||||
pub inner: Vec<KeyValue<K, V>>,
|
||||
}
|
||||
|
||||
#[derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize, Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct KeyValue<K: Eq + PartialEq, V> {
|
||||
pub key: K,
|
||||
pub value: V,
|
||||
}
|
||||
|
||||
impl<K: Eq + PartialEq, V> Default for VecMap<K, V> {
|
||||
fn default() -> Self {
|
||||
VecMap { inner: Vec::new() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Eq + PartialEq, V> VecMap<K, V> {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn with_capacity(capacity: usize) -> Self {
|
||||
Self {
|
||||
inner: Vec::with_capacity(capacity),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn set(&mut self, key: impl Into<K>, value: V) -> bool {
|
||||
let key = key.into();
|
||||
if let Some(kv) = self.inner.iter_mut().find(|kv| kv.key == key) {
|
||||
kv.value = value;
|
||||
false
|
||||
} else {
|
||||
self.inner.push(KeyValue { key, value });
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn append(&mut self, key: impl Into<K>, value: V) {
|
||||
self.inner.push(KeyValue {
|
||||
key: key.into(),
|
||||
value,
|
||||
});
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn with_append(mut self, key: impl Into<K>, value: V) -> Self {
|
||||
self.append(key, value);
|
||||
self
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn insert(&mut self, idx: usize, key: impl Into<K>, value: V) {
|
||||
self.inner.insert(
|
||||
idx,
|
||||
KeyValue {
|
||||
key: key.into(),
|
||||
value,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V>
|
||||
where
|
||||
K: Borrow<Q> + PartialEq<Q>,
|
||||
{
|
||||
self.inner.iter().find_map(|kv| {
|
||||
if &kv.key == key {
|
||||
Some(&kv.value)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
|
||||
self.inner.iter_mut().find_map(|kv| {
|
||||
if &kv.key == key {
|
||||
Some(&mut kv.value)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn contains_key(&self, key: &K) -> bool {
|
||||
self.inner.iter().any(|kv| kv.key == *key)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V>
|
||||
where
|
||||
K: Borrow<Q> + PartialEq<Q>,
|
||||
{
|
||||
self.inner
|
||||
.iter()
|
||||
.position(|kv| kv.key == *key)
|
||||
.map(|pos| self.inner.remove(pos).value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn remove_all(&mut self, key: &K) {
|
||||
self.inner.retain(|kv| kv.key != *key);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn remove_entry(&mut self, key: &K) -> Option<(K, V)> {
|
||||
self.inner.iter().position(|k| &k.key == key).map(|pos| {
|
||||
let kv = self.inner.remove(pos);
|
||||
(kv.key, kv.value)
|
||||
})
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn swap_remove(&mut self, index: usize) -> V {
|
||||
self.inner.swap_remove(index).value
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.inner.is_empty()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn len(&self) -> usize {
|
||||
self.inner.len()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn clear(&mut self) {
|
||||
self.inner.clear();
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
|
||||
self.inner.iter().map(|kv| (&kv.key, &kv.value))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn iter_by_key<'x, 'y: 'x>(&'x self, key: &'y K) -> impl Iterator<Item = &'x V> + 'x {
|
||||
self.inner.iter().filter_map(move |kv| {
|
||||
if &kv.key == key {
|
||||
Some(&kv.value)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = (&mut K, &mut V)> {
|
||||
self.inner.iter_mut().map(|kv| (&mut kv.key, &mut kv.value))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn iter_mut_by_key<'x, 'y: 'x>(
|
||||
&'x mut self,
|
||||
key: &'y K,
|
||||
) -> impl Iterator<Item = &'x mut V> + 'x {
|
||||
self.inner.iter_mut().filter_map(move |kv| {
|
||||
if &kv.key == key {
|
||||
Some(&mut kv.value)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn keys(&self) -> impl Iterator<Item = &K> {
|
||||
self.inner.iter().map(|kv| &kv.key)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn values(&self) -> impl Iterator<Item = &V> {
|
||||
self.inner.iter().map(|kv| &kv.value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn last(&self) -> Option<(&K, &V)> {
|
||||
self.inner.last().map(|kv| (&kv.key, &kv.value))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
|
||||
self.inner.iter_mut().map(|kv| &mut kv.value)
|
||||
}
|
||||
|
||||
pub fn get_mut_or_insert_with(&mut self, key: K, fnc: impl FnOnce() -> V) -> &mut V {
|
||||
if let Some(pos) = self.inner.iter().position(|kv| kv.key == key) {
|
||||
&mut self.inner[pos].value
|
||||
} else {
|
||||
self.inner.push(KeyValue { key, value: fnc() });
|
||||
&mut self.inner.last_mut().unwrap().value
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_key_value(mut self, key: K, value: V) -> Self {
|
||||
self.append(key, value);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn sort_unstable(&mut self)
|
||||
where
|
||||
K: Ord,
|
||||
V: Ord,
|
||||
{
|
||||
self.inner.sort_unstable_by(|a, b| match a.key.cmp(&b.key) {
|
||||
Ordering::Equal => a.value.cmp(&b.value),
|
||||
cmp => cmp,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn sort_unstable_by_key(&mut self)
|
||||
where
|
||||
K: Ord,
|
||||
{
|
||||
self.inner.sort_unstable_by(|a, b| a.key.cmp(&b.key));
|
||||
}
|
||||
|
||||
pub fn extend(&mut self, iter: impl IntoIterator<Item = (K, V)>) {
|
||||
for (k, v) in iter {
|
||||
self.append(k, v);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn drain(&mut self) -> impl Iterator<Item = (K, V)> + '_ {
|
||||
self.inner.drain(..).map(|kv| (kv.key, kv.value))
|
||||
}
|
||||
|
||||
pub fn into_values(self) -> impl Iterator<Item = V> {
|
||||
self.inner.into_iter().map(|kv| kv.value)
|
||||
}
|
||||
|
||||
pub fn into_keys(self) -> impl Iterator<Item = K> {
|
||||
self.inner.into_iter().map(|kv| kv.key)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Eq + PartialEq, V: Default> VecMap<K, V> {
|
||||
pub fn get_mut_or_insert(&mut self, key: K) -> &mut V {
|
||||
if let Some(pos) = self.inner.iter().position(|kv| kv.key == key) {
|
||||
&mut self.inner[pos].value
|
||||
} else {
|
||||
self.inner.push(KeyValue {
|
||||
key,
|
||||
value: V::default(),
|
||||
});
|
||||
&mut self.inner.last_mut().unwrap().value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Archive + Eq + PartialEq, V: Archive> ArchivedVecMap<K, V> {
|
||||
pub fn len(&self) -> usize {
|
||||
self.inner.len()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.inner.is_empty()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn iter(
|
||||
&self,
|
||||
) -> impl Iterator<
|
||||
Item = (
|
||||
&<K as rkyv::Archive>::Archived,
|
||||
&<V as rkyv::Archive>::Archived,
|
||||
),
|
||||
> {
|
||||
self.inner.iter().map(|kv| (&kv.key, &kv.value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Eq + PartialEq, V> IntoIterator for VecMap<K, V> {
|
||||
type Item = (K, V);
|
||||
|
||||
type IntoIter =
|
||||
std::iter::Map<std::vec::IntoIter<KeyValue<K, V>>, fn(KeyValue<K, V>) -> (K, V)>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.inner.into_iter().map(|kv| (kv.key, kv.value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'x, K: Eq + PartialEq, V> IntoIterator for &'x VecMap<K, V> {
|
||||
type Item = (&'x K, &'x V);
|
||||
|
||||
type IntoIter = std::iter::Map<
|
||||
std::slice::Iter<'x, KeyValue<K, V>>,
|
||||
fn(&'x KeyValue<K, V>) -> (&'x K, &'x V),
|
||||
>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.inner.iter().map(|kv| (&kv.key, &kv.value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V> Hash for VecMap<K, V>
|
||||
where
|
||||
K: Eq + PartialEq + Hash,
|
||||
V: Hash,
|
||||
{
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.inner.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Eq + PartialEq, V> FromIterator<(K, V)> for VecMap<K, V> {
|
||||
fn from_iter<T>(iter: T) -> Self
|
||||
where
|
||||
T: IntoIterator<Item = (K, V)>,
|
||||
{
|
||||
let iter = iter.into_iter();
|
||||
let mut map = VecMap::with_capacity(iter.size_hint().0);
|
||||
for (k, v) in iter {
|
||||
map.append(k, v);
|
||||
}
|
||||
map
|
||||
}
|
||||
}
|
||||
|
||||
struct VecMapVisitor<K, V> {
|
||||
phantom: std::marker::PhantomData<(K, V)>,
|
||||
}
|
||||
|
||||
impl<'de, K: Eq + PartialEq + Deserialize<'de>, V: Deserialize<'de>> serde::de::Visitor<'de>
|
||||
for VecMapVisitor<K, V>
|
||||
{
|
||||
type Value = VecMap<K, V>;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a valid map")
|
||||
}
|
||||
|
||||
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: serde::de::MapAccess<'de>,
|
||||
{
|
||||
// Duplicates are not checked during deserialization
|
||||
let mut vec_map = VecMap::new();
|
||||
while let Some(key) = map.next_key::<K>()? {
|
||||
vec_map.append(key, map.next_value()?);
|
||||
}
|
||||
Ok(vec_map)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, K: Eq + PartialEq + Deserialize<'de>, V: Deserialize<'de>> Deserialize<'de>
|
||||
for VecMap<K, V>
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_map(VecMapVisitor {
|
||||
phantom: std::marker::PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Eq + PartialEq + Serialize, V: Serialize> Serialize for VecMap<K, V> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let mut map = serializer.serialize_map(self.len().into())?;
|
||||
|
||||
for (key, value) in self {
|
||||
map.serialize_entry(key, value)?
|
||||
}
|
||||
|
||||
map.end()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user