Skip to content

Commit aa44786

Browse files
feat: Add execution statistics for max plans in flight and plan queue memory usage (#815)
1 parent 47419b8 commit aa44786

4 files changed

Lines changed: 59 additions & 1 deletion

File tree

src/context.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,10 @@ impl Context {
587587
}
588588

589589
pub fn get_execution_statistics(&mut self) -> ExecutionStatistics {
590-
self.execution_profiler.compute_final_statistics()
590+
let mut stats = self.execution_profiler.compute_final_statistics();
591+
stats.max_plans_in_flight = self.plan_queue.max_plans_in_flight;
592+
stats.max_plan_queue_memory_in_use = self.plan_queue.max_memory_in_use;
593+
stats
591594
}
592595
}
593596

src/execution_stats.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ pub fn get_high_res_time() -> f64 {
3131
#[derive(Serialize)]
3232
pub struct ExecutionStatistics {
3333
pub max_memory_usage: u64,
34+
pub max_plans_in_flight: u64,
35+
pub max_plan_queue_memory_in_use: u64,
3436
pub cpu_time: Duration,
3537
pub wall_time: Duration,
3638
}
@@ -171,6 +173,8 @@ impl ExecutionProfilingCollector {
171173

172174
ExecutionStatistics {
173175
max_memory_usage: self.max_memory_usage,
176+
max_plans_in_flight: 0,
177+
max_plan_queue_memory_in_use: 0,
174178
cpu_time,
175179
wall_time,
176180
}
@@ -190,6 +194,15 @@ pub fn print_execution_statistics(summary: &ExecutionStatistics) {
190194
"Max memory usage:",
191195
ByteSize::b(summary.max_memory_usage)
192196
);
197+
println!(
198+
"{:<25}{}",
199+
"Max plans in flight:", summary.max_plans_in_flight
200+
);
201+
println!(
202+
"{:<25}{}",
203+
"Max plan queue memory:",
204+
ByteSize::b(summary.max_plan_queue_memory_in_use)
205+
);
193206
println!("{:<25}{}", "CPU time:", format_duration(summary.cpu_time));
194207
}
195208

@@ -205,6 +218,11 @@ pub fn log_execution_statistics(stats: &ExecutionStatistics) {
205218
info!("Memory and CPU statistics are not available on your platform.");
206219
} else {
207220
info!("Max memory usage: {}", ByteSize::b(stats.max_memory_usage));
221+
info!("Max plans in flight: {}", stats.max_plans_in_flight);
222+
info!(
223+
"Max plan queue memory: {}",
224+
ByteSize::b(stats.max_plan_queue_memory_in_use)
225+
);
208226
info!("CPU time: {}", format_duration(stats.cpu_time));
209227
}
210228
info!("Wall time: {}", format_duration(stats.wall_time));
@@ -251,6 +269,8 @@ mod tests {
251269

252270
// Fields should be non-zero
253271
assert!(stats.max_memory_usage > 0);
272+
assert_eq!(stats.max_plans_in_flight, 0);
273+
assert_eq!(stats.max_plan_queue_memory_in_use, 0);
254274
assert!(stats.wall_time > Duration::ZERO);
255275
}
256276

src/plan.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,14 @@ use crate::{trace, HashMap, HashMapExt};
3131
pub struct Queue<T, P: Eq + PartialEq + Ord> {
3232
queue: BinaryHeap<PlanSchedule<P>>,
3333
data_map: HashMap<u64, T>,
34+
/// The number of plans that have been added; equivalently, the next plan ID that
35+
/// will be issued.
3436
plan_counter: u64,
37+
/// Tracks the high water mark of plans in flight (scheduled but not yet executed).
38+
/// This is the max of `self.queue.len()`, not of `self.data_map.len()`.
39+
pub(crate) max_plans_in_flight: u64,
40+
/// Tracks the high water mark of memory allocated (capacity, not use) by this structure
41+
pub(crate) max_memory_in_use: u64,
3542
}
3643

3744
impl<T, P: Eq + PartialEq + Ord> Queue<T, P> {
@@ -42,6 +49,8 @@ impl<T, P: Eq + PartialEq + Ord> Queue<T, P> {
4249
queue: BinaryHeap::new(),
4350
data_map: HashMap::new(),
4451
plan_counter: 0,
52+
max_plans_in_flight: 0,
53+
max_memory_in_use: 0,
4554
}
4655
}
4756

@@ -60,6 +69,11 @@ impl<T, P: Eq + PartialEq + Ord> Queue<T, P> {
6069
});
6170
self.data_map.insert(plan_id, data);
6271
self.plan_counter += 1;
72+
self.max_plans_in_flight = self.max_plans_in_flight.max(self.queue.len() as u64);
73+
self.max_memory_in_use = self
74+
.max_memory_in_use
75+
.max(self.estimated_memory_in_use() as u64);
76+
6377
PlanId(plan_id)
6478
}
6579

@@ -148,6 +162,14 @@ impl<T, P: Eq + PartialEq + Ord> Queue<T, P> {
148162
pub(crate) fn remaining_plan_count(&self) -> usize {
149163
self.queue.len()
150164
}
165+
166+
fn estimated_memory_in_use(&self) -> usize {
167+
let queue_bytes = self.queue.capacity() * size_of::<PlanSchedule<P>>();
168+
169+
let map_entry_bytes = self.data_map.capacity() * size_of::<(u64, T)>();
170+
171+
queue_bytes + map_entry_bytes
172+
}
151173
}
152174

153175
impl<T, P: Eq + PartialEq + Ord> Default for Queue<T, P> {

src/profiling/file.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ impl Serialize for SerializableDuration {
3232
#[derive(Serialize)]
3333
struct SerializableExecutionStatistics {
3434
max_memory_usage: u64,
35+
max_plans_in_flight: u64,
36+
max_plan_queue_memory_in_use: u64,
3537
cpu_time: SerializableDuration,
3638
wall_time: SerializableDuration,
3739
}
@@ -41,6 +43,8 @@ impl From<ExecutionStatistics> for SerializableExecutionStatistics {
4143
fn from(value: ExecutionStatistics) -> Self {
4244
SerializableExecutionStatistics {
4345
max_memory_usage: value.max_memory_usage,
46+
max_plans_in_flight: value.max_plans_in_flight,
47+
max_plan_queue_memory_in_use: value.max_plan_queue_memory_in_use,
4448
cpu_time: SerializableDuration(value.cpu_time),
4549
wall_time: SerializableDuration(value.wall_time),
4650
}
@@ -189,6 +193,8 @@ mod tests {
189193

190194
let exec_stats = ExecutionStatistics {
191195
max_memory_usage: 1024 * 1024,
196+
max_plans_in_flight: 12,
197+
max_plan_queue_memory_in_use: 4096,
192198
cpu_time: Duration::from_secs(1),
193199
wall_time: Duration::from_secs(2),
194200
};
@@ -211,6 +217,11 @@ mod tests {
211217
json["execution_statistics"]["max_memory_usage"],
212218
1024 * 1024
213219
);
220+
assert_eq!(json["execution_statistics"]["max_plans_in_flight"], 12);
221+
assert_eq!(
222+
json["execution_statistics"]["max_plan_queue_memory_in_use"],
223+
4096
224+
);
214225

215226
let counts = json["named_counts"].as_array().unwrap();
216227
assert!(!counts.is_empty());
@@ -238,6 +249,8 @@ mod tests {
238249

239250
let exec_stats = ExecutionStatistics {
240251
max_memory_usage: 2048,
252+
max_plans_in_flight: 3,
253+
max_plan_queue_memory_in_use: 8192,
241254
cpu_time: Duration::from_secs_f64(1.5),
242255
wall_time: Duration::from_secs_f64(2.5),
243256
};

0 commit comments

Comments
 (0)