Skip to content

Commit 5bb2c36

Browse files
adriangbclaude
andcommitted
Cover Arrow-side reservations reaching the peak recorder
`ArrowMemoryPool` implements Arrow's `MemoryPool` by growing a DataFusion `MemoryReservation` against the pool it wraps, so a buffer claimed through it reaches `PeakRecordingPool::grow` and is recorded like any other reservation. Nothing in DataFusion claims buffers today, but that makes the peak follow the accounting as it changes rather than fixing it to the current set of manually tracked consumers. That property was assumed rather than tested. Add a test that builds an `ArrowMemoryPool` over the recording pool and asserts an Arrow-side reservation both raises the peak and releases on drop. `arrow-buffer/pool` and `datafusion-execution/arrow_buffer_pool` are enabled as dev-dependencies only, so the benchmark binaries are built with exactly the features they were before. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent bd5f16f commit 5bb2c36

3 files changed

Lines changed: 43 additions & 0 deletions

File tree

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

benchmarks/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ tokio = { workspace = true, features = ["rt-multi-thread", "parking_lot"] }
6464
tokio-util = { version = "0.7.17" }
6565

6666
[dev-dependencies]
67+
# `pool`/`arrow_buffer_pool` are enabled only for tests, so the benchmark
68+
# binaries are built exactly as before. They let `memory_pool`'s tests cover
69+
# Arrow-side reservations reaching the pool via `ArrowMemoryPool`.
70+
arrow-buffer = { workspace = true, features = ["pool"] }
71+
datafusion-execution = { workspace = true, features = ["arrow_buffer_pool"] }
6772
datafusion-proto = { workspace = true, features = ["parquet"] }
6873
tempfile = { workspace = true }
6974

benchmarks/src/util/memory_pool.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@
3333
//! This is measurement only: nothing here enforces a relationship between the
3434
//! two numbers.
3535
//!
36+
//! What lands in the peak is whatever the pool accounts for, so this follows
37+
//! the accounting rather than fixing it in place. Arrow-side reservations made
38+
//! through `ArrowMemoryPool` are included, because that adapter grows a
39+
//! DataFusion reservation against the pool it wraps; nothing claims buffers
40+
//! today, but the peak picks it up when something does.
41+
//!
3642
//! [`print_memory_stats`]: super::print_memory_stats
3743
3844
use std::{
@@ -287,4 +293,34 @@ mod tests {
287293
assert_eq!(wrapped.to_string(), inner.to_string());
288294
assert!(matches!(wrapped.memory_limit(), MemoryLimit::Finite(4096)));
289295
}
296+
297+
/// Arrow-side reservations reach the recorder too.
298+
///
299+
/// [`ArrowMemoryPool`] implements Arrow's `MemoryPool` by growing a
300+
/// DataFusion [`MemoryReservation`] against the pool it wraps, so a buffer
301+
/// claimed through it lands in `grow` here. Nothing in DataFusion claims
302+
/// buffers yet (see apache/datafusion#22898), but when something does, the
303+
/// bytes show up in this peak without further changes — as long as the
304+
/// adapter is built from the `RuntimeEnv`'s pool, which is the wrapped one.
305+
/// This test pins that.
306+
#[test]
307+
fn records_reservations_arriving_through_the_arrow_adapter() {
308+
use arrow_buffer::MemoryPool as ArrowMemoryPoolTrait;
309+
use datafusion_execution::memory_pool::arrow::ArrowMemoryPool;
310+
311+
let (pool, _guard) = pool(4096);
312+
313+
let arrow_pool =
314+
ArrowMemoryPool::new(Arc::clone(&pool), MemoryConsumer::new("arrow"));
315+
let reservation = arrow_pool.reserve(1024);
316+
317+
// The Arrow-side reservation is visible as DataFusion pool usage...
318+
assert_eq!(pool.reserved(), 1024);
319+
assert_eq!(peak_pool_reserved(), Some(1024));
320+
321+
// ...and dropping it releases the bytes while the peak is retained.
322+
drop(reservation);
323+
assert_eq!(pool.reserved(), 0);
324+
assert_eq!(peak_pool_reserved(), Some(1024));
325+
}
290326
}

0 commit comments

Comments
 (0)