1use bit_vec::BitVec;
2
3const DEVICE_COUNT: usize = 4096;
4const BYTE_COUNT: usize = DEVICE_COUNT / 8;
5
6pub struct DeviceIdAllocator {
7 states: BitVec,
8 cursor: u32,
9}
10
11impl Default for DeviceIdAllocator {
12 fn default() -> Self {
13 Self::new()
14 }
15}
16
17impl DeviceIdAllocator {
18 pub fn new() -> Self {
19 Self {
20 states: BitVec::from_elem(DEVICE_COUNT, false),
21 cursor: 0,
22 }
23 }
24
25 pub fn deserialize(bytes: &[u8]) -> Option<Self> {
26 if bytes.len() != BYTE_COUNT + 4 {
27 return None;
28 }
29
30 let cursor = bytes[0] as u32
31 | ((bytes[1] as u32) << 8)
32 | ((bytes[2] as u32) << 16)
33 | ((bytes[3] as u32) << 24);
34 let slice = &bytes[4..BYTE_COUNT + 4];
35 if slice.len() != BYTE_COUNT {
36 return None;
37 }
38 let states = BitVec::from_bytes(slice);
39
40 Some(Self { states, cursor })
41 }
42
43 pub fn allocate(&mut self) -> Option<u32> {
44 let start = self.cursor;
45 loop {
46 let id = self.cursor;
47 let value = self.states.get(self.cursor as usize)?;
48
49 self.cursor = (self.cursor + 1) % DEVICE_COUNT as u32;
50
51 if !value {
52 self.states.set(id as usize, true);
53 return Some(id);
54 }
55
56 if self.cursor == start {
57 return None;
58 }
59 }
60 }
61
62 pub fn release(&mut self, id: u32) {
63 self.states.set(id as usize, false);
64 }
65
66 pub fn count_free(&mut self) -> u32 {
67 self.states.count_zeros() as u32
68 }
69
70 pub fn serialize(&mut self) -> Vec<u8> {
71 let mut bytes = Vec::with_capacity(BYTE_COUNT + 4);
72 bytes.push((self.cursor & 0xff) as u8);
73 bytes.push(((self.cursor >> 8) & 0xff) as u8);
74 bytes.push(((self.cursor >> 16) & 0xff) as u8);
75 bytes.push(((self.cursor >> 24) & 0xff) as u8);
76 bytes.extend_from_slice(&self.states.to_bytes());
77 bytes
78 }
79}