shared-framework 0.0.17

Reusable building blocks for HTTP services — Hyper routing, SeaORM data layer, validation, OpenAPI docs, jobs, queues, cache.
Documentation
//! Fixed-size batching buffer.
//!
//! [`BatchContainer<T>`] accumulates items and exposes each full `batch_size`
//! group via [`drain_ready`](BatchContainer::drain_ready). A partial trailing
//! group is only returned by [`flush`](BatchContainer::flush).
//!
//! ```ignore
//! let mut batches = BatchContainer::new(10);
//! batches.add(item);
//! for batch in batches.drain_ready() { process(batch); }
//! ```

use std::collections::VecDeque;

/// Accumulates items of type `T` into fixed-size batches.
pub struct BatchContainer<T> {
    batch_size: usize,
    buffer: Vec<T>,
    ready: VecDeque<Vec<T>>,
}

impl<T> BatchContainer<T> {
    /// Creates a buffer that marks a batch ready every `batch_size` items.
    /// Panics if `batch_size` is zero.
    pub fn new(batch_size: usize) -> Self {
        assert!(batch_size > 0);
        Self { batch_size, buffer: Vec::with_capacity(batch_size), ready: VecDeque::new() }
    }

    /// Pushes an item; a batch becomes ready each time the buffer reaches `batch_size`.
    pub fn add(&mut self, item: T) {
        self.buffer.push(item);
        if self.buffer.len() >= self.batch_size {
            let batch = std::mem::replace(&mut self.buffer, Vec::with_capacity(self.batch_size));
            self.ready.push_back(batch);
        }
    }

    /// Returns true when at least one full batch is waiting to be drained.
    pub fn has_ready_batches(&self) -> bool { !self.ready.is_empty() }

    /// Removes and returns all currently ready full batches.
    pub fn drain_ready(&mut self) -> Vec<Vec<T>> {
        self.ready.drain(..).collect()
    }

    /// Returns all ready batches plus the partial trailing buffer, if non-empty.
    pub fn flush(&mut self) -> Vec<Vec<T>> {
        let mut out = self.drain_ready();
        if !self.buffer.is_empty() {
            out.push(std::mem::take(&mut self.buffer));
        }
        out
    }

    /// Returns the number of items in the partial trailing buffer.
    pub fn pending_len(&self) -> usize { self.buffer.len() }
}