rust_rsm/common/
bitmap.rs

1#![allow(non_camel_case_types)]
2#![allow(non_snake_case)]
3#![allow(non_upper_case_globals)]
4use super::*;
5use std::alloc;
6use errcode;
7
8pub struct bitmap_t {
9    bit_string:*mut u64,
10    capacity:usize,
11    used_count:usize,
12    u64_count:usize,
13}
14
15impl bitmap_t {
16    pub fn new(bits:i32)->Self {
17        let u64_num=ceiling(bits as u64, (std::mem::size_of::<u64>()*8) as u64);
18        let mut bitmap = Self {
19            bit_string:std::ptr::null_mut(),
20            capacity:bits as usize,
21            used_count:0,
22            u64_count:u64_num as usize,
23        };
24        unsafe {
25        bitmap.bit_string = alloc::alloc_zeroed(alloc::Layout::from_size_align_unchecked(bitmap.u64_count*std::mem::size_of::<u64>(),1)) as *mut u64;
26        }
27        return bitmap;
28    }
29
30    ///给定位域索引值,返回指定的u64指针以及bit位域
31    pub fn get_u64_by_index(&mut self,idx:usize)->(&mut u64, u64) {
32        let u64_idx= idx as usize / (8*std::mem::size_of::<u64>());
33        let u64_ptr = unsafe {
34             &mut *((self.bit_string as usize + u64_idx*std::mem::size_of::<u64>()) as *mut u64)
35        };
36        let bit_offset = idx as usize % (std::mem::size_of::<u64>()*8);
37        let test_bits = 1u64<< bit_offset;
38
39        return (u64_ptr,test_bits)
40    }
41
42    ///设置一个bitmap位,从0开始
43    pub fn set_bitmap(&mut self,idx:i32)->errcode::RESULT {
44        if idx as usize>=self.capacity {
45            return errcode::ERROR_OUTOF_MEM;
46        }
47        let (u64_ptr,test_bits) = self.get_u64_by_index(idx as usize);
48        if *u64_ptr & test_bits !=0 {
49            return errcode::ERROR_ALREADY_EXIST;
50        }
51        *u64_ptr |= test_bits;
52        self.used_count+=1;
53        errcode::RESULT_SUCCESS
54    }
55
56        ///设置一个bitmap位,从0开始
57    pub fn unset_bitmap(&mut self,idx:i32)->errcode::RESULT {
58            if idx as usize>=self.capacity {
59                return errcode::ERROR_OUTOF_MEM;
60            }
61            let (u64_ptr,test_bits) = self.get_u64_by_index(idx as usize);
62            if *u64_ptr & test_bits ==0 {
63                return errcode::ERROR_NOT_FOUND;
64            }
65            *u64_ptr &= !test_bits;
66            self.used_count-=1;
67            errcode::RESULT_SUCCESS
68    }
69
70            ///设置一个bitmap位,从0开始
71            pub fn clear_bitmap(&mut self)->errcode::RESULT {
72                if self.bit_string==std::ptr::null_mut() {
73                    return errcode::ERROR_NULL_POINTER;
74                }
75                for i in 0..self.u64_count {
76                    let u64_ptr = unsafe { 
77                        &mut *((self.bit_string as usize + i*std::mem::size_of::<u64>()) as *mut u64)
78                    };
79                    *u64_ptr = 0;
80                }                
81                errcode::RESULT_SUCCESS
82        }
83
84
85    pub fn is_bit_set(&mut self,idx:i32)->bool {
86        if idx as usize>=self.capacity {
87            return false;
88        }
89
90        let (u64_ptr,test_bits) = self.get_u64_by_index(idx as usize);
91        if (*u64_ptr) & (test_bits) !=0 {
92            return true;
93        } else {
94            return false;
95        }
96    }
97
98    pub fn get_used_count(&self)->usize {
99        return self.used_count
100    }
101
102    pub fn to_string(&self)->String {
103        format!("bitmap capacity={},used_count={},u64_count={}",self.capacity,self.used_count,self.u64_count)
104    }
105}
106
107impl Drop for bitmap_t {
108    fn drop(&mut self) {
109        if self.bit_string!=std::ptr::null_mut() {
110            unsafe {
111            alloc::dealloc(self.bit_string as *mut u8, alloc::Layout::from_size_align_unchecked(self.u64_count*std::mem::size_of::<u64>(), 1));
112            self.bit_string=std::ptr::null_mut();
113            }
114        }
115    }
116}