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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
/* src/ops/agg_engine.h — v2 composable aggregation engine entry (design §3). */
/* Test/feature knob: route OP_GROUP through the v2 engine when it can handle
* the query (see agg_v2_can_handle). Enabled by default. */
extern bool ray_agg_engine_v2;
/* Test/feature knob: let an unordered grouped `take: N` find its N groups
* before aggregating and fold only their rows (agg_first_n_run). On by default. */
extern bool ray_agg_first_n;
/* Test/feature knob: int/SYM-key parallel groups that are not dense pre-
* aggregate into per-task top-bit tables (table stack) and scatter only
* all-distinct tails; off = the former radix scatter of every row. */
extern bool ray_agg_tablestack;
/* Admission is pure: inspecting a plan must not change execution diagnostics. */
typedef enum agg_v2_reason_t;
agg_v2_reason_t ;
typedef enum agg_route_t;
typedef enum agg_dense_strategy_t;
/* Per-calling-thread dispatch counts since reset, not a whole-query trace.
* Nested/partitioned groups may record multiple routes. Incremented only at
* dispatch boundaries, never inside worker row loops. A count records an
* attempted dispatch (which may subsequently fail), not successful completion.
* last_v2_reason describes the most recent legacy/v2 admission decision. */
typedef struct agg_route_stats_t;
void ;
void ;
agg_route_stats_t ;
void ;
void ;
/* True iff the v2 engine fully supports this group node over this table.
* Conservative: any uncertainty → false → caller uses the existing engine. */
bool ;
/* Top-N keep decision shared by every strategy: keep[i] = 1 when group i
* passes min_count_exclusive and (when top_count_take > 0) lies within the
* top-N by value in the filter's direction, ties included (a superset of N;
* the DAG's sort+take downstream finalizes order and limit). Returns the
* number kept. vals may be NULL when n == 0. */
int64_t ;
/* The two halves of agg_topn_keep, for callers that reduce candidates in
* parallel: the N-th value in the keep direction (false when every value is
* kept), and the keep marking against a known threshold. */
bool ;
int64_t ;
/* Double view of aggregate `vt` for n groups: group i's state is at
* states + (slots ? slots[i] : i) * stride + off. Nulls (and NaN) map to
* -INFINITY, where the sort places them (first ascending, last descending).
* Returns false for an out_type without a scalar order (LIST, STR, ...). */
bool ;
/* Trim a finished group result to the emit filter's kept superset (row order
* preserved; consumes `result`). Used by routes that emit every group. */
ray_t* ;
/* Precondition: agg_v2_can_handle(g, op, tbl) returned true.
* `group_limit` is the HEAD(GROUP) row-limit HINT (0 = no limit): when
* positive, an engine strategy may emit only the first `group_limit` groups in
* first-seen order. Advisory only — the caller trims the result regardless. */
ray_t* ;
/* Dense group assignment over the group's key columns, first-occurrence
* order (key count unbounded since cut 3; the dense planner self-limits). */
typedef struct agg_groups_t;
/* Multi-key grouping, key count unbounded. Uses native integer/SYM,
* canonical float, byte/string, and structural LIST hash/equality. Assigns
* gids incrementally on first sight → gid
* order == first-occurrence order; first_row[gid] records the row where the
* group first appeared. Returns 0 on success (caller releases out via
* agg_groups_free()), -1 on allocation failure.
* n_keys is uint32_t: unbounded key count. Cut-3 lifted both admission gates
* (the GROUP path and the keys-only DISTINCT path) and the fixed data[16]
* inside became an exact carve, so any key count groups correctly. */
int ;
/* Exact wide-value distinct counts over an existing stable group index. */
ray_t* ;
/* Large flat grouping: return first-occurrence keys and stable index vectors,
* or NULL when the existing serial implementation should handle the input. */
ray_t* ;
/* Release the buffers an agg_groups_t holds (buddy-backed, NOT libc malloc — so
* callers must use this, not free()). Idempotent; NULLs the pointers. */
void ;
/* Multi-key `select {by: {keys}}` with no aggregates → result table carrying the
* first-of-group value of every `tbl` column (keys named by key_syms, then the
* non-key columns), SYM columns adopting their source domain (no global
* interning). See agg_engine.c. Precondition (caller-gated): keys are int/SYM
* and every tbl column is fixed-width/SYM/STR/LIST. Caller owns the table.
* keep_syms (or NULL) lists the column syms a consumer references — non-key
* columns NOT in it are dropped (projection pushdown); keys are always kept.
* nk is uint32_t: unbounded key count (cut-3 lifted query.c's distinct gate;
* agg_group_keys carves its key table, so any nk groups correctly). */
ray_t* ;
/* Build a dense SoA per-group state array for one aggregate (vt), run a single
* update_batch over val_col grouped by gids, and finalize each group into a
* typed result column of vt->out_type, length ngroups. For COUNT, val_col is
* NULL. Caller owns the returned column (ray_release). Returns a ray_error atom
* on allocation failure. Single-threaded (Phase 1a). */
ray_t* ;
ray_t* ;
/* ── Dense grouping eligibility selector (compact-range int/SYM keys) ──
* When dense applies, a group id is the packed key offset (O(1) direct index)
* rather than a hash slot. */
typedef struct dense_plan_t;
/* Release a plan's compaction tables (no-op for raw-range plans). */
void ;
/* Decide if dense grouping applies to (key_cols, aggs). Eligible iff:
* - every key type in {I64,I32,I16,U8,BOOL,DATE,TIME,TIMESTAMP,SYM} with a dedicated slot for nullable keys
* - product of per-key ranges is no larger than the contributing row count
* (so dense state is O(input), never controlled by a machine-size budget)
* Does one min/max prescan over the key columns. Sets out->ok accordingly.
* n_keys is uint32_t (untruncated ext->n_keys): dense direct-index routing
* self-limits to <=16 keys here (wider shapes are rejected to v2's unbounded
* hash/radix path), so the fixed [16] mins/ranges/strides are only ever read
* at <=16. n_aggs is unused by dense eligibility (kept uint32_t so a widened
* ext->n_aggs never narrows at this call). */
bool ;
/* Cardinality estimates for a planner choosing between strategies before
* any grouping runs (try_count_distinct_v2_rewrite), from one strided
* sample of 32,768 rows over `cols` (every row below that) — over the
* `nrows` row indices of `rows` when that is given (a selection's
* survivors), else over rows 0..nrows. When `rows` is itself a sample of
* a larger population (the survivors of a predicate run over sampled rows),
* `population` is that population's size — the estimates and the caps
* scale to it — else 0. A column's
* distinct values in the sample are raised by the Chao1 estimator from the
* values seen once and twice, so a key the sample cannot exhaust — a
* million values, or one value on most rows and a million on the rest — is
* estimated near its size, while a key of 45 values stays 45. The
* estimate is capped at the span of the sampled values — the codes of a
* SYM key, fixed once interned, where the process-wide domain's count
* would move the estimate with every symbol interned afterwards.
* col_est[k] (when given) receives column k's estimate;
* prefix_est the estimate for the tuple of the first n_prefix columns (the
* groups a composite key forms, which the product of its columns' estimates
* overstates when one column follows from another); prefix_max the rows of
* the largest such group (its share of the sample over the input: a
* per-group pass is serial over it); all_est the estimate
* for the tuple of all n columns (the tuples a (key, value) grouping would
* keep). A tuple is capped at the product of its columns' caps and at
* nrows; a sorted prefix, which a stride reads as all distinct, is read
* through blocks of adjacent rows as well. Estimates, never bounds: a
* planner weighs them against thresholds with slack. false — with the
* outputs unset — when a column is not a dense key type (integer, temporal,
* SYM), n is 0 or above 16, the input is empty, or memory runs out. */
bool ;
/* The rows the estimator samples (every row below that). */
/* The row the estimator samples from window i of the `sample` equal ones
* the rows are cut into (nrows / sample rows each, fractional): an offset
* into the window hashed from i by the splitmix64 finaliser. A fixed
* offset reads a key whose period divides the stride — five values
* cycling under a stride of 305 — as one value. An offset nearly linear
* in i, the high bits of i times the golden ratio, keeps the sampled rows
* an arithmetic progression and a key with a period near the stride at a
* nearly fixed phase: a composite of (% i 1000) and (% i 1009) at 10 M
* rows read as ten million tuples under it, one of 1000 and 1013 as a
* tenth of its groups. The finaliser's offsets make the collisions those
* of a random sample. Shared with a planner sampling rows for a predicate
* (query.c). */
static inline int64_t
/* The product of the per-key estimates above for key_cols: the packed key
* space a direct-index grouping would hold. -1 when a key is not a dense
* key type, the input is empty, or the product overflows. */
int64_t ;
/* Result column name for a plain-column-input aggregate: input column name
* (ray_sym_str of in_sym) + per-op suffix (_sum/_count/_mean/_min/_max/...),
* interned. Falls back to in_sym on buffer overflow. Behavior-identical to
* emit_agg_columns' inline naming for the OP_SCAN input case. */
int64_t ;
/* RAY_OPS_AGG_ENGINE_H */