oxihuman_core/
batch_queue.rs1#![allow(dead_code)]
4
5use std::collections::VecDeque;
8
9#[allow(dead_code)]
11#[derive(Debug, Clone)]
12pub struct BatchQueue<T> {
13 items: VecDeque<T>,
14 batch_size: usize,
15}
16
17#[allow(dead_code)]
18impl<T> BatchQueue<T> {
19 pub fn new(batch_size: usize) -> Self {
20 let bs = if batch_size == 0 { 1 } else { batch_size };
21 Self {
22 items: VecDeque::new(),
23 batch_size: bs,
24 }
25 }
26
27 pub fn enqueue(&mut self, item: T) {
28 self.items.push_back(item);
29 }
30
31 pub fn enqueue_many(&mut self, iter: impl IntoIterator<Item = T>) {
32 for item in iter {
33 self.items.push_back(item);
34 }
35 }
36
37 pub fn drain_batch(&mut self) -> Vec<T> {
38 let n = self.batch_size.min(self.items.len());
39 self.items.drain(..n).collect()
40 }
41
42 pub fn has_full_batch(&self) -> bool {
43 self.items.len() >= self.batch_size
44 }
45
46 pub fn len(&self) -> usize {
47 self.items.len()
48 }
49
50 pub fn is_empty(&self) -> bool {
51 self.items.is_empty()
52 }
53
54 pub fn batch_size(&self) -> usize {
55 self.batch_size
56 }
57
58 pub fn pending_batch_count(&self) -> usize {
59 if self.items.is_empty() {
60 0
61 } else {
62 self.items.len().div_ceil(self.batch_size)
63 }
64 }
65
66 pub fn clear(&mut self) {
67 self.items.clear();
68 }
69
70 pub fn peek_front(&self) -> Option<&T> {
71 self.items.front()
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn new_queue_is_empty() {
81 let q = BatchQueue::<i32>::new(4);
82 assert!(q.is_empty());
83 }
84
85 #[test]
86 fn enqueue_and_drain() {
87 let mut q = BatchQueue::new(2);
88 q.enqueue(1);
89 q.enqueue(2);
90 q.enqueue(3);
91 let batch = q.drain_batch();
92 assert_eq!(batch, vec![1, 2]);
93 assert_eq!(q.len(), 1);
94 }
95
96 #[test]
97 fn drain_partial_batch() {
98 let mut q = BatchQueue::new(5);
99 q.enqueue(10);
100 let batch = q.drain_batch();
101 assert_eq!(batch, vec![10]);
102 }
103
104 #[test]
105 fn has_full_batch() {
106 let mut q = BatchQueue::new(2);
107 q.enqueue(1);
108 assert!(!q.has_full_batch());
109 q.enqueue(2);
110 assert!(q.has_full_batch());
111 }
112
113 #[test]
114 fn pending_batch_count() {
115 let mut q = BatchQueue::new(3);
116 q.enqueue_many(0..7);
117 assert_eq!(q.pending_batch_count(), 3); }
119
120 #[test]
121 fn clear_empties() {
122 let mut q = BatchQueue::new(2);
123 q.enqueue(1);
124 q.clear();
125 assert!(q.is_empty());
126 }
127
128 #[test]
129 fn batch_size_zero_becomes_one() {
130 let q = BatchQueue::<i32>::new(0);
131 assert_eq!(q.batch_size(), 1);
132 }
133
134 #[test]
135 fn peek_front() {
136 let mut q = BatchQueue::new(4);
137 assert!(q.peek_front().is_none());
138 q.enqueue(42);
139 assert_eq!(q.peek_front(), Some(&42));
140 }
141
142 #[test]
143 fn enqueue_many_works() {
144 let mut q = BatchQueue::new(3);
145 q.enqueue_many(vec![1, 2, 3, 4]);
146 assert_eq!(q.len(), 4);
147 }
148
149 #[test]
150 fn drain_empty_returns_empty() {
151 let mut q = BatchQueue::<i32>::new(4);
152 assert!(q.drain_batch().is_empty());
153 }
154}