|
Relational NT
A relational database kernel shaped around NT-style object management.
|
C-callable surface over the RNT manager pipeline for OCaml ctypes. More...
Go to the source code of this file.
Classes | |
| struct | PlanArgsScan |
| SCAN context: reads all tuples from a stored relation. More... | |
| struct | PlanArgsJoin |
| JOIN context: nested-loop join of two child plans. More... | |
| struct | PlanArgsTake |
TAKE context: passes at most limit tuples from source, then stops. More... | |
| struct | PlanArgsProject |
PROJECT context: keeps only the named attributes of source. More... | |
| struct | PlanArgsMaterialize |
MATERIALIZE context: caches source on its first scan, then replays the cache on later scans without touching source again. More... | |
| struct | PlanArgsRename |
RENAME context: returns source, with the keys of pairs the values of it. More... | |
| struct | PlanArgsUnion |
| UNION context. More... | |
| struct | PlanAction |
| A single plan-construction request. More... | |
Typedefs | |
| typedef void * | rnt_handle_t |
| Opaque handle to a registry object opened through HandlerManager. | |
| typedef void * | rnt_cursor_t |
| Opaque cursor over a relation, driven by the VM or used directly. | |
| typedef void * | rnt_tuple_sink_t |
| Opaque sink passed to a generator callback. | |
| typedef int(* | rnt_generator_fn) (void *ctx, const char *args, size_t offset, size_t limit, rnt_tuple_sink_t sink) |
| Tuple-producing callback backing an ephemeral relation. | |
| typedef void * | rnt_plan_t |
| Opaque plan node tree, built via rnt_plan_assemble calls. | |
Functions | |
| NT_API int | rnt_init (const char *driver, const char *storage_path) |
| Initializes the RNT runtime with the selected storage backend. | |
| NT_API int | rnt_firewall (const char *auth_method, char **claims_out) |
| Runs PermissionsManager::Firewall for a connection. | |
| NT_API int | rnt_session_open (void *connection_context, char **session_hash_out) |
| Opens a session and registers it at /system/sessions/<hash>. | |
| NT_API int | rnt_session_close (const char *session_hash) |
| Closes a session, unregistering it from /system/sessions/<hash>. | |
| NT_API int | rnt_session_set_branch (const char *session_hash, const char *branch_name, const char *target_hash) |
| Sets a per-session override for a branch. | |
| NT_API int | rnt_sink_emit (rnt_tuple_sink_t sink, const char *tuple_kv) |
| Emits one tuple from inside a generator callback. | |
| NT_API int | rnt_register_ephemeral_relation (const char *session_hash, int named, const char *name, rnt_generator_fn generator, void *generator_ctx, int cardinality, const char *generator_identity, const char *schema_kv, const char *dependencies, char **path_out) |
| Registers an ephemeral relation owned by a session. | |
| NT_API int | rnt_drop_ephemeral_relation (const char *session_hash, const char *name) |
| Drops a named ephemeral relation, releasing its session-ownership pin. | |
| NT_API rnt_handle_t | rnt_open_handle (const char *path, const char *claims) |
| Opens a handle to the object at the given slash-separated path. | |
| NT_API int | rnt_close_handle (rnt_handle_t handle) |
| Closes a handle, running HandlerManager::Close and Unmonitor. | |
| NT_API int | rnt_branch_target (rnt_handle_t handle, char **target_hash_out) |
| Reads the current branch-tree root hash from a BRANCH object. | |
| NT_API int | rnt_branch_advance (const char *branch_path, const char *new_hash) |
| Atomically advances a branch to point at a new branch-tree root. | |
| NT_API int | rnt_register_relation (const char *path) |
| Registers a RELATION object at the given path. | |
| NT_API int | rnt_register_branch (const char *path, const char *target_hash) |
| Registers a BRANCH object at the given path pointing at a branch-tree root. | |
| NT_API int | rnt_list_relations (const char *branch_mg_path, char **out) |
| Lists all relations of a specific multigroup under a branch. | |
| NT_API int | rnt_list_branch_multigroups (const char *branch_path, char **out) |
| Lists all multigroups bound to a branch. | |
| NT_API int | rnt_list_snapshot_relations (const char *snapshot_hash, char **out) |
| Lists all relations stored in a specific snapshot. | |
| NT_API int | rnt_link_tuple (const char *relation_path, const char *kv_attrs, char **hash_out) |
| Stores a tuple and links it to the relation at the given path. | |
| NT_API int | rnt_unlink_tuple (const char *relation_path, const char *tuple_hash) |
| Removes a tuple from the relation's Merkle tree and tuple store. | |
| NT_API int | rnt_clear_relation (const char *relation_path) |
| Resets a relation's Merkle root to the empty-tree state. | |
| NT_API int | rnt_relation_root (const char *relation_path, char **root_hash_out) |
| Returns the current Merkle root hash for a relation. | |
| NT_API rnt_cursor_t | rnt_cursor_open (rnt_handle_t handle) |
| Opens a cursor on the relation referenced by handle. | |
| NT_API int | rnt_cursor_next (rnt_cursor_t cursor, char **tuple_out) |
| Advances the cursor and returns the next tuple as a kv string. | |
| NT_API int | rnt_cursor_close (rnt_cursor_t cursor) |
| Closes a cursor and releases its resources. | |
| NT_API rnt_plan_t | rnt_plan_assemble (PlanAction action) |
Builds one plan node from action and returns the resulting subtree. | |
| NT_API void | rnt_plan_free (rnt_plan_t plan) |
| Releases a plan that was built but not yet executed. | |
| NT_API rnt_cursor_t | rnt_vm_execute_plan (rnt_plan_t plan) |
| Executes a plan tree and returns a streaming VM cursor. | |
| NT_API int | rnt_vm_cursor_next (rnt_cursor_t vm_cursor, char **tuple_out) |
| Advances a VM cursor and returns the next merged tuple as a kv string. | |
| NT_API int | rnt_vm_cursor_close (rnt_cursor_t vm_cursor) |
| Closes a VM cursor, releases all plan nodes, cursors, and handles. | |
| NT_API void | rnt_free_string (char *s) |
| Releases a string allocated by the API. | |
| NT_API void | rnt_free_bytes (uint8_t *p) |
| Releases a byte buffer allocated by the API. | |
C-callable surface over the RNT manager pipeline for OCaml ctypes.
All types are opaque void pointers on the C side; the implementation casts them to the appropriate C++ types internally. Callers must never dereference handle or cursor pointers directly.
This API is not thread-safe. The global runtime (g_rt) is a single in-process instance; all callers share the same ObjectManager and storage backend. The expected usage model is a single OCaml thread (or domain) driving the API at a time. If concurrent access is needed in the future, a per-object or per-relation mutex strategy should be introduced.
| typedef int(* rnt_generator_fn) (void *ctx, const char *args, size_t offset, size_t limit, rnt_tuple_sink_t sink) |
Tuple-producing callback backing an ephemeral relation.
Invoked by the cursor layer each time a page of tuples is needed. The callback must emit at most limit tuples starting at logical position offset by calling rnt_sink_emit once per tuple. Calls may re-enter the RNT API (e.g. to execute a VM plan over base relations); the runtime is single-threaded, so no locking is required.
| ctx | Opaque context pointer given at registration time. |
| args | Bound argument values written by a JOIN before probing, newline-separated. Empty string when scanned standalone. |
| offset | Zero-based logical tuple offset (for pagination). |
| limit | Maximum number of tuples to emit. |
| sink | Pass to rnt_sink_emit for each produced tuple. |
| typedef void* rnt_tuple_sink_t |
Opaque sink passed to a generator callback.
The callback pushes each tuple it produces through rnt_sink_emit; the runtime copies the tuple out immediately, so the string only needs to stay valid for the duration of the rnt_sink_emit call.
| NT_API int rnt_branch_advance | ( | const char * | branch_path, |
| const char * | new_hash ) |
Atomically advances a branch to point at a new branch-tree root.
The new hash must already exist as a content-addressed blob in the KV store — branch-tree roots are produced by mutating calls (rnt_link_tuple, rnt_register_relation, …) and cannot be invented externally. Pass an empty string to reset the branch to unborn.
Write exclusion is structural: BRANCH objects carry exclusive=true in their object_type, so LifecycleManager::Contention prevents a second handle from being opened while a writer holds the branch. AUTH_CLAIM::WRITE is not checked at the C API boundary.
| branch_path | Slash-separated branch path, e.g. "/system/branches/main". |
| new_hash | Branch-tree root to advance to (64-char lowercase hex), or "" to reset to unborn. |
new_hash is non-empty but no matching blob exists in the KV store. | NT_API int rnt_branch_target | ( | rnt_handle_t | handle, |
| char ** | target_hash_out ) |
Reads the current branch-tree root hash from a BRANCH object.
Only valid for handles opened on BRANCH objects. The returned string is the merkle_root of the BRANCH_TREE this branch currently points at — a Merkle<std::string> root mapping mg_name → mg_hash. An empty string indicates an unborn branch with no commits yet.
| handle | Handle to a BRANCH object. |
| target_hash_out | Set to a heap-allocated copy of the target hash (possibly empty). Release with rnt_free_string(). |
| NT_API int rnt_clear_relation | ( | const char * | relation_path | ) |
Resets a relation's Merkle root to the empty-tree state.
Sets ObjectManager::Relation::merkle_root to the empty string. Existing tuple bytes remain in the KV store. After this call the relation contains no tuples from the perspective of cursor iteration.
| relation_path | Slash-separated relation path. |
| NT_API int rnt_close_handle | ( | rnt_handle_t | handle | ) |
Closes a handle, running HandlerManager::Close and Unmonitor.
| NT_API int rnt_cursor_close | ( | rnt_cursor_t | cursor | ) |
Closes a cursor and releases its resources.
| NT_API int rnt_cursor_next | ( | rnt_cursor_t | cursor, |
| char ** | tuple_out ) |
Advances the cursor and returns the next tuple as a kv string.
The tuple is encoded as a newline-delimited "key=value" string matching the format accepted by rnt_link_tuple: "name=Blathers\nprofession=Museum Curator\n"
| cursor | Open cursor. |
| tuple_out | Set to a heap-allocated kv string, or NULL when exhausted. Release with rnt_free_string() when non-NULL. |
| NT_API rnt_cursor_t rnt_cursor_open | ( | rnt_handle_t | handle | ) |
Opens a cursor on the relation referenced by handle.
The returned cursor is positioned before the first tuple. Advance it with rnt_cursor_next(). The cursor must be closed with rnt_cursor_close() before closing the handle.
| handle | Open RELATION handle. |
| NT_API int rnt_drop_ephemeral_relation | ( | const char * | session_hash, |
| const char * | name ) |
Drops a named ephemeral relation, releasing its session-ownership pin.
The entry is collected as soon as no cursor or dependent ephemeral still holds it, cascading the pins it took on its base relations. Scratch entries cannot be dropped by name; they die with their consuming cursor.
| session_hash | Owning session's hash. |
| name | Leaf name given at registration. |
| NT_API int rnt_firewall | ( | const char * | auth_method, |
| char ** | claims_out ) |
Runs PermissionsManager::Firewall for a connection.
| auth_method | "plain_text" or "certificate". |
| claims_out | Set to a heap-allocated, newline-separated claim string. Release with rnt_free_string(). NULL on error. |
| NT_API void rnt_free_bytes | ( | uint8_t * | p | ) |
Releases a byte buffer allocated by the API.
Safe to call with NULL.
| NT_API void rnt_free_string | ( | char * | s | ) |
Releases a string allocated by the API.
Safe to call with NULL.
| NT_API int rnt_init | ( | const char * | driver, |
| const char * | storage_path ) |
Initializes the RNT runtime with the selected storage backend.
Must be called before any other API function. Once the runtime is successfully initialized, subsequent calls are no-ops and return 0. If initialization fails (returns negative), the call may be retried with corrected parameters — the runtime is left in a clean state.
| driver | Storage driver to use: "sqlite" or "memory". "sqlite" persists data to storage_path. "memory" keeps all data in process memory (ignores storage_path); intended for tests. |
| storage_path | File path for the SQLite database, or ":memory:" for an ephemeral SQLite store. Ignored when driver is "memory". |
| NT_API int rnt_link_tuple | ( | const char * | relation_path, |
| const char * | kv_attrs, | ||
| char ** | hash_out ) |
Stores a tuple and links it to the relation at the given path.
Tuples are encoded as a flat key=value string, one attribute per line: "name=Blathers\nprofession=Museum Curator\n" Attributes are sorted by name before hashing to ensure content-addressing is order-independent.
| relation_path | Slash-separated relation path. |
| kv_attrs | Newline-delimited "key=value" attribute string. |
| hash_out | Set to the 64-character hex SHA-256 hash of the tuple. Release with rnt_free_string(). NULL on error. |
| NT_API int rnt_list_branch_multigroups | ( | const char * | branch_path, |
| char ** | out ) |
Lists all multigroups bound to a branch.
Reads the branch-tree root from /system/branches/<name> and pages each (mg_name, mg_hash) entry. Returns "name\thash\n" lines. Unborn branches yield an empty string.
| branch_path | Slash-separated branch path, e.g. "/system/branches/main". |
| out | Heap-allocated string; release with rnt_free_string(). |
| NT_API int rnt_list_relations | ( | const char * | branch_mg_path, |
| char ** | out ) |
Lists all relations of a specific multigroup under a branch.
Returns a newline-delimited string of "name\troot_hash" pairs, one per relation in the named multigroup at the branch's current tree. An unborn branch or an mg absent from the branch tree yields an empty string. The caller must release the string with rnt_free_string().
| branch_mg_path | Slash-separated path of the form "/system/branches/<name>/multigroups/<mg>". |
| out | Set to a heap-allocated "name\troot\n" string. Release with rnt_free_string(). NULL on error. |
| NT_API int rnt_list_snapshot_relations | ( | const char * | snapshot_hash, |
| char ** | out ) |
Lists all relations stored in a specific snapshot.
Reads the multigroup codec directly from the snapshot at /system/snapshots/<snapshot_hash> without following any branch HEAD. Use this when the desired snapshot hash is already known (e.g. detached checkout). Returns the same "name\troot_hash\n" format as rnt_list_relations.
| snapshot_hash | 64-char hex hash of the snapshot. |
| out | Set to heap-allocated string. Release with rnt_free_string(). |
| NT_API rnt_handle_t rnt_open_handle | ( | const char * | path, |
| const char * | claims ) |
Opens a handle to the object at the given slash-separated path.
Runs the full HandlerManager::Open pipeline: ObjectManager::Find → PermissionsManager::Access → IdentityManager::CanOpen → LifecycleManager::Contention → LifecycleManager::Monitor.
| path | Slash-separated logical path, e.g. "/system/branches/main". |
| claims | Claim string returned by rnt_firewall (may be NULL). |
| NT_API rnt_plan_t rnt_plan_assemble | ( | PlanAction | action | ) |
Builds one plan node from action and returns the resulting subtree.
Sole entry point for plan construction. Validates runtime state once, then dispatches on action.op. Child plans for JOIN/TAKE/PROJECT are themselves results of prior rnt_plan_assemble calls; ownership transfers per the per-operator rules documented on each PlanArgs* struct.
| NT_API void rnt_plan_free | ( | rnt_plan_t | plan | ) |
Releases a plan that was built but not yet executed.
Closes any open cursors and handles owned by the plan tree, then frees all nodes. Safe to call with NULL. Do NOT call after rnt_vm_execute_plan — that function takes ownership.
| NT_API int rnt_register_branch | ( | const char * | path, |
| const char * | target_hash ) |
Registers a BRANCH object at the given path pointing at a branch-tree root.
If a BRANCH already exists at this path, returns 0 without modifying it. When target_hash is non-NULL and non-empty it must already exist as a content-addressed blob in the KV store (produced by an earlier mutation through the same runtime); otherwise the call fails. Pass NULL or "" to register an unborn branch.
| path | Slash-separated path, e.g. "/system/branches/main". |
| target_hash | Branch-tree root this branch points at (may be NULL or "" for unborn). |
| NT_API int rnt_register_ephemeral_relation | ( | const char * | session_hash, |
| int | named, | ||
| const char * | name, | ||
| rnt_generator_fn | generator, | ||
| void * | generator_ctx, | ||
| int | cardinality, | ||
| const char * | generator_identity, | ||
| const char * | schema_kv, | ||
| const char * | dependencies, | ||
| char ** | path_out ) |
Registers an ephemeral relation owned by a session.
An ephemeral relation has no tuple storage of its own: its tuples are produced on demand by generator. The entry lands under the session's namespace — /system/sessions/<hash>/ephemeral/<name> when named is non-zero (a named binding that survives between commands until dropped or session close), or /system/sessions/<hash>/scratch/<composed_root> when zero (an anonymous intermediate collected as soon as its consuming cursor closes). Scan it through the normal pipeline: rnt_open_handle on the registered path, then rnt_cursor_open / rnt_plan_scan.
Registration pins every dependency, so a base relation cannot be collected while this relation is defined atop it; the pins are released when the ephemeral itself is collected. Registration is idempotent for an identical scratch result or a live named binding. See docs/ephemeral-relations.org.
| session_hash | Hash returned by rnt_session_open. |
| named | Non-zero for a named binding, 0 for scratch. |
| name | Leaf name for named bindings; ignored for scratch. |
| generator | Tuple-producing callback. Must stay callable until the entry is collected. |
| generator_ctx | Opaque pointer passed back to generator. |
| cardinality | 0 Finite, 1 ConstrainedFinite, 2 AlephZero, 3 Continuum. |
| generator_identity | Stable operator label for the identity hash, e.g. "join:id", "select:age". |
| schema_kv | Newline-separated "name=type" attribute lines. |
| dependencies | Newline-separated logical paths of the base relations this is defined atop, e.g. "system/snapshots/<h>/relations/<rel>". Every path must resolve or the call fails. |
| path_out | Optional (may be NULL): set to the heap-allocated slash-joined registered path. Release with rnt_free_string(). |
| NT_API int rnt_register_relation | ( | const char * | path | ) |
Registers a RELATION object at the given path.
Idempotent: if an object already exists at the path, the call succeeds without re-registering.
| path | Slash-separated path of the form "/system/branches/<branch>/multigroups/<mg>/relations/<rel>". |
| NT_API int rnt_relation_root | ( | const char * | relation_path, |
| char ** | root_hash_out ) |
Returns the current Merkle root hash for a relation.
OCaml calls this after rnt_link_tuple or rnt_unlink_tuple to read the updated root back and store it in the in-memory multigroup (tree_pointer). An empty string is returned for a relation that contains no tuples.
| relation_path | Slash-separated relation path. |
| root_hash_out | Set to the 64-character hex root hash, or to an empty heap-allocated string for an empty relation. Release with rnt_free_string(). |
| NT_API int rnt_session_close | ( | const char * | session_hash | ) |
Closes a session, unregistering it from /system/sessions/<hash>.
After this call the session hash is invalid; subsequent rnt_session_* or resolver lookups against it will fail. Branch overrides held by the session are dropped.
| session_hash | Hash returned by rnt_session_open. |
| NT_API int rnt_session_open | ( | void * | connection_context, |
| char ** | session_hash_out ) |
Opens a session and registers it at /system/sessions/<hash>.
The runtime mints a random 256-bit hex hash for the session; the caller has no influence over the value. The returned string is the opaque identifier required by every other rnt_session_* call.
| connection_context | Caller-owned pointer carried on the session. The runtime treats it as opaque; ownership of the pointee remains with the caller. |
| session_hash_out | Set to a heap-allocated 64-char hex string. Release with rnt_free_string(). |
| NT_API int rnt_session_set_branch | ( | const char * | session_hash, |
| const char * | branch_name, | ||
| const char * | target_hash ) |
Sets a per-session override for a branch.
While the override is in effect, paths resolved through /system/sessions/<hash>/branches/<branch_name>/... point at /system/snapshots/<target_hash>/... regardless of where the global branch HEAD currently sits. Pass an empty string for target_hash to remove the override and resume falling back to the global branch.
Non-empty target hashes must correspond to an existing /system/snapshots/<target_hash> entry; otherwise the call fails.
| session_hash | Session identifier. |
| branch_name | Branch the override applies to (e.g. "main"). |
| target_hash | Snapshot hash to bind, or "" to clear. |
| NT_API int rnt_sink_emit | ( | rnt_tuple_sink_t | sink, |
| const char * | tuple_kv ) |
Emits one tuple from inside a generator callback.
| sink | Sink received by the callback. |
| tuple_kv | Newline-separated "name=value" attribute lines — the same wire format rnt_link_tuple consumes and rnt_cursor_next returns. Copied before returning. |
| NT_API int rnt_unlink_tuple | ( | const char * | relation_path, |
| const char * | tuple_hash ) |
Removes a tuple from the relation's Merkle tree and tuple store.
Calls Merkle::Remove on the relation's current root and updates ObjectManager::Relation::merkle_root atomically. The tuple bytes remain in the KV store (they may be referenced by older snapshots); only the membership in the current tree is removed.
| relation_path | Slash-separated relation path. |
| tuple_hash | 64-character hex SHA-256 of the tuple to remove. |
| NT_API int rnt_vm_cursor_close | ( | rnt_cursor_t | vm_cursor | ) |
Closes a VM cursor, releases all plan nodes, cursors, and handles.
| NT_API int rnt_vm_cursor_next | ( | rnt_cursor_t | vm_cursor, |
| char ** | tuple_out ) |
Advances a VM cursor and returns the next merged tuple as a kv string.
Same encoding and return-value semantics as rnt_cursor_next.
| vm_cursor | Cursor returned by rnt_vm_execute_plan. |
| tuple_out | Set to a heap-allocated kv string, or NULL when exhausted. Release with rnt_free_string() when non-NULL. |
| NT_API rnt_cursor_t rnt_vm_execute_plan | ( | rnt_plan_t | plan | ) |
Executes a plan tree and returns a streaming VM cursor.
Takes ownership of plan; the caller must not call rnt_plan_free after this. The returned cursor is advanced with rnt_vm_cursor_next() and must be closed with rnt_vm_cursor_close(), which also releases all plan resources.