1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
const NUM_DWORDS: usize = 8;
pub struct Bitsfield {
data: [u32; NUM_DWORDS],
}
impl Bitsfield {
#[inline]
pub fn new() -> Bitsfield {
Bitsfield {
data: [0xffffffff; NUM_DWORDS],
}
}
#[inline]
pub fn set_used(&mut self, mut bit: u16) {
let mut offset = 0;
loop {
if offset >= NUM_DWORDS {
unimplemented!();
}
if bit < 32 {
let mask: u32 = 1 << bit;
let mask = !mask;
self.data[offset] &= mask;
return;
}
bit -= 32;
offset += 1;
}
}
#[inline]
pub fn set_unused(&mut self, mut bit: u16) {
let mut offset = 0;
loop {
if offset >= NUM_DWORDS {
unimplemented!();
}
if bit < 32 {
let mask: u32 = 1 << bit;
self.data[offset] |= mask;
return;
}
bit -= 32;
offset += 1;
}
}
#[inline]
pub fn is_used(&self, mut bit: u16) -> bool {
let mut offset = 0;
loop {
if offset >= NUM_DWORDS {
unimplemented!();
}
if bit < 32 {
let mask: u32 = 1 << bit;
return self.data[offset] & mask == 0;
}
bit -= 32;
offset += 1;
}
}
#[inline]
pub fn get_unused(&self) -> Option<u16> {
let mut offset = 0;
loop {
if offset >= NUM_DWORDS {
return None;
}
let v = self.data[offset].trailing_zeros() as u16;
if v < 32 {
return Some(v + offset as u16 * 32);
}
offset += 1;
}
}
}
#[cfg(test)]
mod tests {
use super::Bitsfield;
#[test]
fn get_unused() {
let mut bitsfield = Bitsfield::new();
bitsfield.set_used(0);
bitsfield.set_used(1);
assert_eq!(bitsfield.get_unused(), Some(2))
}
#[test]
fn get_unused2() {
let mut bitsfield = Bitsfield::new();
for i in 0 .. 34 {
bitsfield.set_used(i);
}
assert_eq!(bitsfield.get_unused(), Some(34))
}
#[test]
fn is_used() {
let mut bitsfield = Bitsfield::new();
bitsfield.set_used(5);
bitsfield.set_used(6);
bitsfield.set_used(37);
assert!(!bitsfield.is_used(4));
assert!(bitsfield.is_used(5));
assert!(bitsfield.is_used(6));
assert!(!bitsfield.is_used(7));
assert!(!bitsfield.is_used(36));
assert!(bitsfield.is_used(37));
assert!(!bitsfield.is_used(38));
}
}