Skip to content

Commit f344324

Browse files
committed
dead-node graph algo: traditional and reactive
graph distributed across files dead node algorithms: both traditional and reactive
1 parent a39eb8e commit f344324

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+269517
-0
lines changed

.github/workflows/ci.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,14 @@ jobs:
350350
- name: Version Check
351351
run: yarn constraints
352352

353+
- name: Run reactive graph analyses
354+
run: |
355+
opam exec -- make -C reactive_graph traditional
356+
opam exec -- make -C reactive_graph reactive
357+
opam exec -- make -C reactive_graph traditional-run
358+
opam exec -- make -C reactive_graph reactive-run
359+
shell: bash
360+
353361
- name: Run tests
354362
run: node scripts/test.js -all
355363

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ bench: compiler
167167
$(DUNE_BIN_DIR)/syntax_benchmarks
168168

169169
test: lib ninja
170+
$(MAKE) -C reactive_graph traditional-run
171+
$(MAKE) -C reactive_graph reactive-run
170172
node scripts/test.js -all
171173

172174
test-analysis: lib ninja

reactive_graph/Makefile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
SHELL := /bin/sh
2+
3+
.PHONY: traditional traditional-run reactive-runtime reactive reactive-run clean
4+
5+
traditional:
6+
dune build --root . traditional_analysis/bin/traditional_main.exe
7+
8+
traditional-run: traditional
9+
dune exec --root . traditional_analysis/bin/traditional_main.exe -- data
10+
11+
reactive-runtime:
12+
$(MAKE) -C vendor/skip-ocaml build/libskip_reactive.a
13+
14+
reactive: reactive-runtime
15+
dune build --root . reactive_analysis/bin/reactive_main.exe
16+
17+
reactive-run: reactive
18+
dune exec --root . reactive_analysis/bin/reactive_main.exe -- data
19+
20+
clean:
21+
dune clean --root .
22+
$(RM) graph.rheap
23+
$(MAKE) -C vendor/skip-ocaml clean

reactive_graph/README.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# Reactive Graph Reachability
2+
3+
This directory hosts two minimal OCaml implementations for computing the set of
4+
nodes that are unreachable from all marked nodes in a graph assembled from
5+
multiple per-file fragments:
6+
7+
1. `traditional_analysis/` contains a plain OCaml executable plus unit tests that parse
8+
`.graph` files, build the global graph, and print unreachable nodes.
9+
2. `reactive_analysis/` reuses the same parser/graph logic but runs the pipeline through
10+
the Skip reactive runtime (vendored under `reactive_graph/vendor/skip-ocaml`)
11+
so that file
12+
parsing and reachability recompute incrementally.
13+
14+
The implementations share `graph_lib/`, which knows how to parse graph files and
15+
compute reachability.
16+
17+
## Input format
18+
19+
Each `.graph` file can contain `node` and `edge` directives:
20+
21+
```
22+
node <id> [marked]
23+
edge <src> <dst>
24+
```
25+
26+
* Node identifiers are integers and must be unique globally.
27+
* Adding the literal `marked` after a node ID makes it one of the starting
28+
points for reachability.
29+
* Edge sources must be defined in the same file; edge destinations must exist in
30+
some file.
31+
32+
Sample files live under `data/`.
33+
34+
## Traditional build & tests
35+
36+
```
37+
cd /Users/cristianocalcagno/GitHub/rescript
38+
dune runtest --root reactive_graph # runs unit tests
39+
dune exec --root reactive_graph reactive_graph/traditional_analysis/bin/traditional_main.exe -- reactive_graph/data
40+
```
41+
42+
The executable prints either `All nodes are reachable...` or the sorted list of
43+
unreachable nodes.
44+
45+
## Reactive build & usage
46+
47+
`reactive_graph/vendor/skip-ocaml/` vendors the Skip runtime sources copied from
48+
[`skip-ocaml`](https://github.com/skiplang/skip-ocaml) at commit
49+
`0a8ddbf29970869d9396d7e860e3b48bb3df8695`. The snapshot includes only the
50+
pieces required to build `libskip_reactive.a` (runtime C/C++ glue plus the LLVM
51+
module `external/skip.ll`). If you want libbacktrace support, build
52+
`external/libbacktrace.a` for your platform and drop it into the vendor tree
53+
before compiling. Otherwise, build the static library once:
54+
55+
```
56+
cd /Users/cristianocalcagno/GitHub/rescript/reactive_graph/vendor/skip-ocaml
57+
make build/libskip_reactive.a
58+
```
59+
60+
(Re-run the command whenever you clean the vendor build directory.)
61+
62+
1. Build the reactive binary from the ReScript repo:
63+
64+
```
65+
cd /Users/cristianocalcagno/GitHub/rescript
66+
dune build --root reactive_graph reactive_analysis/bin/reactive_main.exe
67+
```
68+
69+
2. Run it by pointing to the directory with `.graph` files. The executable
70+
creates `graph.rheap` by default; pass a custom heap path as the first
71+
argument if you need to override it (macOS users should delete heaps between
72+
runs, but the CLI now removes the default automatically):
73+
74+
```
75+
./_build/default/reactive_analysis/bin/reactive_main.exe reactive_graph/data
76+
```
77+
78+
The first run parses all files and caches the intermediate representations.
79+
Subsequent runs only re-parse and recompute for the files that change.
80+
(Any heap filename works; `graph.rheap` is just a short example.)
81+
After each run the CLI now prints the reactive heap usage using the
82+
`Reactive.heap_usage()` API, so you can see how many bytes of the `.rheap`
83+
file are currently occupied.
84+
85+
### Makefile shortcuts
86+
87+
From `reactive_graph/` you can use the tiny Makefile:
88+
89+
```
90+
make traditional-run # build + run the non-reactive analysis
91+
make reactive-run # build runtime + reactive binary + run
92+
make clean
93+
```
94+
95+
`make reactive-run` builds the vendored runtime automatically (via
96+
`make -C vendor/skip-ocaml ...`) before invoking the executable.
97+
98+
### macOS note
99+
100+
Because ASLR prevents reusing heaps across fresh processes, macOS users must
101+
delete the `.rheap` file before every new invocation of the reactive binary.
102+
The runtime now exits immediately with an explanatory error if it detects an
103+
existing heap file on macOS.
104+
105+
## Directory layout
106+
107+
```
108+
graph_lib/ Shared parser and reachability logic
109+
traditional_analysis/ Non-reactive CLI + tests
110+
reactive_analysis/ Reactive CLI + vendored Skip runtime bindings
111+
data/ Example input fragments
112+
```
113+
114+
Both executables accept a directory path; they enumerate all `*.graph` files
115+
inside that directory and report unreachable nodes in ascending order.

reactive_graph/data/a.graph

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# File A: simple line
2+
node 1 marked
3+
node 2
4+
node 3
5+
edge 1 2
6+
edge 2 3
7+

reactive_graph/data/b.graph

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# File B: fan-out toward another file
2+
node 4
3+
node 5
4+
edge 4 5
5+

reactive_graph/data/c.graph

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# File C: connects into file B
2+
node 6 marked
3+
node 7
4+
edge 6 7
5+
edge 7 4
6+

reactive_graph/data/d.graph

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# File D: unreachable chain
2+
node 8
3+
node 9
4+
edge 8 9
5+

reactive_graph/dune-project

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
(lang dune 3.13)
2+
(name reactive_graph)
3+

reactive_graph/graph_lib/dune

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
(library
2+
(name graph_lib))
3+

0 commit comments

Comments
 (0)