pub const DEFAULT_BATCH_SIZE: usize = 65_536;
pub const DEFAULT_MAX_BATCH_BYTES: usize = i32::MAX as usize;
#[must_use]
pub fn default_max_batch_bytes() -> usize {
static RESOLVED: std::sync::OnceLock<usize> = std::sync::OnceLock::new();
*RESOLVED.get_or_init(|| {
let mut system = sysinfo::System::new();
system.refresh_memory();
let quarter = usize::try_from(system.total_memory() / 4).unwrap_or(usize::MAX);
if quarter == 0 {
DEFAULT_MAX_BATCH_BYTES
} else {
quarter.min(DEFAULT_MAX_BATCH_BYTES)
}
})
}
const DEFAULT_MAX_THREADS: usize = 4;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub struct ArrowReadOptions {
pub batch_size: usize,
pub max_batch_bytes: usize,
pub threads: usize,
}
impl Default for ArrowReadOptions {
fn default() -> Self {
Self {
batch_size: DEFAULT_BATCH_SIZE,
max_batch_bytes: default_max_batch_bytes(),
threads: 0,
}
}
}
impl ArrowReadOptions {
pub fn with_batch_size(batch_size: usize) -> Self {
Self {
batch_size: batch_size.max(1),
..Self::default()
}
}
#[must_use]
pub fn with_max_batch_bytes(mut self, max_batch_bytes: usize) -> Self {
self.max_batch_bytes = max_batch_bytes.clamp(1, DEFAULT_MAX_BATCH_BYTES);
self
}
#[must_use]
pub fn with_threads(mut self, threads: usize) -> Self {
self.threads = threads;
self
}
pub(crate) fn resolved_threads(self) -> usize {
if self.threads > 0 {
return self.threads;
}
std::thread::available_parallelism()
.map(std::num::NonZeroUsize::get)
.unwrap_or(1)
.min(DEFAULT_MAX_THREADS)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_default_ceiling_never_exceeds_the_offset_limit() {
let resolved = default_max_batch_bytes();
assert!(resolved > 0, "a zero ceiling would put one row in a batch");
assert!(
resolved <= DEFAULT_MAX_BATCH_BYTES,
"i32 offsets cannot address {resolved} bytes"
);
assert_eq!(resolved, default_max_batch_bytes());
}
#[test]
fn a_caller_cannot_raise_the_ceiling_past_the_offset_limit() {
let options = ArrowReadOptions::default().with_max_batch_bytes(usize::MAX);
assert_eq!(options.max_batch_bytes, DEFAULT_MAX_BATCH_BYTES);
}
}