Skip to content

Commit 58a7cb3

Browse files
authored
Merge pull request #11 from lqd/unleash-the-treefrog
Unleash the treefrog
2 parents 4d1e089 + 093c25a commit 58a7cb3

File tree

7 files changed

+523
-89
lines changed

7 files changed

+523
-89
lines changed

.travis.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
language: rust
2+
before_script:
3+
- rustup component add rustfmt-preview
4+
rust:
5+
- beta
6+
- nightly
7+
matrix:
8+
- fast_finish: true
9+
- allow_failures:
10+
- nightly
11+
script:
12+
- cargo build
13+
- cargo fmt --all -- --check
14+
- cargo test --all

src/bin/borrow_check.rs renamed to examples/borrow_check.rs

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ type Borrow = u32;
66
type Point = u32;
77

88
fn main() {
9-
109
let subset = {
11-
1210
// Create a new iteration context, ...
1311
let mut iteration1 = Iteration::new();
1412

@@ -34,37 +32,36 @@ fn main() {
3432

3533
// .. and then start iterating rules!
3634
while iteration1.changed() {
37-
3835
// remap fields to re-index by keys.
39-
subset_r1p.from_map(&subset, |&(r1,r2,p)| ((r1,p),r2));
40-
subset_r2p.from_map(&subset, |&(r1,r2,p)| ((r2,p),r1));
41-
subset_p.from_map(&subset, |&(r1,r2,p)| (p,(r1,r2)));
36+
subset_r1p.from_map(&subset, |&(r1, r2, p)| ((r1, p), r2));
37+
subset_r2p.from_map(&subset, |&(r1, r2, p)| ((r2, p), r1));
38+
subset_p.from_map(&subset, |&(r1, r2, p)| (p, (r1, r2)));
4239

4340
// R0: subset(R1, R2, P) :- outlives(R1, R2, P).
4441
// Already loaded; outlives is static.
4542

4643
// R1: subset(R1, R3, P) :-
4744
// subset(R1, R2, P),
4845
// subset(R2, R3, P).
49-
subset.from_join(&subset_r2p, &subset_r1p, |&(_r2,p),&r1,&r3| (r1,r3,p));
46+
subset.from_join(&subset_r2p, &subset_r1p, |&(_r2, p), &r1, &r3| (r1, r3, p));
5047

5148
// R2: subset(R1, R2, Q) :-
5249
// subset(R1, R2, P),
5350
// cfg_edge(P, Q),
5451
// region_live_at(R1, Q),
5552
// region_live_at(R2, Q).
5653

57-
subset_1.from_join(&subset_p, &cfg_edge_p, |&_p, &(r1,r2), &q| ((r1,q),r2));
58-
subset_2.from_join(&subset_1, &region_live_at, |&(r1,q),&r2,&()| ((r2,q),r1));
59-
subset.from_join(&subset_2, &region_live_at, |&(r2,q),&r1,&()| (r1,r2,q));
60-
54+
subset_1.from_join(&subset_p, &cfg_edge_p, |&_p, &(r1, r2), &q| ((r1, q), r2));
55+
subset_2.from_join(&subset_1, &region_live_at, |&(r1, q), &r2, &()| {
56+
((r2, q), r1)
57+
});
58+
subset.from_join(&subset_2, &region_live_at, |&(r2, q), &r1, &()| (r1, r2, q));
6159
}
6260

6361
subset_r1p.complete()
6462
};
6563

6664
let requires = {
67-
6865
// Create a new iteration context, ...
6966
let mut iteration2 = Iteration::new();
7067

@@ -87,9 +84,8 @@ fn main() {
8784

8885
// .. and then start iterating rules!
8986
while iteration2.changed() {
90-
91-
requires_rp.from_map(&requires, |&(r,b,p)| ((r,p),b));
92-
requires_bp.from_map(&requires, |&(r,b,p)| ((b,p),r));
87+
requires_rp.from_map(&requires, |&(r, b, p)| ((r, p), b));
88+
requires_bp.from_map(&requires, |&(r, b, p)| ((b, p), r));
9389

9490
// requires(R, B, P) :- borrow_region(R, B, P).
9591
// Already loaded; borrow_region is static.
@@ -105,16 +101,15 @@ fn main() {
105101
// cfg_edge(P, Q),
106102
// (region_live_at(R, Q); universal_region(R)).
107103

108-
requires_1.from_antijoin(&requires_bp, &killed, |&(b,p),&r| (p,(b,r)));
109-
requires_2.from_join(&requires_1, &cfg_edge_p, |&_p, &(b,r), &q| ((r,q),b));
110-
requires.from_join(&requires_2, &region_live_at, |&(r,q),&b,&()| (r,b,q));
104+
requires_1.from_antijoin(&requires_bp, &killed, |&(b, p), &r| (p, (b, r)));
105+
requires_2.from_join(&requires_1, &cfg_edge_p, |&_p, &(b, r), &q| ((r, q), b));
106+
requires.from_join(&requires_2, &region_live_at, |&(r, q), &b, &()| (r, b, q));
111107
}
112108

113109
requires.complete()
114110
};
115111

116-
// borrow_live_at(B, P) :- requires(R, B, P), region_live_at(R, P)
117-
118-
// borrow_live_at(B, P) :- requires(R, B, P), universal_region(R).
112+
// borrow_live_at(B, P) :- requires(R, B, P), region_live_at(R, P)
119113

120-
}
114+
// borrow_live_at(B, P) :- requires(R, B, P), universal_region(R).
115+
}

src/bin/graspan1.rs renamed to examples/graspan1.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,15 @@ extern crate datafrog;
22
use datafrog::Iteration;
33

44
fn main() {
5-
65
let timer = ::std::time::Instant::now();
76

87
// Make space for input data.
98
let mut nodes = Vec::new();
109
let mut edges = Vec::new();
1110

1211
// Read input data from a handy file.
13-
use std::io::{BufRead, BufReader};
1412
use std::fs::File;
13+
use std::io::{BufRead, BufReader};
1514

1615
let filename = std::env::args().nth(1).unwrap();
1716
let file = BufReader::new(File::open(filename).unwrap());
@@ -23,9 +22,13 @@ fn main() {
2322
let dst: u32 = elts.next().unwrap().parse().expect("malformed dst");
2423
let typ: &str = elts.next().unwrap();
2524
match typ {
26-
"n" => { nodes.push((dst, src)); },
27-
"e" => { edges.push((src, dst)); },
28-
unk => { panic!("unknown type: {}", unk)},
25+
"n" => {
26+
nodes.push((dst, src));
27+
}
28+
"e" => {
29+
edges.push((src, dst));
30+
}
31+
unk => panic!("unknown type: {}", unk),
2932
}
3033
}
3134
}
@@ -36,8 +39,8 @@ fn main() {
3639
let mut iteration = Iteration::new();
3740

3841
// .. some variables, ..
39-
let variable1 = iteration.variable::<(u32,u32)>("nodes");
40-
let variable2 = iteration.variable::<(u32,u32)>("edges");
42+
let variable1 = iteration.variable::<(u32, u32)>("nodes");
43+
let variable2 = iteration.variable::<(u32, u32)>("edges");
4144

4245
// .. load them with some initial values, ..
4346
variable1.insert(nodes.into());
@@ -46,11 +49,14 @@ fn main() {
4649
// .. and then start iterating rules!
4750
while iteration.changed() {
4851
// N(a,c) <- N(a,b), E(b,c)
49-
variable1.from_join(&variable1, &variable2, |_b, &a, &c| (c,a));
52+
variable1.from_join(&variable1, &variable2, |_b, &a, &c| (c, a));
5053
}
5154

5255
let reachable = variable1.complete();
5356

54-
println!("{:?}\tComputation complete (nodes_final: {})", timer.elapsed(), reachable.len());
55-
57+
println!(
58+
"{:?}\tComputation complete (nodes_final: {})",
59+
timer.elapsed(),
60+
reachable.len()
61+
);
5662
}

src/join.rs

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
//! Join functionality.
22
3-
use super::{Variable, Relation};
3+
use super::{Relation, Variable};
44

55
pub fn join_into<Key: Ord, Val1: Ord, Val2: Ord, Result: Ord>(
66
input1: &Variable<(Key, Val1)>,
77
input2: &Variable<(Key, Val2)>,
88
output: &Variable<Result>,
9-
mut logic: impl FnMut(&Key, &Val1, &Val2)->Result) {
10-
9+
mut logic: impl FnMut(&Key, &Val1, &Val2) -> Result,
10+
) {
1111
let mut results = Vec::new();
1212

1313
let recent1 = input1.recent.borrow();
1414
let recent2 = input2.recent.borrow();
1515

16-
{ // scoped to let `closure` drop borrow of `results`.
16+
{
17+
// scoped to let `closure` drop borrow of `results`.
1718

18-
let mut closure = |k: &Key, v1: &Val1, v2: &Val2| results.push(logic(k,v1,v2));
19+
let mut closure = |k: &Key, v1: &Val1, v2: &Val2| results.push(logic(k, v1, v2));
1920

2021
for batch2 in input2.stable.borrow().iter() {
2122
join_helper(&recent1, &batch2, &mut closure);
@@ -36,40 +37,44 @@ pub fn antijoin_into<Key: Ord, Val: Ord, Result: Ord>(
3637
input1: &Variable<(Key, Val)>,
3738
input2: &Relation<Key>,
3839
output: &Variable<Result>,
39-
mut logic: impl FnMut(&Key, &Val)->Result) {
40-
40+
mut logic: impl FnMut(&Key, &Val) -> Result,
41+
) {
4142
let mut tuples2 = &input2[..];
4243

43-
let results = input1.recent.borrow().iter().filter(|(ref key, _)| {
44-
tuples2 = gallop(tuples2, |k| k < key);
45-
tuples2.first() != Some(key)
46-
}).map(|(ref key, ref val)| logic(key, val)).collect::<Vec<_>>();
44+
let results = input1
45+
.recent
46+
.borrow()
47+
.iter()
48+
.filter(|(ref key, _)| {
49+
tuples2 = gallop(tuples2, |k| k < key);
50+
tuples2.first() != Some(key)
51+
})
52+
.map(|(ref key, ref val)| logic(key, val))
53+
.collect::<Vec<_>>();
4754

4855
output.insert(Relation::from_vec(results));
4956
}
5057

5158
fn join_helper<K: Ord, V1, V2>(
52-
mut slice1: &[(K,V1)],
53-
mut slice2: &[(K,V2)],
54-
mut result: impl FnMut(&K,&V1,&V2)) {
55-
59+
mut slice1: &[(K, V1)],
60+
mut slice2: &[(K, V2)],
61+
mut result: impl FnMut(&K, &V1, &V2),
62+
) {
5663
while !slice1.is_empty() && !slice2.is_empty() {
57-
5864
use std::cmp::Ordering;
5965

6066
// If the keys match produce tuples, else advance the smaller key until they might.
6167
match slice1[0].0.cmp(&slice2[0].0) {
6268
Ordering::Less => {
6369
slice1 = gallop(slice1, |x| x.0 < slice2[0].0);
64-
},
70+
}
6571
Ordering::Equal => {
66-
6772
// Determine the number of matching keys in each slice.
6873
let count1 = slice1.iter().take_while(|x| x.0 == slice1[0].0).count();
6974
let count2 = slice2.iter().take_while(|x| x.0 == slice2[0].0).count();
7075

7176
// Produce results from the cross-product of matches.
72-
for index1 in 0 .. count1 {
77+
for index1 in 0..count1 {
7378
for s2 in slice2[..count2].iter() {
7479
result(&slice1[0].0, &slice1[index1].1, &s2.1);
7580
}
@@ -86,7 +91,7 @@ fn join_helper<K: Ord, V1, V2>(
8691
}
8792
}
8893

89-
pub fn gallop<T>(mut slice: &[T], mut cmp: impl FnMut(&T)->bool) -> &[T] {
94+
pub fn gallop<T>(mut slice: &[T], mut cmp: impl FnMut(&T) -> bool) -> &[T] {
9095
// if empty slice, or already >= element, return
9196
if !slice.is_empty() && cmp(&slice[0]) {
9297
let mut step = 1;

0 commit comments

Comments
 (0)