Skip to content

Commit d4092ed

Browse files
committed
Reactive: add refined stats tracking, remove V1, rename ReactiveV2 to Reactive
- Add adds_received/removes_received to track input churn - Add adds_emitted/removes_emitted to track output changes - Add process_count (runs) to track how many times each node processes - Delete unused V1 API (Reactive.ml/mli) - Rename ReactiveV2 to Reactive throughout codebase - Split ReactiveTest.ml into themed test files - Add Makefile and README for analysis/reactive - Clean up README to remove V1/V2 references
1 parent aa1941e commit d4092ed

26 files changed

+3054
-3025
lines changed

analysis/reactive/Makefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
.PHONY: build test clean
2+
3+
# Build the reactive library
4+
build:
5+
dune build src/
6+
7+
# Run all tests
8+
test:
9+
dune build test/ReactiveTest.exe
10+
dune exec test/ReactiveTest.exe
11+
12+
# Clean build artifacts
13+
clean:
14+
dune clean
15+

analysis/reactive/README.md

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Reactive Collections Library
2+
3+
A library for incremental computation using reactive collections with delta-based updates.
4+
5+
## Overview
6+
7+
This library provides composable reactive collections that automatically propagate changes through a computation graph. When source data changes, only the affected parts of derived collections are recomputed.
8+
9+
### Key Features
10+
11+
- **Delta-based updates**: Changes propagate as `Set`, `Remove`, or `Batch` deltas
12+
- **Glitch-free semantics**: Topological scheduling ensures consistent updates
13+
- **Composable combinators**: `flatMap`, `join`, `union`, `fixpoint`
14+
- **Incremental fixpoint**: Efficient transitive closure with support for additions and removals
15+
16+
## Usage
17+
18+
```ocaml
19+
open Reactive
20+
21+
(* Create a source collection *)
22+
let (files, emit) = source ~name:"files" ()
23+
24+
(* Derive collections with combinators *)
25+
let decls = flatMap ~name:"decls" files
26+
~f:(fun _path data -> data.declarations)
27+
()
28+
29+
let refs = flatMap ~name:"refs" files
30+
~f:(fun _path data -> data.references)
31+
~merge:PosSet.union
32+
()
33+
34+
(* Join collections *)
35+
let resolved = join ~name:"resolved" refs decls
36+
~key_of:(fun pos _ref -> pos)
37+
~f:(fun pos ref decl_opt -> ...)
38+
()
39+
40+
(* Compute transitive closure *)
41+
let reachable = fixpoint ~name:"reachable"
42+
~init:roots
43+
~edges:graph
44+
()
45+
46+
(* Emit changes *)
47+
emit (Set ("file.res", file_data))
48+
emit (Batch [set "a.res" data_a; set "b.res" data_b])
49+
```
50+
51+
## Combinators
52+
53+
| Combinator | Description |
54+
|------------|-------------|
55+
| `source` | Create a mutable source collection |
56+
| `flatMap` | Transform and flatten entries, with optional merge |
57+
| `join` | Look up keys from left collection in right collection |
58+
| `union` | Combine two collections, with optional merge for conflicts |
59+
| `fixpoint` | Compute transitive closure incrementally |
60+
61+
## Building & Testing
62+
63+
```bash
64+
# Build the library
65+
make build
66+
67+
# Run all tests
68+
make test
69+
70+
# Clean build artifacts
71+
make clean
72+
```
73+
74+
## Test Structure
75+
76+
Tests are organized by theme:
77+
78+
| File | Description |
79+
|------|-------------|
80+
| `FlatMapTest.ml` | FlatMap combinator tests |
81+
| `JoinTest.ml` | Join combinator tests |
82+
| `UnionTest.ml` | Union combinator tests |
83+
| `FixpointBasicTest.ml` | Basic fixpoint graph traversal |
84+
| `FixpointIncrementalTest.ml` | Incremental fixpoint updates |
85+
| `BatchTest.ml` | Batch processing tests |
86+
| `IntegrationTest.ml` | End-to-end file processing |
87+
| `GlitchFreeTest.ml` | Glitch-free scheduler tests |
88+
89+
## Glitch-Free Semantics
90+
91+
The scheduler ensures that derived collections never see inconsistent intermediate states:
92+
93+
1. **Topological levels**: Each node has a level based on its dependencies
94+
2. **Accumulate phase**: All deltas at a level are collected before processing
95+
3. **Propagate phase**: Nodes process accumulated deltas in level order
96+
97+
This prevents issues like:
98+
- Anti-joins seeing partial data (e.g., refs without matching decls)
99+
- Multi-level unions causing spurious additions/removals
100+
101+
## Usage in Reanalyze
102+
103+
This library powers the reactive dead code analysis in reanalyze:
104+
105+
- `ReactiveFileCollection`: Manages CMT file processing
106+
- `ReactiveMerge`: Merges per-file data into global collections
107+
- `ReactiveLiveness`: Computes live declarations via fixpoint
108+
- `ReactiveSolver`: Generates dead code issues reactively
109+

0 commit comments

Comments
 (0)