aboutsummaryrefslogtreecommitdiffstats
path: root/lib/nt_ffi.ml
diff options
context:
space:
mode:
authorMarcos Magueta <maguetamarcos@gmail.com>2026-06-22 22:55:27 -0300
committerGitHub <noreply@github.com>2026-06-22 22:55:27 -0300
commitb81586ee4a0543a5f9866586c78dccdd6328934a (patch)
tree4cd2f26e8e57e7e8d852fb7deddd0818c482dc8b /lib/nt_ffi.ml
parent57b55b51ee6a1d4678ba37e4631d61a248411ff2 (diff)
downloadSakura-b81586ee4a0543a5f9866586c78dccdd6328934a.tar.gz
Sakura-b81586ee4a0543a5f9866586c78dccdd6328934a.zip
RNT ephemeral relations representation
Diffstat (limited to '')
-rw-r--r--lib/nt_ffi.ml107
1 files changed, 58 insertions, 49 deletions
diff --git a/lib/nt_ffi.ml b/lib/nt_ffi.ml
index bfbdf65..6759a17 100644
--- a/lib/nt_ffi.ml
+++ b/lib/nt_ffi.ml
@@ -25,6 +25,27 @@ let rnt_session_set_branch =
fn "rnt_session_set_branch"
(string @-> string @-> string @-> returning int)
+(* Ephemeral relations ------------------------------------------------------ *)
+
+(* rnt_generator_fn: (ctx, args, offset, limit, sink) -> int.
+ OCaml closures passed here cross into C; the closure must stay reachable
+ for as long as RNT may invoke it (Nt retains them, see
+ Nt.retained_generators). *)
+let rnt_generator_fn =
+ funptr
+ (ptr void @-> string @-> size_t @-> size_t @-> ptr void @-> returning int)
+
+let rnt_sink_emit =
+ fn "rnt_sink_emit" (ptr void @-> string @-> returning int)
+
+let rnt_register_ephemeral_relation =
+ fn "rnt_register_ephemeral_relation"
+ (string @-> int @-> string @-> rnt_generator_fn @-> ptr void @-> int
+ @-> string @-> string @-> string @-> ptr (ptr char) @-> returning int)
+
+let rnt_drop_ephemeral_relation =
+ fn "rnt_drop_ephemeral_relation" (string @-> string @-> returning int)
+
(* Handle lifecycle -------------------------------------------------------- *)
let rnt_open_handle =
fn "rnt_open_handle" (string @-> ptr void @-> returning (ptr void))
@@ -84,72 +105,53 @@ let rnt_cursor_close =
(* VM plan builder --------------------------------------------------------- *)
-type operation = Scan | Join | Take | Project
-
-let int_of_operation = function
- | Scan -> 1 | Join -> 2 | Take -> 3 | Project -> 4
-
-let operation_of_int = function
- | 1 -> Scan | 2 -> Join | 3 -> Take | 4 -> Project
- | _ -> failwith "Bad operation" (* FIXME *)
-
-let operation = view ~read:operation_of_int ~write:int_of_operation int
+(* For PlanAction in RNT_C_API.h, where one context struct per operator is laid
+ side by side (no unions unfortunately as ctypes has no union support 🤡, and
+ the C side reads only the member matching [operation]). Strings are passed
+ as [ptr char]; the caller owns the backing CArray and must keep it alive across
+ the rnt_plan_assemble call (the C side copies immediately). *)
type plan_args_scan
-let plan_args_scan : plan_args_scan structure typ = structure "plan_args_scan"
-let pas_relation_path = field plan_args_scan "pas_relation_path" string
+let plan_args_scan : plan_args_scan structure typ = structure "PlanArgsScan"
+let scan_relation_path = field plan_args_scan "relation_path" (ptr char)
let () = seal plan_args_scan
type plan_args_join
-let plan_args_join : plan_args_join structure typ = structure "plan_args_join"
-let paj_left = field plan_args_join "paj_left" (ptr void)
-let paj_right = field plan_args_join "paj_right" (ptr void)
+let plan_args_join : plan_args_join structure typ = structure "PlanArgsJoin"
+let join_left = field plan_args_join "left" (ptr void)
+let join_right = field plan_args_join "right" (ptr void)
let () = seal plan_args_join
type plan_args_take
-let plan_args_take : plan_args_take structure typ = structure "plan_args_take"
-let pat_source = field plan_args_take "pat_source" (ptr void)
-let pat_limit = field plan_args_take "pat_limit" size_t
+let plan_args_take : plan_args_take structure typ = structure "PlanArgsTake"
+let take_source = field plan_args_take "source" (ptr void)
+let take_limit = field plan_args_take "limit" size_t
let () = seal plan_args_take
type plan_args_project
-let plan_args_project : plan_args_project structure typ = structure "plan_args_project"
-let pap_source = field plan_args_project "pap_source" (ptr void)
-let pap_attrs = field plan_args_project "pap_attrs" (ptr (ptr char))
+let plan_args_project : plan_args_project structure typ =
+ structure "PlanArgsProject"
+let project_source = field plan_args_project "source" (ptr void)
+let project_attrs = field plan_args_project "attrs" (ptr (ptr char))
let () = seal plan_args_project
type plan_action
-let plan_action : plan_action structure typ = structure "plan_action"
-let pa_operation = field plan_action "pa_operation" operation
-let pa_scan = field plan_action "pa_scan" plan_args_scan
-let pa_join = field plan_action "pa_join" plan_args_join
-let pa_take = field plan_action "pa_take" plan_args_take
-let pa_project = field plan_action "pa_project" plan_args_project
+let plan_action : plan_action structure typ = structure "PlanAction"
+let action_operation = field plan_action "operation" int
+let action_scan = field plan_action "scan" plan_args_scan
+let action_join = field plan_action "join" plan_args_join
+let action_take = field plan_action "take" plan_args_take
+let action_project = field plan_action "project" plan_args_project
let () = seal plan_action
-let rnt_plan_assemble = fn "rnt_plan_assemble" (plan_action @-> returning (ptr void))
-
-let ( &-> ) = getf
+(* nt::Operation values, RNT include/VM.h *)
+let fol_operation_scan = 1
+let fol_operation_join = 2
+let fol_operation_take = 3
+let fol_operation_project = 4
-let rnt_plan_scan str =
- let plan = make plan_action in
- setf plan pa_operation Scan;
- setf (plan &-> pa_scan) pas_relation_path str;
- rnt_plan_assemble plan
-
-let rnt_plan_join left right =
- let plan = make plan_action in
- setf plan pa_operation Join;
- setf (plan &-> pa_join) paj_left left;
- setf (plan &-> pa_join) paj_right right;
- rnt_plan_assemble plan
-
-let rnt_plan_take source limit =
- let plan = make plan_action in
- setf plan pa_operation Take;
- setf (plan &-> pa_take) pat_source source;
- setf (plan &-> pa_take) pat_limit limit;
- rnt_plan_assemble plan
+let rnt_plan_assemble =
+ fn "rnt_plan_assemble" (plan_action @-> returning (ptr void))
let rnt_plan_free =
fn "rnt_plan_free" (ptr void @-> returning void)
@@ -176,6 +178,13 @@ let rnt_free_bytes =
let null_char_ptr : char ptr = from_voidp char null
+let cstring (s : string) : char CArray.t =
+ let n = String.length s in
+ let arr = CArray.make char (n + 1) in
+ String.iteri (CArray.set arr) s;
+ CArray.set arr n '\000';
+ arr
+
(* Reads a null-terminated C string from a char pointer, then frees it. *)
let consume_cstring (p : char ptr) : string =
let n = ref 0 in