micromegas_analytics/lakehouse/
scoped_memory_pool.rs1use datafusion::error::Result;
13use datafusion::execution::memory_pool::{
14 MemoryConsumer, MemoryLimit, MemoryPool, MemoryReservation,
15};
16use std::sync::Arc;
17use std::sync::atomic::{AtomicUsize, Ordering};
18
19#[derive(Debug)]
22pub struct ScopedMemoryPool {
23 inner: Arc<dyn MemoryPool>,
24 current: AtomicUsize,
25 peak: AtomicUsize,
26}
27
28impl ScopedMemoryPool {
29 pub fn new(inner: Arc<dyn MemoryPool>) -> Self {
31 Self {
32 inner,
33 current: AtomicUsize::new(0),
34 peak: AtomicUsize::new(0),
35 }
36 }
37
38 pub fn peak(&self) -> usize {
40 self.peak.load(Ordering::Relaxed)
41 }
42
43 pub fn current(&self) -> usize {
45 self.current.load(Ordering::Relaxed)
46 }
47
48 fn record_grow(&self, additional: usize) {
51 let cur = self.current.fetch_add(additional, Ordering::Relaxed) + additional;
52 self.peak.fetch_max(cur, Ordering::Relaxed);
53 }
54}
55
56impl MemoryPool for ScopedMemoryPool {
57 fn name(&self) -> &str {
58 "scoped"
59 }
60
61 fn register(&self, consumer: &MemoryConsumer) {
65 self.inner.register(consumer);
66 }
67
68 fn unregister(&self, consumer: &MemoryConsumer) {
69 self.inner.unregister(consumer);
70 }
71
72 fn grow(&self, reservation: &MemoryReservation, additional: usize) {
73 self.inner.grow(reservation, additional);
74 self.record_grow(additional);
75 }
76
77 fn try_grow(&self, reservation: &MemoryReservation, additional: usize) -> Result<()> {
78 self.inner.try_grow(reservation, additional)?; self.record_grow(additional);
80 Ok(())
81 }
82
83 fn shrink(&self, reservation: &MemoryReservation, shrink: usize) {
84 self.inner.shrink(reservation, shrink);
85 let prev = self.current.fetch_sub(shrink, Ordering::Relaxed);
86 debug_assert!(prev >= shrink, "scoped pool shrink underflow");
87 }
88
89 fn reserved(&self) -> usize {
90 self.inner.reserved() }
92
93 fn memory_limit(&self) -> MemoryLimit {
94 self.inner.memory_limit()
95 }
96}
97
98impl std::fmt::Display for ScopedMemoryPool {
99 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100 write!(
101 f,
102 "scoped(inner_pool: {}, peak: {})",
103 self.inner,
104 self.peak()
105 )
106 }
107}