#ifndef RAY_OPS_AGG_ENGINE_H
#define RAY_OPS_AGG_ENGINE_H
#include <rayforce.h>
#include "ops/internal.h"
#include "ops/agg_acc.h"
extern bool ray_agg_engine_v2;
typedef enum {
AGG_V2_ADMITTED,
AGG_V2_SHAPE,
AGG_V2_KEY_EXPRESSION,
AGG_V2_KEY_TYPE,
AGG_V2_AGG_EXPRESSION,
AGG_V2_AGG_TYPE,
AGG_V2_BUFFERED,
AGG_V2_PARAMETER,
AGG_V2_DISABLED,
AGG_V2_EMIT_FILTER,
AGG_V2_PARALLEL_WIDE,
} agg_v2_reason_t;
agg_v2_reason_t agg_v2_admission(ray_graph_t* g, ray_op_t* op, ray_t* tbl);
typedef enum {
AGG_ROUTE_NONE,
AGG_ROUTE_LEGACY,
AGG_ROUTE_SLICES,
AGG_ROUTE_PARTED,
AGG_ROUTE_V2_SERIAL_DENSE,
AGG_ROUTE_V2_SERIAL_HASH,
AGG_ROUTE_V2_DENSE,
AGG_ROUTE_V2_RADIX,
AGG_ROUTE_V2_HASH,
AGG_ROUTE_V2_SMALLHASH,
AGG_ROUTE_V2_INDEXED,
AGG_ROUTE_COUNT,
} agg_route_t;
typedef enum {
AGG_DENSE_NONE,
AGG_DENSE_TASK_LOCAL,
AGG_DENSE_PARTITIONED,
AGG_DENSE_SHARED,
} agg_dense_strategy_t;
typedef struct {
uint64_t routes[AGG_ROUTE_COUNT];
agg_v2_reason_t last_v2_reason;
bool nullable_key;
bool dense_plan_available;
bool dense_worker_budget;
agg_dense_strategy_t dense_strategy;
uint64_t dense_local_slots;
uint32_t dense_tasks;
uint64_t key_domain_evals;
bool topn_native;
int64_t topn_kept;
} agg_route_stats_t;
void agg_route_reset(void);
void agg_route_note_key_domain(void);
agg_route_stats_t agg_route_stats(void);
void agg_route_record(agg_route_t route);
void agg_route_reason(agg_v2_reason_t reason);
bool agg_v2_can_handle(ray_graph_t* g, ray_op_t* op, ray_t* tbl);
int64_t agg_topn_keep(const double* vals, int64_t n,
const ray_group_emit_filter_t* ef, uint8_t* keep);
bool agg_topn_threshold(const double* vals, int64_t n,
const ray_group_emit_filter_t* ef, double* thr);
int64_t agg_topn_mark(const double* vals, int64_t n, const ray_group_emit_filter_t* ef,
bool have_thr, double thr, uint8_t* keep);
bool agg_group_values_f64(const agg_vtable_t* vt, const char* states,
size_t stride, size_t off, const int64_t* slots,
int64_t n, int64_t param, double* out);
ray_t* agg_emit_filter_trim(ray_t* result, uint32_t n_keys, uint32_t n_aggs,
const uint16_t* agg_ops, const ray_group_emit_filter_t* ef);
ray_t* exec_group_v2(ray_graph_t* g, ray_op_t* op, ray_t* tbl,
int64_t group_limit);
typedef struct {
uint32_t* gids;
int64_t* first_row;
int64_t ngroups;
} agg_groups_t;
int agg_group_keys(ray_t** key_cols, uint32_t n_keys, int64_t nrows, agg_groups_t* out);
ray_t* agg_count_distinct_indexed(ray_t* src, const int64_t* rows,
const int64_t* offsets, const int64_t* counts, int64_t groups);
ray_t* agg_group_indices(ray_t* source);
void agg_groups_free(agg_groups_t* out);
ray_t* agg_select_distinct(ray_t* tbl, ray_t** key_cols, const int64_t* key_syms,
uint32_t nk, int64_t nrows,
const int64_t* keep_syms, int keep_n);
ray_t* agg_run_one(const agg_vtable_t* vt, ray_t* val_col,
const uint32_t* gids, int64_t nrows, int64_t ngroups,
int64_t kparam);
ray_t* agg_run_one_bin(const agg_vtable_t* vt, ray_t* x_col, ray_t* y_col,
const uint32_t* gids, int64_t nrows, int64_t ngroups,
int64_t kparam);
typedef struct {
bool ok;
uint32_t n_keys;
bool nullable[16];
int64_t nulls[16];
int64_t mins[16];
int64_t ranges[16];
int64_t strides[16];
int64_t total_slots;
int32_t* remap[16];
int64_t* inverse[16];
bool compacted;
} dense_plan_t;
void agg_dense_plan_free(dense_plan_t* dp);
bool agg_dense_plan(ray_t** key_cols, uint32_t n_keys,
const agg_vtable_t** vts, uint32_t n_aggs,
int64_t nrows, dense_plan_t* out);
int64_t agg_result_col_name(int64_t in_sym, uint16_t agg_op);
#endif