factcircuit
FactCircuit: an auditable claim-and-evidence verification loop with immutable provenance, staged checks, bounded retrieval, and reproducible evaluation.
Pure C zero-dependency embeddable engine where columnar analytics and graph operations share a single operation DAG, pass through a multi-pass optimizer, and execute as fused morsel-driven bytecode.
Translation pending
DataC · HTMLGitHub @RayforceDBOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
A SIMD-accelerated columnar database for analytics, written in pure C with zero dependencies.
AI translation
SIMD-accelerated columnar database for analytics — pure C, zero dependencies
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Columnar analytics and graph traversal in one fused pipeline.
Rayforce is a pure C zero-dependency embeddable engine where columnar
analytics and graph traversals share a single operation DAG, pass through a
multi-pass optimizer, and execute as morsel-driven bytecode compiled at
execution time. No malloc.
Debian / Ubuntu (.deb, x86-64) — grab the .deb from the
latest release:
Prebuilt tarball (Linux x86-64 / macOS arm64) is also attached to each
release. Or build from source below — zero dependencies, just
make.Read the full README ↗Rayforce is a pure C zero-dependency embeddable engine where columnar analytics and graph traversals share a single operation DAG, pass through a multi-pass optimizer, and execute as morsel-driven bytecode compiled at execution time. No malloc.
Homebrew (macOS & Linux):
brew install rayforcedb/tap/rayforce
Debian / Ubuntu (.deb, x86-64) — grab the .deb from the
latest release:
curl -LO https://github.com/RayforceDB/rayforce/releases/download/vX.Y.Z/rayforce_X.Y.Z_amd64.deb
sudo dpkg -i rayforce_X.Y.Z_amd64.deb
Prebuilt tarball (Linux x86-64 / macOS arm64) is also attached to each
release. Or build from source below — zero dependencies, just
make.
make # debug build (ASan + UBSan)
make release # optimized build
make test # run full test suite
./rayforce # start the Rayfall REPL
make compiles with clang when CC is not set; make CC=gcc (or CC=gcc
in the environment) builds with gcc.
Rayforce ships with Rayfall — a Lisp-like query language with a rich set
of builtins. The REPL prompt is ‣:
‣ (set t (table [Symbol Side Qty]
(list [AAPL GOOG MSFT AAPL GOOG]
[Buy Sell Buy Sell Buy]
[100 200 150 300 250])))
‣ (select {from:t by: Symbol Qty: (sum Qty)})
+--------+----------------------------+
| Symbol | Qty |
| SYM | I64 |
+--------+----------------------------+
| AAPL | 400 |
| GOOG | 450 |
| MSFT | 150 |
+-------------------------------------+
| 3 rows (3 shown) 2 columns (2 shown)|
+-------------------------------------+
‣ (pivot t 'Symbol 'Side 'Qty sum)
+--------+-----+----------------------+
| Symbol | Buy | Sell |
| SYM | I64 | I64 |
+--------+-----+----------------------+
| AAPL | 100 | 300 |
| GOOG | 250 | 200 |
| MSFT | 150 | 0Nl |
+-------------------------------------+
| 3 rows (3 shown) 3 columns (3 shown)|
+-------------------------------------+
Headers: include/rayforce.h (types, memory, atoms,
vectors, tables, symbols), src/ops/ops.h (DAG construction, opcodes,
optimizer, executor, graph algorithms), src/mem/heap.h (allocator lifecycle).
#include <rayforce.h>
#include "mem/heap.h"
#include "ops/ops.h"
int main(void) {
ray_heap_init();
ray_sym_init();
/* Build a table */
int64_t regions[] = {0, 0, 1, 1, 2, 2};
int64_t amounts[] = {100, 200, 150, 300, 175, 225};
ray_t* reg = ray_vec_from_raw(RAY_I64, regions, 6);
ray_t* amt = ray_vec_from_raw(RAY_I64, amounts, 6);
ray_t* tbl = ray_table_new(2);
tbl = ray_table_add_col(tbl, ray_sym_intern("region", 6), reg);
tbl = ray_table_add_col(tbl, ray_sym_intern("amount", 6), amt);
ray_release(reg); ray_release(amt);
/* Group by region, sum amounts */
ray_graph_t* g = ray_graph_new(tbl);
ray_op_t* keys[] = { ray_scan(g, "region") };
uint16_t agg_ops[] = { OP_SUM };
ray_op_t* agg_ins[] = { ray_scan(g, "amount") };
ray_op_t* grp = ray_group(g, keys, 1, agg_ops, agg_ins, 1);
ray_t* result = ray_execute(g, grp);
if (result && !RAY_IS_ERR(result)) ray_release(result);
ray_graph_free(g);
ray_release(tbl);
ray_sym_destroy();
ray_heap_destroy();
}
make lib builds the engine as a static library, librayforce.a, with no
dependencies beyond libc, libm and pthreads. The build compiles library
objects with -ffunction-sections -fdata-sections (the Makefile's
LIB_CFLAGS flavour, applied automatically to the .lib.o objects that go
into the archive), so no extra flags are needed at this step.
To discard everything your code never reaches, pass -Wl,--gc-sections to
the linker on the final link, and -s to strip the result. A DAG-route
client, meaning one that builds and executes query plans through the
ray_graph_*, ray_scan and ray_execute C API and never calls
ray_eval_str or loads .rfl files, never touches the Rayfall parser,
compiler, REPL or IPC server, and section GC drops that whole surface
(mixing the two routes pulls the parser back in):
make clean && make lib
cc -O2 -Iinclude -Isrc examples/analytics.c librayforce.a \
-lm -lpthread -Wl,--gc-sections -s -o analytics
The command above is the Linux one. On macOS, use -Wl,-dead_strip in
place of -Wl,--gc-sections (the Makefile's platform block does the same
for its own release links). On MinGW, link the winsock libraries as well:
-lws2_32 -lmswsock -lkernel32 -ladvapi32, with the same section-GC flag
the toolchain accepts.
A checkout at the current commit links analytics.c to a 3.47 MB
stripped binary, from a 10.22 MB archive; sizes move with the tree, so
this is just one measurement, not a bound.
Memory follows consumed-argument conventions documented per function in
the headers: arguments marked consumes are released by the call, and
returns marked borrowed stay owned by the container. On error paths the
library releases the references it holds. Values are COW, managed with
ray_retain/ray_release; error objects are owned and freed with
ray_error_free.
Build — Construct a lazy DAG: scans, filters, joins, aggregations, window functions, graph traversals. Nothing executes yet.
Optimize — Multi-pass rewriting: type inference → constant folding → idiom rewrite → SIP → factorize → predicate pushdown → filter reorder → projection pushdown → partition pruning → DCE.
Execute — Element-wise subtrees are compiled to flat bytecode at execution time and evaluated over 1024-element morsels that stay L1-resident, with no intermediate heap allocation. Radix-partitioned hash joins size partitions to fit L2. Thread pool dispatches morsels in parallel.
Execution engine
ray_executeGraph engine
Rayfall language
select/update/pivot bridge to the DAG optimizer at runtimeMemory
ray_alloc/ray_free for everythingVector search
cos-dist / l2-dist / inner-prod / norm / knn
and the HNSW lifecycle hnsw-build / ann / hnsw-save / hnsw-load /
hnsw-free / hnsw-infoselect ... where ... nearest (ann handle query) take kwhere predicate is pushed into HNSW's
beam loop so rejected candidates don't consume result slotsStorage
include/rayforce.h Single public header
src/mem/ Buddy allocator, slab cache, arena, COW
src/core/ Type system, platform abstraction, runtime
src/vec/ Vector, list, string, selection bitmap ops
src/table/ Table, symbol intern table
src/store/ Column files, CSR, splayed/parted tables, HNSW
src/ops/ DAG, optimizer, fused executor, LFTJ
src/io/ CSV reader/writer (parallel mmap)
src/lang/ Rayfall parser, evaluator, bytecode VM
src/app/ REPL, terminal, pretty-printer
test/ Test suites
examples/rfl/ Rayfall example scripts
examples/ C API examples
website/ Documentation site (GitHub Pages)
Full docs: rayforcedb.github.io/rayforce
Rayforce has Python bindings at rayforce-py — contributions welcome.
Contributions are welcome. You can help by:
Rayforce is jointly developed with and sponsored by Lynx.
This partnership has been instrumental in making Rayforce a mature, production-ready engine. Lynx's active involvement in development and their commitment to innovative open-source technologies in the financial sector has enabled Rayforce to reach its full potential.