Skip to content

Commit 402f415

Browse files
committed
create a from_leapjoin on Relation
1 parent 2e760a7 commit 402f415

File tree

3 files changed

+41
-4
lines changed

3 files changed

+41
-4
lines changed

src/lib.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,16 @@ impl<Tuple: Ord> Relation<Tuple> {
100100
Relation { elements }
101101
}
102102

103+
/// Creates a `Relation` using the `leapjoin` logic;
104+
/// see [`Variable::leapjoin`]
105+
pub fn from_leapjoin<'a, SourceTuple: Ord, Val: Ord + 'a>(
106+
source: &Relation<SourceTuple>,
107+
leapers: &mut [&mut dyn Leaper<'a, SourceTuple, Val>],
108+
logic: impl FnMut(&SourceTuple, &Val) -> Tuple,
109+
) -> Self {
110+
treefrog::leapjoin(&source.elements, leapers, logic)
111+
}
112+
103113
/// Creates a `Relation` by joining the values from `input1` and
104114
/// `input2` and then applying `logic`. Like
105115
/// [`Variable::from_join`] except for use where the inputs are
@@ -398,7 +408,7 @@ impl<Tuple: Ord> Variable<Tuple> {
398408
leapers: &mut [&mut dyn Leaper<'a, SourceTuple, Val>],
399409
logic: impl FnMut(&SourceTuple, &Val) -> Tuple,
400410
) {
401-
self.insert(treefrog::leapjoin(source, leapers, logic));
411+
self.insert(treefrog::leapjoin(&source.recent.borrow(), leapers, logic));
402412
}
403413
}
404414

src/test.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,30 @@ proptest! {
126126
assert_eq!(output1.elements, output2.elements);
127127
}
128128
}
129+
130+
/// Test that `from_leapjoin` matches against the tuples from an
131+
/// `extend` that precedes first iteration.
132+
///
133+
/// This was always true, but wasn't immediately obvious to me until I
134+
/// re-read the code more carefully. -nikomatsakis
135+
#[test]
136+
fn leapjoin_from_extend() {
137+
let doubles: Relation<(u32, u32)> = (0..10).map(|i| (i, i * 2)).collect();
138+
139+
let mut iteration = Iteration::new();
140+
141+
let variable = iteration.variable::<(u32, u32)>("variable");
142+
variable.extend(Some((2, 2)));
143+
144+
while iteration.changed() {
145+
variable.from_leapjoin(
146+
&variable,
147+
&mut [&mut doubles.extend_with(|&(i, _)| i)],
148+
|&(i, _), &j| (i, j),
149+
);
150+
}
151+
152+
let variable = variable.complete();
153+
154+
assert_eq!(variable.elements, vec![(2, 2), (2, 4)]);
155+
}

src/treefrog.rs

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

55
/// Performs treefrog leapjoin using a list of leapers.
66
pub(crate) fn leapjoin<'a, Tuple: Ord, Val: Ord + 'a, Result: Ord>(
7-
source: &Variable<Tuple>,
7+
source: &[Tuple],
88
leapers: &mut [&mut dyn Leaper<'a, Tuple, Val>],
99
mut logic: impl FnMut(&Tuple, &Val) -> Result,
1010
) -> Relation<Result> {
1111
let mut result = Vec::new(); // temp output storage.
1212
let mut values = Vec::new(); // temp value storage.
1313

14-
for tuple in source.recent.borrow().iter() {
14+
for tuple in source {
1515
// Determine which leaper would propose the fewest values.
1616
let mut min_index = usize::max_value();
1717
let mut min_count = usize::max_value();

0 commit comments

Comments
 (0)