1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//! Memory management utilities for efficient query execution
//!
//! This module provides memory-bounded execution for SQL query operators,
//! enabling processing of datasets larger than available memory through
//! disk spilling.
//!
//! # Components
//!
//! - **Memory Controller** (`MemoryController`): Budget management and tracking
//! - **Memory Reservation** (`MemoryReservation`): Per-operator memory tracking
//! - **External Sort** (`ExternalSort`): Disk-spilling merge sort
//! - **External Aggregate** (`ExternalAggregate`): Partition-based GROUP BY
//! - **External Hash Join** (`ExternalHashJoin`): Grace hash join with spilling
//! - **Spill Files** (`SpillFile`): Temporary file management with auto-cleanup
//! - **Arena Allocator** (`QueryArena`): Fast bump-pointer allocator
//!
//! # Architecture
//!
//! ```text
//! ┌─────────────────────────────────────────────────────────────────┐
//! │ MemoryController │
//! │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
//! │ │ Budget Pool │ │ Tracking │ │ Metrics │ │
//! │ │ (configurable)│ │ (per-operator)│ │ (spills, peak, etc.) │ │
//! │ └─────────────┘ └─────────────┘ └─────────────────────────┘ │
//! └─────────────────────────────────────────────────────────────────┘
//! │ │ │
//! ▼ ▼ ▼
//! ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
//! │ External │ │ External │ │ External │
//! │ Sort │ │ Aggregate │ │ Hash Join │
//! │ (merge sort) │ │ (partitioned)│ │ (grace join) │
//! └──────────────┘ └──────────────┘ └──────────────┘
//! │ │ │
//! ▼ ▼ ▼
//! ┌─────────────────────────────────────────────────────────────────┐
//! │ SpillFile (temp files) │
//! │ Auto-cleanup on drop, buffered I/O, seeking │
//! └─────────────────────────────────────────────────────────────────┘
//! ```
//!
//! # Memory-Bounded Execution
//!
//! ```text
//! use std::sync::Arc;
//! use vibesql_executor::memory::{MemoryController, MemoryConfig};
//!
//! // Create controller with 1GB budget
//! let controller = Arc::new(MemoryController::with_budget(1024 * 1024 * 1024));
//!
//! // Operators create reservations to track their memory
//! let mut reservation = controller.create_reservation();
//!
//! // When memory is exhausted, spill to disk
//! if !reservation.try_grow(batch_size) {
//! spill_to_disk(&data);
//! reservation.shrink(data.size());
//! }
//!
//! // Check statistics after execution
//! let stats = controller.stats();
//! println!("{}", stats); // "Memory: 512MB/1GB (50%), peak: 950MB, spilled: 2GB (3 ops)"
//! ```
//!
//! # External Operators
//!
//! ## External Sort
//!
//! Two-phase external merge sort:
//! 1. **Run generation**: Sort in-memory chunks, spill as sorted runs
//! 2. **K-way merge**: Merge runs using a tournament tree
//!
//! ```text
//! let mut sort = ExternalSort::new(controller, config, sort_keys);
//! for row in input {
//! sort.add_row(&row)?; // Automatically spills when needed
//! }
//! for result in sort.finish()? {
//! // Rows come out in sorted order
//! }
//! ```
//!
//! ## External Aggregate
//!
//! Partition-based aggregation for GROUP BY:
//! 1. Hash rows to partitions
//! 2. Spill partitions when memory exhausted
//! 3. Process each partition's groups
//!
//! ```text
//! let specs = vec![AggregateSpec { function_name: "SUM".into(), .. }];
//! let mut agg = ExternalAggregate::new(controller, config, specs, 2);
//! for row in input {
//! agg.add_row(&row)?;
//! }
//! for result in agg.finish()? {
//! // (group_key..., aggregate_values...)
//! }
//! ```
//!
//! ## External Hash Join
//!
//! Grace hash join with partition-based spilling:
//! 1. Partition both build and probe sides by join key hash
//! 2. Spill partitions when memory exhausted
//! 3. Process matching partitions together
//!
//! ```text
//! let mut join = ExternalHashJoin::new(
//! controller, config,
//! vec![0], // build key columns
//! vec![0], // probe key columns
//! JoinType::Inner,
//! );
//! for row in build_side { join.add_build_row(&row)?; }
//! for row in probe_side { join.add_probe_row(&row)?; }
//! for result in join.finish()? {
//! // Joined rows
//! }
//! ```
//!
//! # Configuration
//!
//! Environment variables:
//!
//! | Variable | Description | Default |
//! |----------|-------------|---------|
//! | `VIBESQL_MEMORY_LIMIT` | Total memory budget (e.g., "4GB") | 1GB |
//! | `VIBESQL_TEMP_DIR` | Directory for spill files | system temp |
//! | `VIBESQL_SPILL_THRESHOLD` | When to start spilling (0.0-1.0) | 0.8 |
//! | `VIBESQL_PARTITION_SIZE` | Target partition size | 64MB |
pub use QueryArena;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;