Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
666b944
fix(group): bound the tied groups the radix top-N selection keeps
ser-vasilich Sep 19, 2026
bc350dd
feat(lang): add a `while` special form
singaraiona Sep 19, 2026
8168f1e
feat(lang): add `times` and `fold-while`
singaraiona Sep 19, 2026
cf3cbe5
Merge branch 'dev' into feat/while-form
singaraiona Sep 19, 2026
4e122fc
Merge pull request #590 from RayforceDB/feat/while-form
singaraiona Sep 19, 2026
d1d6d55
Merge branch 'dev' into feat/times-fold-while
singaraiona Sep 19, 2026
cd42a1b
Merge pull request #591 from RayforceDB/fix/topn-radix-highcard
singaraiona Sep 19, 2026
1c22f9d
Merge pull request #594 from RayforceDB/feat/times-fold-while
singaraiona Sep 20, 2026
62e4447
perf(join): skip per-cell key null tests on provably null-free columns
singaraiona Sep 20, 2026
e777041
Merge pull request #598 from RayforceDB/perf/join-nullfree-keys-597
singaraiona Sep 20, 2026
06449e6
fix(system): validate launcher and timeit integer arguments
belowzeroff Sep 18, 2026
0137aa4
Merge pull request #601 from belowzeroff/fix/system-arg-validation
singaraiona Sep 20, 2026
525a51d
fix(cli): reject a flag as another flag's value, and unknown options
singaraiona Sep 20, 2026
63d91b1
fix(exec): release the input table of window, sort and limit uncondit…
ser-vasilich Sep 21, 2026
a2fe496
test(lang): pin the refcount of a table across window, sort and limit…
ser-vasilich Sep 21, 2026
2ccebde
fix(exec): the reduction case owns its input too
ser-vasilich Sep 21, 2026
ffd3b22
Merge pull request #604 from RayforceDB/fix/window-input-ref
singaraiona Sep 21, 2026
c555611
Merge pull request #603 from RayforceDB/fix/cli-flag-values-600
singaraiona Sep 21, 2026
a7b9b39
perf(pool): wake only the workers a dispatch can keep busy
singaraiona Sep 21, 2026
d13bde4
Merge pull request #605 from RayforceDB/perf/pool-wake-count
singaraiona Sep 21, 2026
08c5918
build: Windows (MSYS2 CLANG64/MINGW64) toolchain in the Makefile
ser-vasilich Sep 22, 2026
5ee60ea
feat(core): WSAPoll event loop for Windows
ser-vasilich Sep 22, 2026
7cb12af
fix(net): Winsock errno mapping, exclusive bind and IPC on Windows
ser-vasilich Sep 22, 2026
4a392b7
fix: Windows platform layer (file mapping, pools, crash report, paths)
ser-vasilich Sep 22, 2026
9f5bbaf
fix: REPL, profiler and system builtins build and work on Windows
ser-vasilich Sep 22, 2026
0807e1c
test: run the suite on Windows
ser-vasilich Sep 22, 2026
fbf55cf
docs: Windows build instructions and platform status
ser-vasilich Sep 22, 2026
cfdbb34
fix: readable REPL prompt and CPU name in the banner on Windows
ser-vasilich Sep 23, 2026
bb6b5d8
bench: build the micro-benchmarks on Windows, record a Windows/Linux …
ser-vasilich Sep 23, 2026
fb392d9
bench: record the recent perf benches on Windows vs Linux
ser-vasilich Sep 23, 2026
5543006
fix(format): render i64 at full width, not through 32-bit long
ser-vasilich Sep 23, 2026
7d370d4
fix(crash): format the banner with snprintf instead of macro string s…
ser-vasilich Sep 23, 2026
6b4de91
test(regress): drop the 24 GB til from the i64 width probe
ser-vasilich Sep 23, 2026
4eb3b10
Merge pull request #618 from RayforceDB/serhii/windows-port
singaraiona Sep 23, 2026
cf9aa21
fix(mem): hand workers their freed blocks back at the end of every di…
ser-vasilich Sep 24, 2026
a3ba555
fix(serde): reject trailing payload bytes (#622)
belowzeroff Sep 24, 2026
31f45a7
fix(select): a projection sees the projections before it (#620)
ser-vasilich Sep 25, 2026
d896a12
perf(like): one column kernel for the direct builtin and the executor…
ser-vasilich Sep 25, 2026
f35846a
fix(system): report arity errors for extra arguments (#616)
belowzeroff Sep 25, 2026
fb426dc
fix(in): admit the typed kernel for text columns, which it never reac…
singaraiona Sep 25, 2026
db062c1
perf: shared-node memo, STR descriptor views, fused top-k on nullable…
ser-vasilich Sep 26, 2026
d70bc38
v2.9.1 (#625) (#629)
ser-vasilich Sep 26, 2026
01c2a33
chore: merge master back into dev after the v2.9.1 release (#625)
singaraiona Sep 26, 2026
e04b972
docs(release): merge master back into dev after each release
singaraiona Sep 26, 2026
f10a9c6
perf(select): whole-table count/min/max/sum/avg from chunk-zone metadata
ser-vasilich Sep 27, 2026
a2049e7
fix(index): mapped index regions — bounds-checked children, never rel…
ser-vasilich Sep 27, 2026
f5ee037
fix(agg): zone min/max tell all-null from the non-null counts; empty …
ser-vasilich Sep 27, 2026
82a5342
test(store): portable in-place sed in splayed_zone_aggs
ser-vasilich Sep 27, 2026
0076631
fix(system): reject arguments to gc (#615)
belowzeroff Sep 27, 2026
1ae2435
fix(string): a STR view keeps only the bytes it points at (#631)
ser-vasilich Sep 27, 2026
a73fab9
fix(log): reject arguments to purge (#638)
belowzeroff Sep 28, 2026
12502a6
perf(vec): avoid rewriting copied text nulls during concat (#641)
singaraiona Sep 28, 2026
338b9d6
fix(hnsw): reject invalid persisted graph ids (#642)
belowzeroff Sep 29, 2026
69b4558
fix(log): reject arguments to roll (#639)
belowzeroff Sep 29, 2026
85d80ee
perf(expr): 32 registers per fused expression; nulls produced mid-pro…
ser-vasilich Sep 29, 2026
aa51f70
perf(select): filtered positional take stops early; sort by an unproj…
ser-vasilich Sep 29, 2026
fdc1a4c
perf(group): partitioned dense accumulate; derived-key grouping over …
ser-vasilich Sep 29, 2026
41063a0
perf(csv): parallel splayed load, batched symfile interning, parallel…
ser-vasilich Sep 29, 2026
f82dc86
perf(select): fused top-k prunes chunks by zone extrema and visits th…
ser-vasilich Sep 29, 2026
44c6331
Merge pull request #635 from RayforceDB/perf/chunk-meta-aggs
singaraiona Sep 29, 2026
67861ce
fix(collection): hash int cells through f64 when a set meets a float …
singaraiona Sep 29, 2026
a581a77
test(agg): pin the LLC in dense_cache_bound so the route is runner-in…
singaraiona Sep 29, 2026
4a7276d
fix(in): admit the typed kernel unless both sides carry a null (#644)
singaraiona Sep 29, 2026
7b7acdf
fix(agg): integer mean divides the exact 128-bit sum; mapped index ta…
ser-vasilich Sep 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,26 @@ truth for the version** — no version literal is ever hand-edited in source.
- packages `rayforce-X.Y.Z-<os>-<arch>.tar.gz` + a `.sha256` checksum,
- publishes a GitHub Release with a feature-oriented changelog and the
artifacts.
5. **Merge `master` back into `dev`** right after the release PR merges:

```sh
git fetch origin
git switch dev && git pull --ff-only
git merge --no-ff -s ours origin/master \
-m "chore: merge master back into dev after the vX.Y.Z release (#N)"
git diff origin/dev --stat # must print nothing
git push origin dev
```

Merging the release PR leaves a squash or merge commit on `master` that `dev`
doesn't contain. `master` requires branches to be up to date before merging,
so without this step the next release PR is blocked as "out of date with the
base". After a squash, it also shows conflicts that aren't real. Copying the
release commit onto `dev` doesn't help: only a merge makes `master`'s commit
an ancestor of `dev`. `-s ours` is correct because `dev` already contains
everything the release shipped, so the empty `git diff` proves the merge
changed no files. If `master` ever carries a hotfix that isn't on `dev`,
drop `-s ours` and do a normal merge instead.

That's the whole ritual. **Never edit the version in source to make a release** —
the tag is authoritative.
Expand Down
45 changes: 45 additions & 0 deletions bench/concat_text_nulls.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* Focused concat benchmark: build with release library, run before/after. */
#define _POSIX_C_SOURCE 200809L
#include <rayforce.h>
#include "mem/heap.h"
#include "vec/vec.h"
#include <stdio.h>
#include <time.h>

static double now(void) {
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
return t.tv_sec + t.tv_nsec * 1e-9;
}

int main(void) {
ray_heap_init();
const int64_t n = 1000000;
const int reps = 40;
for (int kind = 0; kind < 2; kind++) {
for (int mode = 0; mode < 3; mode++) {
ray_t* a = ray_vec_new(kind ? RAY_SYM : RAY_STR, n);
if (!a || RAY_IS_ERR(a)) return 1;
if (kind) {
a->len = n;
for (int64_t i = 0; i < n; i++) ((int64_t*)ray_data(a))[i] = 1;
} else {
for (int64_t i = 0; i < n; i++) a = ray_str_vec_append(a, "abc", 3);
}
if (mode == 1) ray_vec_set_null(a, 0, true);
if (mode == 2) ray_vec_set_null(a, n - 1, true);
double start = now();
for (int r = 0; r < reps; r++) {
ray_t* out = ray_vec_concat(a, a);
if (!out || RAY_IS_ERR(out) || out->len != 2 * n) return 2;
ray_release(out);
}
printf("%s %s rows=%lld reps=%d ms_per_concat=%.6f\n",
kind ? "SYM64" : "STR-inline", mode == 0 ? "no-null" : mode == 1 ? "first-null" : "last-null",
(long long)n, reps, (now() - start) * 1000 / reps);
ray_release(a);
}
}
ray_heap_destroy();
return 0;
}
2 changes: 1 addition & 1 deletion docs/docs/guides/memory.md
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ This tells you the join needed about 1 GB of temporary memory beyond what was al
| Tool | What It Does | When to Use |
|---|---|---|
| `(.sys.mem 0)` | Returns heap allocation statistics | Monitor memory usage, detect leaks |
| `(.sys.gc 0)` | Flushes caches, releases pages | Between heavy queries, before benchmarks |
| `(.sys.gc)` | Flushes caches, releases pages | Between heavy queries, before benchmarks |
| `(.sys.info 0)` | Shows system and runtime info | Check total RAM, CPU count, OS details |
| `(timeit expr)` | Measures execution time of one expression | Benchmark a specific operation |
| `:timeit` | Toggles profiling for all REPL expressions | Interactive performance exploration |
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/namespaces/log.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ The journal is intentionally minimal: there's no per-entry timestamp or transact
| [`.log.write`](#log-write) | unary | — | Append a serialised expression to the open journal. |
| [`.log.sync`](#log-sync) | variadic | — | `fsync` the journal. |
| [`.log.snapshot`](#log-snapshot) | variadic | restricted | Write a snapshot of current state and roll to a fresh segment. |
| [`.log.roll`](#log-roll) | variadic | restricted | Close the active segment and start a new one. |
| [`.log.roll`](#log-roll) | nullary | restricted | Close the active segment and start a new one. |
| [`.log.replay`](#log-replay) | unary | restricted | Replay a journal file; return entry count. |
| [`.log.validate`](#log-validate) | unary | — | Scan a journal file; return `(chunks valid_bytes)`. |
| [`.log.close`](#log-close) | variadic | restricted | Flush and close the active journal. |
| [`.log.purge`](#log-purge) | variadic | restricted | Close the active journal and delete all its files. |
| [`.log.purge`](#log-purge) | nullary | restricted | Close the active journal and delete all its files. |

## `.log.open` { #log-open }

Expand Down
24 changes: 21 additions & 3 deletions src/core/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ static uint64_t cache_sysfs_llc_bytes(void) {
}
#endif

uint64_t ray_cache_llc_bytes(void) {
static uint64_t cache_llc_probe(void) {
static uint64_t cached = UINT64_MAX;
if (cached != UINT64_MAX) return cached;
uint64_t bytes = 0;
Expand Down Expand Up @@ -642,7 +642,7 @@ uint32_t ray_physical_core_count(void) {
/* Sum of every level-3 cache instance reported by the processor topology
* (each SYSTEM_LOGICAL_PROCESSOR_INFORMATION cache record is one instance).
* 0 when the query fails. */
uint64_t ray_cache_llc_bytes(void) {
static uint64_t cache_llc_probe(void) {
static uint64_t cached = UINT64_MAX;
if (cached != UINT64_MAX) return cached;
uint64_t bytes = 0;
Expand Down Expand Up @@ -800,7 +800,7 @@ ray_err_t ray_thread_join(ray_thread_t t) {
}

uint32_t ray_thread_count(void) { return 1; }
uint64_t ray_cache_llc_bytes(void) { return 0; }
static uint64_t cache_llc_probe(void) { return 0; }

/* Semaphore — counter-only. Single-threaded so wait never blocks (the
* counter must already be positive when wait fires). */
Expand All @@ -818,3 +818,21 @@ void ray_sem_wait(ray_sem_t* s) {
void ray_sem_signal(ray_sem_t* s) { (*s)++; }

#endif /* RAY_OS_WASM */

#ifdef DEBUG
/* Test pin for the probed LLC size: routing that bounds replicated state by
* the cache (group dense slabs) otherwise picks a different strategy on
* every CI runner. 0 restores the platform probe. */
static uint64_t g_llc_for_test = 0;

void ray_cache_llc_set_for_test(uint64_t bytes) {
g_llc_for_test = bytes;
}
#endif

uint64_t ray_cache_llc_bytes(void) {
#ifdef DEBUG
if (g_llc_for_test) return g_llc_for_test;
#endif
return cache_llc_probe();
}
4 changes: 4 additions & 0 deletions src/core/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ uint32_t ray_physical_core_count(void);
* 0 when the platform cannot report it. Bounds replicated per-task state
* whose random-access working set must stay cache-resident to scale. */
uint64_t ray_cache_llc_bytes(void);
#ifdef DEBUG
/* Pin ray_cache_llc_bytes to `bytes` (0 = probe again). */
void ray_cache_llc_set_for_test(uint64_t bytes);
#endif

void ray_parallel_begin(void);
void ray_parallel_end(void);
Expand Down
Loading
Loading