mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-20 18:26:32 +00:00
添加动态申请的bitmap (#532)
This commit is contained in:
109
kernel/crates/bitmap/src/alloc_bitmap.rs
Normal file
109
kernel/crates/bitmap/src/alloc_bitmap.rs
Normal file
@ -0,0 +1,109 @@
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use crate::{bitmap_core::BitMapCore, traits::BitMapOps};
|
||||
|
||||
pub struct AllocBitmap {
|
||||
elements: usize,
|
||||
data: Vec<usize>,
|
||||
core: BitMapCore<usize>,
|
||||
}
|
||||
|
||||
impl AllocBitmap {
|
||||
pub fn new(elements: usize) -> Self {
|
||||
let data = vec![0usize; (elements + usize::BITS as usize - 1) / (usize::BITS as usize)];
|
||||
Self {
|
||||
elements,
|
||||
data,
|
||||
core: BitMapCore::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BitMapOps<usize> for AllocBitmap {
|
||||
#[inline]
|
||||
fn get(&self, index: usize) -> Option<bool> {
|
||||
return self.core.get(self.elements, &self.data, index);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set(&mut self, index: usize, value: bool) -> Option<bool> {
|
||||
return self.core.set(self.elements, &mut self.data, index, value);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn len(&self) -> usize {
|
||||
self.elements
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size(&self) -> usize {
|
||||
self.data.len() * core::mem::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.elements, &self.data)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn last_index(&self) -> Option<usize> {
|
||||
self.core.last_index(self.elements, &self.data)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn last_false_index(&self) -> Option<usize> {
|
||||
self.core.last_false_index(self.elements, &self.data)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn next_index(&self, index: usize) -> Option<usize> {
|
||||
self.core.next_index(self.elements, &self.data, index)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn next_false_index(&self, index: usize) -> Option<usize> {
|
||||
self.core.next_false_index(self.elements, &self.data, index)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prev_index(&self, index: usize) -> Option<usize> {
|
||||
self.core.prev_index(self.elements, &self.data, index)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prev_false_index(&self, index: usize) -> Option<usize> {
|
||||
self.core.prev_false_index(self.elements, &self.data, index)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn invert(&mut self) {
|
||||
self.core.invert(self.elements, &mut self.data);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_full(&self) -> bool {
|
||||
self.core.is_full(self.elements, &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(self.elements, &mut self.data, value);
|
||||
}
|
||||
}
|
@ -2,11 +2,11 @@ use core::{intrinsics::unlikely, marker::PhantomData};
|
||||
|
||||
use crate::traits::BitOps;
|
||||
|
||||
pub(crate) struct BitMapCore<T: BitOps, const N: usize> {
|
||||
pub(crate) struct BitMapCore<T: BitOps> {
|
||||
phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: BitOps, const N: usize> BitMapCore<T, N> {
|
||||
impl<T: BitOps> BitMapCore<T> {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
phantom: PhantomData,
|
||||
@ -14,8 +14,8 @@ impl<T: BitOps, const N: usize> BitMapCore<T, N> {
|
||||
}
|
||||
|
||||
/// 获取位图中的某一位
|
||||
pub(crate) fn get(&self, data: &[T], index: usize) -> Option<bool> {
|
||||
if unlikely(index >= N) {
|
||||
pub(crate) fn get(&self, n: usize, data: &[T], index: usize) -> Option<bool> {
|
||||
if unlikely(index >= n) {
|
||||
return None;
|
||||
}
|
||||
|
||||
@ -29,8 +29,8 @@ impl<T: BitOps, const N: usize> BitMapCore<T, N> {
|
||||
}
|
||||
|
||||
/// 设置位图中的某一位
|
||||
pub(crate) fn set(&self, data: &mut [T], index: usize, value: bool) -> Option<bool> {
|
||||
if unlikely(index >= N) {
|
||||
pub(crate) fn set(&self, n: usize, data: &mut [T], index: usize, value: bool) -> Option<bool> {
|
||||
if unlikely(index >= n) {
|
||||
return None;
|
||||
}
|
||||
let element_index = index / T::bit_size();
|
||||
@ -42,7 +42,7 @@ impl<T: BitOps, const N: usize> BitMapCore<T, N> {
|
||||
Some(bit)
|
||||
}
|
||||
|
||||
pub(crate) fn set_all(&self, data: &mut [T], value: bool) {
|
||||
pub(crate) fn set_all(&self, n: usize, data: &mut [T], value: bool) {
|
||||
let val = if value { T::max() } else { T::zero() };
|
||||
for element in data.iter_mut() {
|
||||
*element = val;
|
||||
@ -50,7 +50,7 @@ impl<T: BitOps, const N: usize> BitMapCore<T, N> {
|
||||
|
||||
// 特殊处理最后一个元素
|
||||
let last_element = data.last_mut().unwrap();
|
||||
let mask = T::make_mask(N % T::bit_size());
|
||||
let mask = T::make_mask(n % T::bit_size());
|
||||
if mask != T::zero() {
|
||||
*last_element &= mask;
|
||||
}
|
||||
@ -69,10 +69,10 @@ impl<T: BitOps, const N: usize> BitMapCore<T, N> {
|
||||
}
|
||||
|
||||
/// 获取位图中第一个为0的位
|
||||
pub(crate) fn first_false_index(&self, data: &[T]) -> Option<usize> {
|
||||
pub(crate) fn first_false_index(&self, n: usize, 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);
|
||||
return self.make_index(n, i * T::bit_size() + bit);
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,10 +80,10 @@ impl<T: BitOps, const N: usize> BitMapCore<T, N> {
|
||||
}
|
||||
|
||||
/// 获取位图中最后一个为1的位
|
||||
pub(crate) fn last_index(&self, data: &[T]) -> Option<usize> {
|
||||
pub(crate) fn last_index(&self, n: usize, 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);
|
||||
return self.make_index(n, i * T::bit_size() + bit);
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,12 +96,12 @@ impl<T: BitOps, const N: usize> BitMapCore<T, N> {
|
||||
///
|
||||
/// - `data`:位图数据
|
||||
/// - `n`:位图有效位数
|
||||
pub(crate) fn last_false_index(&self, data: &[T]) -> Option<usize> {
|
||||
pub(crate) fn last_false_index(&self, n: usize, 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());
|
||||
let mut mask = T::make_mask(n % T::bit_size());
|
||||
if mask != T::zero() {
|
||||
<T as BitOps>::invert(&mut mask);
|
||||
|
||||
@ -109,12 +109,12 @@ impl<T: BitOps, const N: usize> BitMapCore<T, N> {
|
||||
}
|
||||
|
||||
if let Some(bit) = <T as BitOps>::last_false_index(&last_element) {
|
||||
return self.make_index((data.len() - 1) * T::bit_size() + bit);
|
||||
return self.make_index(n, (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);
|
||||
return self.make_index(n, (data.len() - 1) * T::bit_size() + bit);
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,8 +122,8 @@ impl<T: BitOps, const N: usize> BitMapCore<T, N> {
|
||||
}
|
||||
|
||||
/// 获取位图中下一个为1的位
|
||||
pub(crate) fn next_index(&self, data: &[T], index: usize) -> Option<usize> {
|
||||
if unlikely(index >= N) {
|
||||
pub(crate) fn next_index(&self, n: usize, data: &[T], index: usize) -> Option<usize> {
|
||||
if unlikely(index >= n) {
|
||||
return None;
|
||||
}
|
||||
|
||||
@ -132,12 +132,12 @@ impl<T: BitOps, const N: usize> BitMapCore<T, N> {
|
||||
|
||||
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);
|
||||
return self.make_index(n, 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);
|
||||
return self.make_index(n, i * T::bit_size() + bit);
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,8 +145,8 @@ impl<T: BitOps, const N: usize> BitMapCore<T, N> {
|
||||
}
|
||||
|
||||
/// 获取位图中下一个为0的位
|
||||
pub(crate) fn next_false_index(&self, data: &[T], index: usize) -> Option<usize> {
|
||||
if unlikely(index >= N) {
|
||||
pub(crate) fn next_false_index(&self, n: usize, data: &[T], index: usize) -> Option<usize> {
|
||||
if unlikely(index >= n) {
|
||||
return None;
|
||||
}
|
||||
|
||||
@ -155,12 +155,12 @@ impl<T: BitOps, const N: usize> BitMapCore<T, N> {
|
||||
|
||||
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);
|
||||
return self.make_index(n, 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);
|
||||
return self.make_index(n, i * T::bit_size() + bit);
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,8 +168,8 @@ impl<T: BitOps, const N: usize> BitMapCore<T, N> {
|
||||
}
|
||||
|
||||
/// 获取位图中上一个为1的位
|
||||
pub(crate) fn prev_index(&self, data: &[T], index: usize) -> Option<usize> {
|
||||
if unlikely(index >= N) {
|
||||
pub(crate) fn prev_index(&self, n: usize, data: &[T], index: usize) -> Option<usize> {
|
||||
if unlikely(index >= n) {
|
||||
return None;
|
||||
}
|
||||
let element_index = index / T::bit_size();
|
||||
@ -177,37 +177,37 @@ impl<T: BitOps, const N: usize> BitMapCore<T, N> {
|
||||
|
||||
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);
|
||||
return self.make_index(n, 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);
|
||||
return self.make_index(n, i * T::bit_size() + bit);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub(crate) fn prev_false_index(&self, data: &[T], index: usize) -> Option<usize> {
|
||||
pub(crate) fn prev_false_index(&self, n: usize, 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);
|
||||
return self.make_index(n, 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);
|
||||
return self.make_index(n, i * T::bit_size() + bit);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub(crate) fn invert(&self, data: &mut [T]) {
|
||||
pub(crate) fn invert(&self, n: usize, data: &mut [T]) {
|
||||
for element in data.iter_mut() {
|
||||
<T as BitOps>::invert(element);
|
||||
}
|
||||
@ -215,19 +215,19 @@ impl<T: BitOps, const N: usize> BitMapCore<T, N> {
|
||||
// 特殊处理最后一个元素
|
||||
|
||||
let last_element = data.last_mut().unwrap();
|
||||
let mask = T::make_mask(N % T::bit_size());
|
||||
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 {
|
||||
pub(crate) fn is_full(&self, n: usize, 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());
|
||||
let mut mask = T::make_mask(n % T::bit_size());
|
||||
if mask == T::zero() {
|
||||
mask = T::max();
|
||||
}
|
||||
@ -256,8 +256,8 @@ impl<T: BitOps, const N: usize> BitMapCore<T, N> {
|
||||
return true;
|
||||
}
|
||||
|
||||
fn make_index(&self, index: usize) -> Option<usize> {
|
||||
if unlikely(index >= N) {
|
||||
fn make_index(&self, n: usize, index: usize) -> Option<usize> {
|
||||
if unlikely(index >= n) {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,12 @@
|
||||
#![allow(incomplete_features)] // for const generics
|
||||
#![feature(generic_const_exprs)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate alloc;
|
||||
|
||||
mod alloc_bitmap;
|
||||
mod bitmap_core;
|
||||
mod static_bitmap;
|
||||
pub mod traits;
|
||||
pub use alloc_bitmap::AllocBitmap;
|
||||
pub use static_bitmap::StaticBitmap;
|
||||
|
@ -10,7 +10,7 @@ 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>,
|
||||
core: BitMapCore<usize>,
|
||||
}
|
||||
|
||||
impl<const N: usize> StaticBitmap<N>
|
||||
@ -32,12 +32,12 @@ where
|
||||
{
|
||||
#[inline]
|
||||
fn get(&self, index: usize) -> Option<bool> {
|
||||
return self.core.get(&self.data, index);
|
||||
return self.core.get(N, &self.data, index);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set(&mut self, index: usize, value: bool) -> Option<bool> {
|
||||
return self.core.set(&mut self.data, index, value);
|
||||
return self.core.set(N, &mut self.data, index, value);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -57,47 +57,47 @@ where
|
||||
|
||||
#[inline]
|
||||
fn first_false_index(&self) -> Option<usize> {
|
||||
self.core.first_false_index(&self.data)
|
||||
self.core.first_false_index(N, &self.data)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn last_index(&self) -> Option<usize> {
|
||||
self.core.last_index(&self.data)
|
||||
self.core.last_index(N, &self.data)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn last_false_index(&self) -> Option<usize> {
|
||||
self.core.last_false_index(&self.data)
|
||||
self.core.last_false_index(N, &self.data)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn next_index(&self, index: usize) -> Option<usize> {
|
||||
self.core.next_index(&self.data, index)
|
||||
self.core.next_index(N, &self.data, index)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn next_false_index(&self, index: usize) -> Option<usize> {
|
||||
self.core.next_false_index(&self.data, index)
|
||||
self.core.next_false_index(N, &self.data, index)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prev_index(&self, index: usize) -> Option<usize> {
|
||||
self.core.prev_index(&self.data, index)
|
||||
self.core.prev_index(N, &self.data, index)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn prev_false_index(&self, index: usize) -> Option<usize> {
|
||||
self.core.prev_false_index(&self.data, index)
|
||||
self.core.prev_false_index(N, &self.data, index)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn invert(&mut self) {
|
||||
self.core.invert(&mut self.data);
|
||||
self.core.invert(N, &mut self.data);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_full(&self) -> bool {
|
||||
self.core.is_full(&self.data)
|
||||
self.core.is_full(N, &self.data)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -114,6 +114,6 @@ where
|
||||
}
|
||||
|
||||
fn set_all(&mut self, value: bool) {
|
||||
self.core.set_all(&mut self.data, value);
|
||||
self.core.set_all(N, &mut self.data, value);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user