Skip to content

Commit ff2f9e3

Browse files
committed
Filtersets API
Filtersets are a novel way of querying spans in ENTRACE, inspired by nixpkgs's Filesets. Filtersets are a generalization of the old en_filter function. A Filterset is a description of a set of span ids. For example, a Primitive filterset is a list of ids or a range of ids; a Filter filterset is the set of ids that match the filter predicate. These description compose via relations such as AND, OR, NOT, etc, this allows filtersets to have an expressive SQL-like API with a minimal backend implementation. In a way, filtersets encode dataflow itself. The other defining feature of a Filterset is that it can be *materialized* (turned into a Vec<id>) freely at any time, which aids debugging, and makes it trivial to switch between Filtersets and "traditional" lua when desired. The performance speedup (1.3-2x) of filtersets primarily comes from the fact that via filtersets, many allocations in the Lua evaluator can be avoided; and that the Filterset evaluator includes a "normalization" step, which tries to rewrite the filterset to the fastest possible query. Filtersets have a long way to go still. The filterset evaluator itself is very generic on purpose; it assumes nothing about ENTRACE itself. In the future, it can (and should) be extracted from this project, as it may be useful in other software as well. There is still a long way to go with filtersets, many possible optmizations (e.g. introducing a DNF type in the evaluator to reduce scans in queries having OR), a BlackBox type that materializes its source without rewriting; but they are already powerful enough to speed up queries; and to provide a nicer syntax.
1 parent 3af49b0 commit ff2f9e3

File tree

12 files changed

+1065
-87
lines changed

12 files changed

+1065
-87
lines changed

Cargo.lock

Lines changed: 20 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bench/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "bench"
3-
version = "0.1.0"
3+
version = "0.1.2"
44
edition = "2024"
55

66
[dependencies]

docs/filtersets.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
THE FILTERSET CALCULUS
2+
---
3+
4+
### TYPES
5+
6+
```rust
7+
type FiltersetId = usize;
8+
struct Predicate {
9+
attr: String,
10+
rel: Ordering,
11+
con: EnValue,
12+
}
13+
#[derive(Debug)]
14+
enum Filterset {
15+
Dead,
16+
Primitive(Roaring),
17+
Rel(Predicate, FiltersetId),
18+
RelIntersect(Vec<Predicate>, FiltersetId),
19+
RelUnion(Vec<Predicate>, FiltersetId),
20+
And(Vec<FiltersetId>),
21+
Or(Vec<FiltersetId>),
22+
Not(FiltersetId),
23+
}
24+
```
25+
26+
### REWRITE RULES
27+
28+
**Flattening**
29+
30+
And([... And(children) ...]) -> And(flattened)
31+
Or([... Or(children) ...]) -> Or(flattened)
32+
Not(Not(X)) -> X
33+
34+
**Eliminating trivial ops (unimplemeneted)**
35+
And([A]) -> A
36+
Or([A]) -> A
37+
38+
**REL composition**
39+
40+
I. Rel(p1, Rel(p2, A)) -> RelIntersect([p1, p2], A)
41+
II. Rel(p, RelIntersect(ps, A)) -> RelIntersect([p] + ps, A)
42+
III. RelIntersect(ps1, RelIntersect(ps2, A)) -> RelIntersect(ps1 + ps2, A)
43+
IV. RelIntersect(ps, Rel(p, A)) -> RelIntersect(ps + [p], A)
44+
V. RelUnion(ps1, RelUnion(ps2, A)) -> RelUnion(ps1 + ps2, A)
45+
46+
47+
**Flattening on the same level (unimplemeneted)**
48+
And([RelIntersect(ps, A), RelIntersect(ps2, A), RelIntersect(_, B) ...])
49+
-> And([RelIntersect(ps1+ps2, A), RelIntersect(_, B)])
50+
- This could be hard to detect, instead there could be just:
51+
And([RelIntersect(ps_1, A), .. RelIntersect(ps_n, A)]) -> RelIntersect(ps_1+..+ps_n, A)
52+
Or([RelUnion(ps, A), RelUnion(ps2, A), RelUnion(_, B) ...])
53+
-> Or([RelUnion(ps1+ps2, A), RelIntersect(_, B)])
54+
- same applies here.

entrace_query/Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "entrace_query"
3-
version = "0.1.1"
3+
version = "0.1.2"
44
edition = "2024"
55

66
[dependencies]
@@ -9,3 +9,8 @@ entrace_core = { version = "0.1.1", path = "../entrace_core/" }
99
anyhow = "1.0.100"
1010
memchr = "2.7.6"
1111
thiserror = "2.0.17"
12+
roaring = "0.11.2"
13+
14+
[[bin]]
15+
name="entrace-query-test"
16+
path="src/main.rs"

0 commit comments

Comments
 (0)