1extern crate alloc;
4
5use alloc::rc::Rc;
6use core::cell::RefCell;
7use core::marker::PhantomData;
8
9type Used<V> = Rc<RefCell<Vec<V>>>;
10
11const BITS_IN_U32: usize = 32;
12
13fn value_of_index(values: &[u32], index: usize) -> Result<bool, ()> {
14 let value_index = index / BITS_IN_U32;
15 let offset = index % BITS_IN_U32;
16
17 if let Some(v) = values.get(value_index) {
18 if offset < 32 {
19 Ok(v & (1 << offset) != 0)
20 } else {
21 Err(())
22 }
23 } else {
24 Err(())
25 }
26}
27
28fn update_index(values: &mut [u32], index: usize, value: bool) -> Result<(), ()> {
29 let value_index = index / BITS_IN_U32;
30 let offset = index % BITS_IN_U32;
31
32 if let Some(v) = values.get_mut(value_index) {
33 if offset < 32 {
34 let mask = 1 << offset;
35 if value {
36 *v |= mask;
37 } else {
38 *v &= !mask;
39 }
40 Ok(())
41 } else {
42 Err(())
43 }
44 } else {
45 Err(())
46 }
47}
48
49pub struct BufferPool<V: Default + Clone> {
52 buffer: Used<V>,
53 buffer_size: usize,
54 used: Used<u32>,
55}
56
57pub struct BufferPoolBuilder<V: Default + Clone> {
59 buffer_size: usize,
60 capacity: usize,
61 marker: PhantomData<V>,
62}
63
64impl<V: Clone + Default> Default for BufferPoolBuilder<V> {
65 fn default() -> BufferPoolBuilder<V> {
66 BufferPoolBuilder {
67 buffer_size: 1024,
68 capacity: 0,
69 marker: PhantomData {},
70 }
71 }
72}
73
74impl<V: Default + Clone> BufferPoolBuilder<V> {
75 pub fn new() -> BufferPoolBuilder<V> {
76 BufferPoolBuilder::default()
77 }
78
79 pub fn with_capacity(mut self, capacity: usize) -> BufferPoolBuilder<V> {
81 self.capacity = capacity;
82 self
83 }
84
85 pub fn with_buffer_size(mut self, buffer_size: usize) -> BufferPoolBuilder<V> {
87 self.buffer_size = buffer_size;
88 self
89 }
90
91 pub fn build(self) -> BufferPool<V> {
92 BufferPool {
93 buffer_size: self.buffer_size,
94 buffer: Rc::new(RefCell::new(vec![
95 V::default();
96 self.capacity * self.buffer_size
97 ])),
98 used: Rc::new(RefCell::new(vec![
99 0;
100 if self.capacity == 0 {
101 0
102 } else {
103 1 + ((self.capacity - 1) / BITS_IN_U32)
104 }
105 ])),
106 }
107 }
108}
109
110impl<V: Default + Clone> Default for BufferPool<V> {
111 fn default() -> BufferPool<V> {
112 BufferPoolBuilder::default().build()
113 }
114}
115
116impl<V: Default + Clone> BufferPool<V> {
117 pub fn builder() -> BufferPoolBuilder<V> {
118 BufferPoolBuilder::default()
119 }
120
121 fn find_free_index(&self) -> Result<usize, ()> {
122 let mut index = 0;
123 let max_index = self.capacity();
124
125 loop {
126 let used = self.used.borrow();
127 let used = used.as_slice();
128
129 if index % BITS_IN_U32 == 0 {
130 if let Some(value) = used.get(index / BITS_IN_U32) {
131 if value == &core::u32::MAX {
132 index += BITS_IN_U32;
133 continue;
134 }
135 }
136 }
137
138 if let Ok(value) = value_of_index(used, index) {
139 if !value {
140 return Ok(index);
141 } else {
142 index += 1;
143
144 if max_index <= index {
145 return Err(());
146 }
147 }
148 } else {
149 return Err(());
150 }
151 }
152 }
153
154 pub fn get_buffer_size(&self) -> usize {
155 self.buffer_size
156 }
157
158 pub fn try_clear(&mut self) -> Result<(), ()> {
160 if self.is_borrowed() {
161 Err(())
162 } else {
163 let mut buffer = self.buffer.borrow_mut();
164 for value in buffer.as_mut_slice().iter_mut() {
165 *value = V::default();
166 }
167 Ok(())
168 }
169 }
170
171 pub fn clear(&mut self) {
176 if self.try_clear().is_err() {
177 panic!("Cannot clear when buffers are borrowed!");
178 }
179 }
180
181 fn set_index_used(&mut self, index: usize) -> Result<(), ()> {
182 let mut used = self.used.borrow_mut();
183 let used = used.as_mut_slice();
184 update_index(used, index, true)
185 }
186
187 fn find_free_index_and_use(&mut self) -> Result<usize, ()> {
188 if let Ok(index) = self.find_free_index() {
189 self.set_index_used(index).map(|_| index)
190 } else {
191 Err(())
192 }
193 }
194
195 pub fn capacity(&self) -> usize {
197 let mut buffer = self.buffer.borrow_mut();
198 buffer.as_mut_slice().len() / self.buffer_size
199 }
200
201 pub fn change_buffer_size(&mut self, new_buffer_size: usize) {
206 if self.try_change_buffer_size(new_buffer_size).is_err() {
207 panic!("Cannot change buffer size when buffers are borrowed!");
208 }
209 }
210
211 pub fn try_change_buffer_size(&mut self, new_buffer_size: usize) -> Result<(), ()> {
213 let len = self.capacity();
214 self.buffer_size = new_buffer_size;
215 self.try_resize(len)
216 }
217
218 pub fn resize_len_and_buffer(&mut self, new_len: usize, new_buffer_size: usize) {
223 self.buffer_size = new_buffer_size;
224 self.resize(new_len);
225 }
226
227 pub fn is_empty(&self) -> bool {
229 self.capacity() == 0
230 }
231
232 pub fn reserve(&mut self, additional: usize) {
237 self.resize(self.capacity() + additional);
238 }
239
240 pub fn try_reserve(&mut self, additional: usize) -> Result<(), ()> {
242 self.try_resize(self.capacity() + additional)
243 }
244
245 pub fn is_borrowed(&self) -> bool {
247 let mut index = 0;
248 let max_index = self.capacity();
249
250 let used = self.used.borrow();
251 let used = used.as_slice();
252
253 loop {
254 if let Ok(value) = value_of_index(used, index) {
255 if value {
256 return false;
257 } else {
258 index += 1;
259
260 if max_index <= index {
261 break;
262 }
263 }
264 } else {
265 return false;
266 }
267 }
268
269 false
270 }
271
272 pub fn resize(&mut self, new_len: usize) {
277 if self.try_resize(new_len).is_err() {
278 panic!("Can't resize when borrowed!");
279 }
280 }
281
282 pub fn try_resize(&mut self, new_len: usize) -> Result<(), ()> {
284 if self.is_borrowed() {
285 Err(())
286 } else {
287 let mut buffer = self.buffer.borrow_mut();
288 (*buffer).resize_with(new_len * self.buffer_size, V::default);
289
290 let mut used_capacity = self.used.borrow().len() * BITS_IN_U32;
291
292 while used_capacity < new_len {
293 let new_len = self.used.borrow().len() + 1;
294
295 self.used.borrow_mut().resize(new_len, 0);
296
297 used_capacity = self.used.borrow().len() * BITS_IN_U32;
298 }
299
300 Ok(())
301 }
302 }
303
304 pub fn get_cleared_space(&mut self) -> Result<BufferPoolReference<V>, ()> {
307 self.get_space().and_then(|mut space| {
308 for value in space.as_mut().iter_mut() {
309 *value = V::default();
310 }
311
312 Ok(space)
313 })
314 }
315
316 pub fn get_space(&mut self) -> Result<BufferPoolReference<V>, ()> {
318 self.find_free_index_and_use().and_then(|index| {
319 let slice = unsafe {
320 (*self.buffer.borrow_mut())
321 .as_mut_ptr()
322 .add(index * self.buffer_size)
323 };
324
325 Ok(BufferPoolReference {
326 index,
327 used: Rc::clone(&self.used),
328 parent: Rc::clone(&self.buffer),
329 buffer_size: self.buffer_size,
330 slice,
331 })
332 })
333 }
334}
335
336pub struct BufferPoolReference<V> {
340 index: usize,
341 used: Used<u32>,
342 #[allow(dead_code)]
346 parent: Used<V>,
347 slice: *mut V,
348 buffer_size: usize,
349}
350
351impl<V> AsMut<[V]> for BufferPoolReference<V> {
352 fn as_mut(&mut self) -> &mut [V] {
353 unsafe { alloc::slice::from_raw_parts_mut(self.slice, self.buffer_size) }
354 }
355}
356
357impl<V> AsRef<[V]> for BufferPoolReference<V> {
358 fn as_ref(&self) -> &[V] {
359 unsafe { alloc::slice::from_raw_parts(self.slice, self.buffer_size) }
360 }
361}
362
363impl<V> Drop for BufferPoolReference<V> {
364 fn drop(&mut self) {
365 let mut used = self.used.borrow_mut();
366 let used = used.as_mut_slice();
367
368 if update_index(used, self.index, false).is_err() {
369 panic!("Unable to free reference for index {}!", self.index);
370 }
371 }
372}
373
374#[cfg(test)]
375mod tests {
376 use super::*;
377
378 #[test]
379 fn it_should_add_capacity() {
380 let mut pool: BufferPool<f32> = BufferPool::default();
381
382 assert_eq!(pool.capacity(), 0);
383
384 pool.reserve(1);
385
386 assert_eq!(pool.capacity(), 1);
387
388 pool.reserve(1);
389
390 assert_eq!(pool.capacity(), 2);
391 }
392
393 #[test]
394 fn it_should_get_space_if_capacity() {
395 let mut pool: BufferPool<f32> = BufferPool::default();
396
397 assert_eq!(pool.capacity(), 0);
398
399 assert!(pool.get_space().is_err());
400
401 pool.resize(1);
402
403 let index = pool.get_space().unwrap();
404
405 assert!(pool.get_space().is_err());
406 assert_eq!(index.index, 0);
407 }
408
409 #[test]
410 fn it_should_work_with_interesting_sizes() {
411 let sizes: Vec<usize> = vec![12, 100, 1001, 1024, 2048, 4096, 1];
412
413 for buffer_size in sizes.iter() {
414 for capacity in sizes.iter() {
415 let mut pool: BufferPool<f32> = BufferPoolBuilder::new()
416 .with_buffer_size(*buffer_size)
417 .with_capacity(*capacity)
418 .build();
419
420 assert_eq!(pool.capacity(), *capacity);
421 assert_eq!(pool.get_space().is_err(), false);
422 }
423 }
424 }
425
426 #[test]
427 fn it_should_return_space_when_deallocated() {
428 let mut pool: BufferPool<f32> = BufferPool::default();
429
430 assert_eq!(pool.capacity(), 0);
431 pool.reserve(1);
432
433 {
434 let index = pool.get_space().unwrap();
435 assert!(pool.get_space().is_err());
436 assert_eq!(index.index, 0);
437 }
438
439 assert!(pool.get_space().is_ok());
440 }
441
442 #[test]
443 fn it_should_update_internal_buffer() {
444 let buffer_size = 10;
445 let mut pool: BufferPool<f32> = BufferPool::default();
446 pool.change_buffer_size(buffer_size);
447 pool.reserve(10);
448
449 let mut a = pool.get_space().unwrap();
450 let mut b = pool.get_space().unwrap();
451
452 for value in a.as_mut().iter_mut() {
453 *value = 1.;
454 }
455
456 for value in b.as_mut().iter_mut() {
457 *value = 2.;
458 }
459
460 let buffer = pool.buffer.borrow();
461 assert_eq!(
462 (*buffer)[0..(buffer_size)],
463 vec![1. as f32; buffer_size][..]
464 );
465
466 assert_eq!(*a.as_ref(), vec![1. as f32; buffer_size][..]);
467
468 let buffer = pool.buffer.borrow();
469 assert_eq!(
470 (*buffer)[(buffer_size)..(2 * buffer_size)],
471 vec![2. as f32; buffer_size][..]
472 );
473
474 assert_eq!(*b.as_ref(), vec![2. as f32; buffer_size][..]);
475 }
476
477 #[test]
478 fn it_should_not_default_space_when_deallocated() {
479 let buffer_size = 10;
480 let mut pool: BufferPool<f32> = BufferPool::default();
481 pool.change_buffer_size(buffer_size);
482 pool.reserve(10);
483
484 {
485 let mut a = pool.get_space().unwrap();
486
487 for value in a.as_mut().iter_mut() {
488 *value = 1.;
489 }
490
491 let buffer = pool.buffer.borrow();
492 assert_eq!(
493 (*buffer)[0..(buffer_size)],
494 vec![1. as f32; buffer_size][..]
495 );
496
497 assert_eq!(*a.as_ref(), vec![1. as f32; buffer_size][..]);
498 }
499
500 let buffer = pool.buffer.borrow();
501
502 assert_eq!(
503 (*buffer)[0..(buffer_size)],
504 vec![1. as f32; buffer_size][..]
505 );
506 }
507
508 #[test]
509 fn it_should_clear_space_if_explicitly_requested() {
510 let buffer_size = 10;
511 let mut pool: BufferPool<f32> = BufferPool::default();
512 pool.change_buffer_size(buffer_size);
513 pool.reserve(10);
514
515 {
516 let mut a = pool.get_space().unwrap();
517
518 for value in a.as_mut().iter_mut() {
519 *value = 1.;
520 }
521
522 let buffer = pool.buffer.borrow();
523
524 assert_eq!(
525 (*buffer)[0..(buffer_size)],
526 vec![1. as f32; buffer_size][..]
527 );
528
529 assert_eq!(*a.as_ref(), vec![1. as f32; buffer_size][..]);
530 }
531
532 let space = pool.get_cleared_space().unwrap();
533
534 let buffer = pool.buffer.borrow();
535
536 assert_eq!(
537 (*buffer)[0..(buffer_size)],
538 vec![0. as f32; buffer_size][..]
539 );
540
541 assert_eq!(*space.as_ref(), vec![0. as f32; buffer_size][..]);
542 }
543
544 #[test]
545 fn it_should_still_work_if_parent_is_dropped() {
546 let buffer_size = 10;
547 let mut pool: BufferPool<usize> = BufferPool::default();
548 pool.change_buffer_size(buffer_size);
549 pool.reserve(10);
550
551 let space = pool.get_cleared_space().unwrap();
552
553 drop(pool);
554
555 let value = space.as_ref().iter().fold(0, |a, b| a + b);
556 assert_eq!(value, 0);
557 }
558}