Skip to main content

xmtp_api_backend/queries/
mod.rs

1#[cfg(not(target_arch = "wasm32"))]
2mod backend;
3#[cfg(not(target_arch = "wasm32"))]
4pub use backend::*;
5mod api_stats;
6#[cfg(not(target_arch = "wasm32"))]
7mod bidi;
8#[cfg(not(target_arch = "wasm32"))]
9mod bidi_transport;
10#[cfg(all(test, not(target_arch = "wasm32")))]
11mod bidi_transport_props;
12mod boxed_streams;
13mod builder;
14pub mod stream;
15
16pub use api_stats::*;
17#[cfg(not(target_arch = "wasm32"))]
18pub use bidi::*;
19#[cfg(not(target_arch = "wasm32"))]
20pub use bidi_transport::*;
21pub use boxed_streams::*;
22pub use builder::*;
23
24/// Keep input order while splitting at either the item count or byte budget.
25/// An item that alone exceeds a budget gets its own chunk; the caller rejects it.
26pub(crate) fn chunk_by_budget<T>(
27    items: Vec<T>,
28    max_count: usize,
29    max_bytes: usize,
30    wire_cost: impl Fn(&T) -> usize,
31) -> Vec<Vec<T>> {
32    let mut chunks: Vec<Vec<T>> = Vec::new();
33    let mut current: Vec<T> = Vec::new();
34    let mut current_bytes = 0usize;
35    for item in items {
36        let cost = wire_cost(&item);
37        if !current.is_empty() && (current.len() >= max_count || current_bytes + cost > max_bytes) {
38            chunks.push(std::mem::take(&mut current));
39            current_bytes = 0;
40        }
41        current_bytes += cost;
42        current.push(item);
43    }
44    if !current.is_empty() {
45        chunks.push(current);
46    }
47    chunks
48}