Allocate a slot. Returns the slot index, or None if the tier is full (caller should grow the tier).
(&mut self, data: &[u8])
| 50 | /// Allocate a slot. Returns the slot index, or None if the tier is full |
| 51 | /// (caller should grow the tier). |
| 52 | fn alloc(&mut self, data: &[u8]) -> Option<u32> { |
| 53 | debug_assert!(data.len() <= self.slot_size); |
| 54 | |
| 55 | if let Some(slot_idx) = self.free_list.pop() { |
| 56 | let offset = slot_idx as usize * self.slot_size; |
| 57 | self.buf[offset..offset + data.len()].copy_from_slice(data); |
| 58 | // Zero remaining bytes in the slot (deterministic reads). |
| 59 | if data.len() < self.slot_size { |
| 60 | self.buf[offset + data.len()..offset + self.slot_size].fill(0); |
| 61 | } |
| 62 | self.occupied += 1; |
| 63 | Some(slot_idx) |
| 64 | } else { |
| 65 | None // Tier full — caller must grow. |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | /// Grow the tier by doubling its capacity. |
| 70 | fn grow(&mut self) { |