trueno/brick/patterns/
reserve_strategy.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum ReserveStrategy {
6 Exact,
8 Grow50,
10 Double,
12 PowerOfTwo,
14}
15
16#[must_use]
28pub fn reserve_capacity(needed: usize, strategy: ReserveStrategy) -> usize {
29 match strategy {
30 ReserveStrategy::Exact => needed,
31 ReserveStrategy::Grow50 => needed + needed / 2,
32 ReserveStrategy::Double => needed * 2,
33 ReserveStrategy::PowerOfTwo => needed.next_power_of_two(),
34 }
35}
36
37#[derive(Debug)]
39pub struct StrategicBuffer {
40 data: Vec<u8>,
41 strategy: ReserveStrategy,
42}
43
44impl StrategicBuffer {
45 pub fn new(strategy: ReserveStrategy) -> Self {
47 Self { data: Vec::new(), strategy }
48 }
49
50 pub fn with_capacity(capacity: usize, strategy: ReserveStrategy) -> Self {
52 Self { data: Vec::with_capacity(reserve_capacity(capacity, strategy)), strategy }
53 }
54
55 pub fn reserve(&mut self, additional: usize) {
57 let needed = self.data.len() + additional;
58 if needed > self.data.capacity() {
59 let new_cap = reserve_capacity(needed, self.strategy);
60 self.data.reserve(new_cap - self.data.capacity());
61 }
62 }
63
64 pub fn write(&mut self, bytes: &[u8]) {
66 contract_pre_write!();
67 self.reserve(bytes.len());
68 self.data.extend_from_slice(bytes);
69 }
70
71 #[must_use]
73 pub fn as_slice(&self) -> &[u8] {
74 &self.data
75 }
76
77 #[must_use]
79 pub fn len(&self) -> usize {
80 self.data.len()
81 }
82
83 #[must_use]
85 pub fn is_empty(&self) -> bool {
86 self.data.is_empty()
87 }
88
89 #[must_use]
91 pub fn capacity(&self) -> usize {
92 self.data.capacity()
93 }
94
95 pub fn clear(&mut self) {
97 self.data.clear();
98 }
99}
100
101impl Default for StrategicBuffer {
102 fn default() -> Self {
103 Self::new(ReserveStrategy::Double)
104 }
105}