/* * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC * * 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 { pub bitmap: u64, #[serde(skip)] #[rkyv(omit_bounds)] _state: std::marker::PhantomData, } pub trait BitmapItem: From + Into + 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; } impl Bitmap { 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) { self.bitmap |= items.bitmap; } #[inline(always)] pub fn union_raw(&mut self, items: impl Into) { self.bitmap |= items.into(); } #[inline(always)] pub fn intersection(&mut self, items: &Bitmap) { 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) { for item in items.into_iter() { self.insert(item); } } pub fn remove_many(&mut self, items: impl IntoIterator) { 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 { 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) -> 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) -> 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 { 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 { if *self != 0 { let item = 63 - self.leading_zeros(); *self ^= 1 << item; Some(item as u8) } else { None } } } impl From> for Bitmap { fn from(value: ArchivedBitmap) -> Self { Self { bitmap: value.bitmap.into(), _state: std::marker::PhantomData, } } } impl From<&ArchivedBitmap> for Bitmap { fn from(value: &ArchivedBitmap) -> Self { Self { bitmap: value.bitmap.into(), _state: std::marker::PhantomData, } } } impl From for Bitmap { fn from(value: u64) -> Self { Self { bitmap: value, _state: std::marker::PhantomData, } } } impl AsRef for Bitmap { fn as_ref(&self) -> &u64 { &self.bitmap } } impl Deref for Bitmap { type Target = u64; fn deref(&self) -> &Self::Target { &self.bitmap } } impl From> for u64 { fn from(value: Bitmap) -> Self { value.bitmap } } impl Iterator for Bitmap { type Item = T; fn next(&mut self) -> Option { if self.bitmap != 0 { let item = 63 - self.bitmap.leading_zeros(); self.bitmap ^= 1 << item; Some((item as u64).into()) } else { None } } } impl From> for Bitmap { fn from(values: Vec) -> Self { let mut bitmap = Bitmap::default(); for value in values { if value.is_valid() { bitmap.insert(value); } } bitmap } } impl FromIterator for Bitmap { fn from_iter>(iter: U) -> Self { let mut bitmap = Bitmap::new(); for value in iter { if value.is_valid() { bitmap.insert(value); } } bitmap } } impl From<&Vec> for Bitmap { fn from(values: &Vec) -> Self { let mut bitmap = Bitmap::default(); for value in values { if value.is_valid() { bitmap.insert(*value); } } bitmap } } impl From for Bitmap { fn from(value: T) -> Self { let mut bitmap = Bitmap::default(); bitmap.insert(value); bitmap } } impl From> for Vec { fn from(values: Bitmap) -> Self { let mut list = Vec::new(); for item in values { list.push(item); } list } } impl Default for Bitmap { fn default() -> Self { Bitmap { bitmap: 0, _state: std::marker::PhantomData, } } }