molframe_core/io/
structure_batch_pool.rs1use super::{StructureBatch, StructureBatchBuffer, StructureBatchBuilder, StructureBatchError};
4use crate::execution::BatchBufferPool;
5use crate::{Batch, BatchLease, ChunkDescriptor, ExecutionContext, MemoryReservation};
6use std::sync::Arc;
7
8#[derive(Clone, Debug)]
14pub struct StructureBatchPool {
15 inner: Arc<BatchBufferPool<StructureBatch>>,
16}
17
18impl StructureBatchPool {
19 #[must_use]
21 pub fn new() -> Self {
22 Self {
23 inner: Arc::new(BatchBufferPool::new()),
24 }
25 }
26
27 pub fn acquire(
37 &self,
38 descriptor: ChunkDescriptor,
39 reserve_bytes: usize,
40 max_retained_bytes: usize,
41 context: &ExecutionContext,
42 ) -> Result<Option<(StructureBatchBuilder, MemoryReservation)>, StructureBatchError> {
43 let capacity = descriptor.rows();
44 let recycled = self.inner.take().filter(|(batch, reservation)| {
45 reservation.belongs_to(context) && batch.can_reuse(capacity, max_retained_bytes)
46 });
47 if let Some((batch, mut reservation)) = recycled {
48 if reservation.bytes() < reserve_bytes
49 && reservation
50 .try_grow(reserve_bytes - reservation.bytes())
51 .is_err()
52 {
53 self.inner.put(batch, reservation)?;
54 return Ok(None);
55 }
56 let buffer = StructureBatchBuffer::new(batch);
57 let builder = StructureBatchBuilder::reuse(
58 buffer,
59 descriptor.dataset(),
60 descriptor.chunk(),
61 descriptor.logical_start(),
62 )?;
63 return Ok(Some((builder, reservation)));
64 }
65 let Ok(reservation) = context.try_reserve(reserve_bytes) else {
66 return Ok(None);
67 };
68 let builder = StructureBatchBuilder::new(
69 descriptor.dataset(),
70 descriptor.chunk(),
71 descriptor.logical_start(),
72 capacity,
73 )?;
74 Ok(Some((builder, reservation)))
75 }
76
77 pub fn lease(
83 &self,
84 buffer: StructureBatchBuffer,
85 reservation: MemoryReservation,
86 ) -> Result<BatchLease<StructureBatch>, StructureBatchError> {
87 BatchLease::try_from_reservation_recycling(
88 buffer.into_owned(),
89 reservation,
90 Arc::clone(&self.inner),
91 )
92 .map_err(StructureBatchError::from)
93 }
94
95 pub fn recycle(&self, buffer: StructureBatchBuffer, reservation: MemoryReservation) {
97 if buffer.batch().retained_bytes() > reservation.bytes() {
98 drop(buffer);
99 return;
100 }
101 let _ = self.inner.put(buffer.into_owned(), reservation);
104 }
105}
106
107impl Default for StructureBatchPool {
108 fn default() -> Self {
109 Self::new()
110 }
111}
112
113#[cfg(test)]
114#[path = "structure_batch_pool_tests.rs"]
115mod tests;