#ifndef RAY_LFTJ_H
#define RAY_LFTJ_H
#include "ops.h"
#include "store/csr.h"
typedef struct ray_lftj_iter {
int64_t* targets;
int64_t start;
int64_t end;
int64_t pos;
} ray_lftj_iter_t;
static inline int64_t lftj_key(ray_lftj_iter_t* it) {
if (!it->targets || it->pos >= it->end) return INT64_MAX;
return it->targets[it->pos];
}
static inline bool lftj_at_end(ray_lftj_iter_t* it) {
return !it->targets || it->pos >= it->end;
}
static inline void lftj_next(ray_lftj_iter_t* it) {
if (it->pos < it->end) it->pos++;
}
static inline void lftj_seek(ray_lftj_iter_t* it, int64_t v) {
if (!it->targets) { it->pos = it->end; return; }
int64_t lo = it->pos, hi = it->end;
while (lo < hi) {
int64_t mid = lo + (hi - lo) / 2;
if (it->targets[mid] < v) lo = mid + 1;
else hi = mid;
}
it->pos = lo;
}
static inline void lftj_open(ray_lftj_iter_t* it, ray_csr_t* csr, int64_t parent) {
if (!csr || !csr->offsets || !csr->targets
|| parent < 0 || parent >= csr->n_nodes) {
it->targets = NULL; it->start = 0; it->end = 0; it->pos = 0;
return;
}
int64_t* o = (int64_t*)ray_data(csr->offsets);
it->targets = (int64_t*)ray_data(csr->targets);
it->start = o[parent];
it->end = o[parent + 1];
it->pos = it->start;
}
bool leapfrog_search(ray_lftj_iter_t** iters, int k, int64_t* out);
#define LFTJ_MAX_VARS 16
#define LFTJ_MAX_ITERS_PER_VAR 8
typedef struct lftj_binding {
ray_csr_t* csr;
uint8_t bound_var;
} lftj_binding_t;
typedef struct lftj_var_plan {
lftj_binding_t bindings[LFTJ_MAX_ITERS_PER_VAR];
uint8_t n_bindings;
} lftj_var_plan_t;
typedef struct lftj_enum_ctx {
lftj_var_plan_t var_plans[LFTJ_MAX_VARS];
uint8_t n_vars;
int64_t bound[LFTJ_MAX_VARS];
int64_t** col_data;
int64_t out_count;
int64_t out_cap;
ray_t* buf_hdrs[LFTJ_MAX_VARS];
bool oom;
} lftj_enum_ctx_t;
bool lftj_build_plan(lftj_enum_ctx_t* ctx,
ray_rel_t** rels, uint8_t n_rels, uint8_t n_vars,
const uint8_t* rel_src_var, const uint8_t* rel_dst_var);
bool lftj_build_default_plan(lftj_enum_ctx_t* ctx,
ray_rel_t** rels, uint8_t n_rels, uint8_t n_vars);
void lftj_enumerate(lftj_enum_ctx_t* ctx, uint8_t depth);
#endif