273 lines
5.9 KiB
Rust
273 lines
5.9 KiB
Rust
/*
|
|
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <hello@stalw.art>
|
|
*
|
|
* 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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
#[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<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,
|
|
}
|
|
}
|
|
}
|