完成bitmap的static bitmap功能,能够静态声明bitmap (#490)

* 完成bitmap的static bitmap功能,能够静态声明bitmap
This commit is contained in:
LoGin
2024-01-15 18:13:22 +08:00
committed by GitHub
parent dcf232f378
commit 6994f6b113
7 changed files with 1363 additions and 1 deletions

View File

@ -0,0 +1,266 @@
use core::{intrinsics::unlikely, marker::PhantomData};
use crate::traits::BitOps;
pub(crate) struct BitMapCore<T: BitOps, const N: usize> {
phantom: PhantomData<T>,
}
impl<T: BitOps, const N: usize> BitMapCore<T, N> {
pub const fn new() -> Self {
Self {
phantom: PhantomData,
}
}
/// 获取位图中的某一位
pub(crate) fn get(&self, data: &[T], index: usize) -> Option<bool> {
if unlikely(index >= N) {
return None;
}
let element_index = index / T::bit_size();
let bit_index = index % T::bit_size();
let element = data.get(element_index)?;
let bit = <T as BitOps>::get(element, bit_index);
Some(bit)
}
/// 设置位图中的某一位
pub(crate) fn set(&self, data: &mut [T], index: usize, value: bool) -> Option<bool> {
if unlikely(index >= N) {
return None;
}
let element_index = index / T::bit_size();
let bit_index = index % T::bit_size();
let element = data.get_mut(element_index)?;
let bit = <T as BitOps>::set(element, bit_index, value);
Some(bit)
}
pub(crate) fn set_all(&self, data: &mut [T], value: bool) {
let val = if value { T::max() } else { T::zero() };
for element in data.iter_mut() {
*element = val;
}
// 特殊处理最后一个元素
let last_element = data.last_mut().unwrap();
let mask = T::make_mask(N % T::bit_size());
if mask != T::zero() {
*last_element &= mask;
}
}
/// 获取位图中第一个为1的位
pub(crate) fn first_index(&self, data: &[T]) -> Option<usize> {
for (i, element) in data.iter().enumerate() {
let bit = <T as BitOps>::first_index(element);
if bit.is_some() {
return Some(i * T::bit_size() + bit.unwrap());
}
}
None
}
/// 获取位图中第一个为0的位
pub(crate) fn first_false_index(&self, data: &[T]) -> Option<usize> {
for (i, element) in data.iter().enumerate() {
if let Some(bit) = <T as BitOps>::first_false_index(element) {
return self.make_index(i * T::bit_size() + bit);
}
}
None
}
/// 获取位图中最后一个为1的位
pub(crate) fn last_index(&self, data: &[T]) -> Option<usize> {
for (i, element) in data.iter().enumerate().rev() {
if let Some(bit) = <T as BitOps>::last_index(element) {
return self.make_index(i * T::bit_size() + bit);
}
}
None
}
/// 获取位图中最后一个为0的位
///
/// ## 参数
///
/// - `data`:位图数据
/// - `n`:位图有效位数
pub(crate) fn last_false_index(&self, data: &[T]) -> Option<usize> {
let mut iter = data.iter().rev();
let mut last_element = *iter.next()?;
// 对最后一个元素进行特殊处理,因为最后一个元素可能不是满的
let mut mask = T::make_mask(N % T::bit_size());
if mask != T::zero() {
<T as BitOps>::invert(&mut mask);
last_element |= mask;
}
if let Some(bit) = <T as BitOps>::last_false_index(&last_element) {
return self.make_index((data.len() - 1) * T::bit_size() + bit);
}
for element in iter {
if let Some(bit) = <T as BitOps>::last_false_index(element) {
return self.make_index((data.len() - 1) * T::bit_size() + bit);
}
}
None
}
/// 获取位图中下一个为1的位
pub(crate) fn next_index(&self, data: &[T], index: usize) -> Option<usize> {
if unlikely(index >= N) {
return None;
}
let element_index = index / T::bit_size();
let bit_index = index % T::bit_size();
let element = data.get(element_index)?;
if let Some(bit) = <T as BitOps>::next_index(element, bit_index) {
return self.make_index(element_index * T::bit_size() + bit);
}
for (i, element) in data.iter().enumerate().skip(element_index + 1) {
if let Some(bit) = <T as BitOps>::first_index(element) {
return self.make_index(i * T::bit_size() + bit);
}
}
None
}
/// 获取位图中下一个为0的位
pub(crate) fn next_false_index(&self, data: &[T], index: usize) -> Option<usize> {
if unlikely(index >= N) {
return None;
}
let element_index = index / T::bit_size();
let bit_index = index % T::bit_size();
let element = data.get(element_index)?;
if let Some(bit) = <T as BitOps>::next_false_index(element, bit_index) {
return self.make_index(element_index * T::bit_size() + bit);
}
for (i, element) in data.iter().enumerate().skip(element_index + 1) {
if let Some(bit) = <T as BitOps>::first_false_index(element) {
return self.make_index(i * T::bit_size() + bit);
}
}
None
}
/// 获取位图中上一个为1的位
pub(crate) fn prev_index(&self, data: &[T], index: usize) -> Option<usize> {
if unlikely(index >= N) {
return None;
}
let element_index = index / T::bit_size();
let bit_index = index % T::bit_size();
let element = data.get(element_index)?;
if let Some(bit) = <T as BitOps>::prev_index(element, bit_index) {
return self.make_index(element_index * T::bit_size() + bit);
}
for (i, element) in data.iter().enumerate().take(element_index).rev() {
if let Some(bit) = <T as BitOps>::last_index(element) {
return self.make_index(i * T::bit_size() + bit);
}
}
None
}
pub(crate) fn prev_false_index(&self, data: &[T], index: usize) -> Option<usize> {
let element_index = index / T::bit_size();
let bit_index = index % T::bit_size();
let element = data.get(element_index)?;
if let Some(bit) = <T as BitOps>::prev_false_index(element, bit_index) {
return self.make_index(element_index * T::bit_size() + bit);
}
for (i, element) in data.iter().enumerate().take(element_index).rev() {
if let Some(bit) = <T as BitOps>::last_false_index(element) {
return self.make_index(i * T::bit_size() + bit);
}
}
None
}
pub(crate) fn invert(&self, data: &mut [T]) {
for element in data.iter_mut() {
<T as BitOps>::invert(element);
}
// 特殊处理最后一个元素
let last_element = data.last_mut().unwrap();
let mask = T::make_mask(N % T::bit_size());
if mask != T::zero() {
*last_element &= mask;
}
}
pub(crate) fn is_full(&self, data: &[T]) -> bool {
let mut iter = data.iter().peekable();
while let Some(element) = iter.next() {
if iter.peek().is_none() {
// 这是最后一个元素,进行特殊处理
let mut element = *element;
let mut mask = T::make_mask(N % T::bit_size());
if mask == T::zero() {
mask = T::max();
}
T::bit_and(&mut element, &mask);
if element == mask {
return true;
}
} else {
if element != &T::make_mask(T::bit_size()) {
return false;
}
}
}
return false;
}
pub(crate) fn is_empty(&self, data: &[T]) -> bool {
for element in data.iter() {
if element != &T::zero() {
return false;
}
}
return true;
}
fn make_index(&self, index: usize) -> Option<usize> {
if unlikely(index >= N) {
return None;
}
Some(index)
}
}

View File

@ -0,0 +1,9 @@
#![no_std]
#![feature(core_intrinsics)]
#![allow(incomplete_features)] // for const generics
#![feature(generic_const_exprs)]
mod bitmap_core;
mod static_bitmap;
pub mod traits;
pub use static_bitmap::StaticBitmap;

View File

@ -0,0 +1,119 @@
use core::mem::size_of;
use crate::{bitmap_core::BitMapCore, traits::BitMapOps};
/// 静态位图
///
/// 该位图的大小在编译时确定,不可变
pub struct StaticBitmap<const N: usize>
where
[(); (N + usize::BITS as usize - 1) / (usize::BITS as usize)]:,
{
pub data: [usize; (N + usize::BITS as usize - 1) / (usize::BITS as usize)],
core: BitMapCore<usize, N>,
}
impl<const N: usize> StaticBitmap<N>
where
[(); (N + usize::BITS as usize - 1) / (usize::BITS as usize)]:,
{
/// 创建一个新的静态位图
pub const fn new() -> Self {
Self {
data: [0; (N + usize::BITS as usize - 1) / (usize::BITS as usize)],
core: BitMapCore::new(),
}
}
}
impl<const N: usize> BitMapOps<usize> for StaticBitmap<N>
where
[(); (N + usize::BITS as usize - 1) / (usize::BITS as usize)]:,
{
#[inline]
fn get(&self, index: usize) -> Option<bool> {
return self.core.get(&self.data, index);
}
#[inline]
fn set(&mut self, index: usize, value: bool) -> Option<bool> {
return self.core.set(&mut self.data, index, value);
}
#[inline]
fn len(&self) -> usize {
N
}
#[inline]
fn size(&self) -> usize {
self.data.len() * size_of::<usize>()
}
#[inline]
fn first_index(&self) -> Option<usize> {
self.core.first_index(&self.data)
}
#[inline]
fn first_false_index(&self) -> Option<usize> {
self.core.first_false_index(&self.data)
}
#[inline]
fn last_index(&self) -> Option<usize> {
self.core.last_index(&self.data)
}
#[inline]
fn last_false_index(&self) -> Option<usize> {
self.core.last_false_index(&self.data)
}
#[inline]
fn next_index(&self, index: usize) -> Option<usize> {
self.core.next_index(&self.data, index)
}
#[inline]
fn next_false_index(&self, index: usize) -> Option<usize> {
self.core.next_false_index(&self.data, index)
}
#[inline]
fn prev_index(&self, index: usize) -> Option<usize> {
self.core.prev_index(&self.data, index)
}
#[inline]
fn prev_false_index(&self, index: usize) -> Option<usize> {
self.core.prev_false_index(&self.data, index)
}
#[inline]
fn invert(&mut self) {
self.core.invert(&mut self.data);
}
#[inline]
fn is_full(&self) -> bool {
self.core.is_full(&self.data)
}
#[inline]
fn is_empty(&self) -> bool {
self.core.is_empty(&self.data)
}
#[inline]
unsafe fn as_bytes(&self) -> &[u8] {
core::slice::from_raw_parts(
self.data.as_ptr() as *const u8,
core::mem::size_of::<Self>(),
)
}
fn set_all(&mut self, value: bool) {
self.core.set_all(&mut self.data, value);
}
}

View File

@ -0,0 +1,314 @@
use core::ops::{BitAnd, BitAndAssign, BitOrAssign, Not};
/// A trait that defines generalised operations on a `Bits::Store` type.
pub trait BitOps:
BitAndAssign + Sized + Copy + PartialEq + Not + BitOrAssign + BitOrAssign + BitAnd
{
fn get(bits: &Self, index: usize) -> bool;
fn set(bits: &mut Self, index: usize, value: bool) -> bool;
fn set_value(bits: &mut Self, value: Self);
fn len(bits: &Self) -> usize;
fn first_index(bits: &Self) -> Option<usize>;
fn first_false_index(bits: &Self) -> Option<usize>;
fn last_index(bits: &Self) -> Option<usize>;
fn last_false_index(bits: &Self) -> Option<usize>;
fn next_index(bits: &Self, index: usize) -> Option<usize>;
fn next_false_index(bits: &Self, index: usize) -> Option<usize>;
fn prev_index(bits: &Self, index: usize) -> Option<usize>;
fn prev_false_index(bits: &Self, index: usize) -> Option<usize>;
fn bit_and(bits: &mut Self, other_bits: &Self);
fn bit_or(bits: &mut Self, other_bits: &Self);
fn bit_xor(bits: &mut Self, other_bits: &Self);
fn invert(bits: &mut Self);
fn make_mask(shift: usize) -> Self;
fn bit_size() -> usize;
fn zero() -> Self;
fn max() -> Self;
}
macro_rules! bitops_for {
($target:ty) => {
impl BitOps for $target {
#[inline]
fn get(bits: &Self, index: usize) -> bool {
bits & (1 << index) != 0
}
#[inline]
fn set(bits: &mut Self, index: usize, value: bool) -> bool {
let mask = 1 << index;
let prev = *bits & mask;
if value {
*bits |= mask;
} else {
*bits &= !mask;
}
prev != 0
}
#[inline]
fn set_value(bits: &mut Self, value: Self) {
*bits = value;
}
#[inline]
fn len(bits: &Self) -> usize {
bits.count_ones() as usize
}
#[inline]
fn first_index(bits: &Self) -> Option<usize> {
if *bits == 0 {
None
} else {
Some(bits.trailing_zeros() as usize)
}
}
#[inline]
fn first_false_index(bits: &Self) -> Option<usize> {
if *bits == <$target>::MAX {
None
} else {
Some(bits.trailing_ones() as usize)
}
}
#[inline]
fn last_index(bits: &Self) -> Option<usize> {
if *bits == 0 {
None
} else {
Some(<$target>::BITS as usize - 1 - (bits.leading_zeros() as usize))
}
}
#[inline]
fn last_false_index(bits: &Self) -> Option<usize> {
if *bits == <$target>::MAX {
None
} else {
Some(<$target>::BITS as usize - 1 - bits.leading_ones() as usize)
}
}
#[inline]
fn next_index(bits: &Self, index: usize) -> Option<usize> {
if *bits == 0 || index >= <$target>::BITS as usize - 1 {
None
} else {
let intermediate =
(*bits & (<$target>::MAX.overflowing_shl(1 + index as u32).0));
if intermediate == 0 {
None
} else {
Some(intermediate.trailing_zeros() as usize)
}
}
}
#[inline]
fn next_false_index(bits: &Self, index: usize) -> Option<usize> {
if *bits == <$target>::MAX || index >= <$target>::BITS as usize - 1 {
None
} else {
let intermediate = (*bits | ((1 << (index + 1)) - 1));
if intermediate == <$target>::MAX {
None
} else {
Some(intermediate.trailing_ones() as usize)
}
}
}
#[inline]
fn prev_index(bits: &Self, index: usize) -> Option<usize> {
if *bits == 0 || index == 0 {
None
} else {
let intermediate = bits & ((1 << index) - 1);
if intermediate == 0 {
None
} else {
Some(<$target>::BITS as usize - 1 - (intermediate.leading_zeros() as usize))
}
}
}
#[inline]
fn prev_false_index(bits: &Self, index: usize) -> Option<usize> {
if *bits == <$target>::MAX || index == 0 {
None
} else {
let intermediate = bits | (<$target>::MAX.overflowing_shl(index as u32).0);
if intermediate == <$target>::MAX {
None
} else {
Some(<$target>::BITS as usize - 1 - (intermediate.leading_ones() as usize))
}
}
}
#[inline]
fn bit_and(bits: &mut Self, other_bits: &Self) {
*bits &= *other_bits;
}
#[inline]
fn bit_or(bits: &mut Self, other_bits: &Self) {
*bits |= *other_bits;
}
#[inline]
fn bit_xor(bits: &mut Self, other_bits: &Self) {
*bits ^= *other_bits;
}
#[inline]
fn invert(bits: &mut Self) {
*bits = !*bits;
}
#[inline]
fn make_mask(shift: usize) -> Self {
if shift == <$target>::BITS as usize {
<$target>::MAX
} else {
(1 << shift) - 1
}
}
#[cfg(feature = "std")]
fn to_hex(bits: &Self) -> String {
format!("{:x}", bits)
}
#[inline]
fn bit_size() -> usize {
<$target>::BITS as usize
}
#[inline]
fn zero() -> Self {
0
}
#[inline]
fn max() -> Self {
<$target>::MAX
}
}
};
}
// 为 `u8` 、 `u16` 、 `u32` 和 `u64` 实现 `BitOps` trait
bitops_for!(u8);
bitops_for!(u16);
bitops_for!(u32);
bitops_for!(u64);
bitops_for!(usize);
/// Bitmap应当实现的trait
pub trait BitMapOps<T: BitOps> {
/// 获取指定index的位
///
/// ## 返回
///
/// - `Some(true)` - 该位为1
/// - `Some(false)` - 该位为0
/// - `None` - index超出范围
fn get(&self, index: usize) -> Option<bool>;
/// 设置指定index的位并返回该位之前的值
///
/// ## 参数
///
/// - `index` - 位的index
/// - `value` - 位的新值
///
/// ## 返回
///
/// - `Some(true)` - 该位之前为1
/// - `Some(false)` - 该位之前为0
/// - `None` - index超出范围
fn set(&mut self, index: usize, value: bool) -> Option<bool>;
/// 将所有位设置为指定值
fn set_all(&mut self, value: bool);
/// 获取bitmap的长度以位为单位
///
/// ## Example
///
/// ```
/// use bitmap::StaticBitmap;
/// use bitmap::traits::BitMapOps;
///
/// let mut bitmap = StaticBitmap::<34>::new();
/// assert_eq!(bitmap.len(), 34);
/// ```
///
fn len(&self) -> usize;
/// 获取bitmap的大小以字节为单位
fn size(&self) -> usize;
/// 获取第一个为1的位的index
///
/// ## 返回
///
/// - `Some(index)` - 第一个为1的位的index
/// - `None` - 不存在为1的位
fn first_index(&self) -> Option<usize>;
/// 获取第一个为0的位的index
///
/// ## 返回
///
/// - `Some(index)` - 第一个为0的位的index
/// - `None` - 不存在为0的位
fn first_false_index(&self) -> Option<usize>;
/// 获取最后一个为1的位的index
///
/// ## 返回
///
/// - `Some(index)` - 最后一个为1的位的index
/// - `None` - 不存在为1的位
fn last_index(&self) -> Option<usize>;
/// 获取最后一个为0的位的index
///
/// ## 返回
///
/// - `Some(index)` - 最后一个为0的位的index
/// - `None` - 不存在为0的位
fn last_false_index(&self) -> Option<usize>;
/// 获取指定index之后第一个为1的位的index
fn next_index(&self, index: usize) -> Option<usize>;
/// 获取指定index之后第一个为0的位的index
fn next_false_index(&self, index: usize) -> Option<usize>;
/// 获取指定index之前第一个为1的位的index
fn prev_index(&self, index: usize) -> Option<usize>;
/// 获取指定index之前第一个为0的位的index
fn prev_false_index(&self, index: usize) -> Option<usize>;
/// 反转bitmap
fn invert(&mut self);
/// 判断bitmap是否满了
fn is_full(&self) -> bool;
/// 判断bitmap是否为空
fn is_empty(&self) -> bool;
/// 将bitmap转换为字节数组
unsafe fn as_bytes(&self) -> &[u8];
}