@@ -22,12 +22,8 @@ mod join;
22
22
/// A relation represents a fixed set of key-value pairs. In many places in a
23
23
/// Datalog computation we want to be sure that certain relations are not able
24
24
/// to vary (for example, in antijoins).
25
- #[ derive( Eq , PartialEq ) ]
26
25
pub struct Relation < Tuple : Ord > {
27
- /// Wrapped elements in the relation.
28
- ///
29
- /// It is crucial that if this type is constructed manually, this field be
30
- /// sorted, and it is probably important that all elements be distinct.
26
+ /// Sorted list of distinct tuples.
31
27
pub elements : Vec < Tuple >
32
28
}
33
29
@@ -61,13 +57,18 @@ impl<Tuple: Ord> Relation<Tuple> {
61
57
elements. dedup ( ) ;
62
58
Relation { elements }
63
59
}
60
+
61
+ fn from_vec ( mut elements : Vec < Tuple > ) -> Self {
62
+ elements. sort_unstable ( ) ;
63
+ elements. dedup ( ) ;
64
+ Relation { elements }
65
+ }
66
+
64
67
}
65
68
66
69
impl < Tuple : Ord , I : IntoIterator < Item =Tuple > > From < I > for Relation < Tuple > {
67
70
fn from ( iterator : I ) -> Self {
68
- let mut elements: Vec < Tuple > = iterator. into_iter ( ) . collect ( ) ;
69
- elements. sort_unstable ( ) ;
70
- Relation { elements }
71
+ Relation :: from_vec ( iterator. into_iter ( ) . collect ( ) )
71
72
}
72
73
}
73
74
@@ -120,34 +121,39 @@ impl Iteration {
120
121
}
121
122
122
123
/// A type that can report on whether it has changed.
123
- pub trait VariableTrait {
124
+ trait VariableTrait {
124
125
/// Reports whether the variable has changed since it was last asked.
125
126
fn changed ( & mut self ) -> bool ;
126
127
}
127
128
128
129
/// An monotonically increasing set of `Tuple`s.
129
130
///
130
- /// The design here is that there are three types of tuples: i. those that have been
131
- /// processed by all operators that can access the variable, ii. those that should now
132
- /// be processed by all operators that can access the variable, and iii. those that
133
- /// have only just been added and should eventually be promoted to type ii. (but which
134
- /// are currently hidden) .
131
+ /// There are three stages in the lifecycle of a tuple:
132
+ ///
133
+ /// 1. A tuple is added to `self.to_add`, but is not yet visible externally.
134
+ /// 2. Newly added tuples are then promoted to `self.recent` for one iteration.
135
+ /// 3. After one iteration, recent tuples are moved to `self.tuples` for posterity .
135
136
///
136
137
/// Each time `self.changed()` is called, the `recent` relation is folded into `tuples`,
137
- /// and the `to_add` relations are merged, deduplicated against `tuples`, and then made
138
- /// `recent`. This way, across calls to `changed()` all added relations are at some point
139
- /// in `recent` once and eventually all are in `tuples`.
138
+ /// and the `to_add` relations are merged, potentially deduplicated against `tuples`, and
139
+ /// then made `recent`. This way, across calls to `changed()` all added tuples are in
140
+ /// `recent` at least once and eventually all are in `tuples`.
141
+ ///
142
+ /// A `Variable` may optionally be instructed not to de-duplicate its tuples, for reasons
143
+ /// of performance. Such a variable cannot be relied on to terminate iterative computation,
144
+ /// and it is important that any cycle of derivations have at least one de-duplicating
145
+ /// variable on it.
140
146
pub struct Variable < Tuple : Ord > {
141
147
/// Should the variable be maintained distinctly.
142
- pub distinct : bool ,
148
+ distinct : bool ,
143
149
/// A useful name for the variable.
144
- pub name : String ,
150
+ name : String ,
145
151
/// A list of relations whose union are the accepted tuples.
146
- pub tuples : Rc < RefCell < Vec < Relation < Tuple > > > > ,
152
+ stable : Rc < RefCell < Vec < Relation < Tuple > > > > ,
147
153
/// A list of recent tuples, still to be processed.
148
- pub recent : Rc < RefCell < Relation < Tuple > > > ,
154
+ recent : Rc < RefCell < Relation < Tuple > > > ,
149
155
/// A list of future tuples, to be introduced.
150
- pub to_add : Rc < RefCell < Vec < Relation < Tuple > > > > ,
156
+ to_add : Rc < RefCell < Vec < Relation < Tuple > > > > ,
151
157
}
152
158
153
159
// Operator implementations.
@@ -256,7 +262,7 @@ impl<Tuple: Ord> Clone for Variable<Tuple> {
256
262
Variable {
257
263
distinct : self . distinct ,
258
264
name : self . name . clone ( ) ,
259
- tuples : self . tuples . clone ( ) ,
265
+ stable : self . stable . clone ( ) ,
260
266
recent : self . recent . clone ( ) ,
261
267
to_add : self . to_add . clone ( ) ,
262
268
}
@@ -268,7 +274,7 @@ impl<Tuple: Ord> Variable<Tuple> {
268
274
Variable {
269
275
distinct : true ,
270
276
name : name. to_string ( ) ,
271
- tuples : Rc :: new ( RefCell :: new ( Vec :: new ( ) . into ( ) ) ) ,
277
+ stable : Rc :: new ( RefCell :: new ( Vec :: new ( ) . into ( ) ) ) ,
272
278
recent : Rc :: new ( RefCell :: new ( Vec :: new ( ) . into ( ) ) ) ,
273
279
to_add : Rc :: new ( RefCell :: new ( Vec :: new ( ) . into ( ) ) ) ,
274
280
}
@@ -292,7 +298,7 @@ impl<Tuple: Ord> Variable<Tuple> {
292
298
assert ! ( self . recent. borrow( ) . is_empty( ) ) ;
293
299
assert ! ( self . to_add. borrow( ) . is_empty( ) ) ;
294
300
let mut result: Relation < Tuple > = Vec :: new ( ) . into ( ) ;
295
- while let Some ( batch) = self . tuples . borrow_mut ( ) . pop ( ) {
301
+ while let Some ( batch) = self . stable . borrow_mut ( ) . pop ( ) {
296
302
result = result. merge ( batch) ;
297
303
}
298
304
result
@@ -302,14 +308,14 @@ impl<Tuple: Ord> Variable<Tuple> {
302
308
impl < Tuple : Ord > VariableTrait for Variable < Tuple > {
303
309
fn changed ( & mut self ) -> bool {
304
310
305
- // 1. Merge self.recent into self.tuples .
306
- let mut recent = :: std :: mem :: replace ( & mut ( * self . recent . borrow_mut ( ) ) , Vec :: new ( ) . into ( ) ) ;
307
- while self . tuples . borrow ( ) . last ( ) . map ( |x| x . len ( ) <= 2 * recent. len ( ) ) == Some ( true ) {
308
- let last = self . tuples . borrow_mut ( ) . pop ( ) . unwrap ( ) ;
309
- recent = recent . merge ( last ) ;
310
- }
311
- if !recent . is_empty ( ) {
312
- self . tuples . borrow_mut ( ) . push ( recent) ;
311
+ // 1. Merge self.recent into self.stable .
312
+ if ! self . recent . borrow ( ) . is_empty ( ) {
313
+ let mut recent = :: std :: mem :: replace ( & mut ( * self . recent . borrow_mut ( ) ) , Vec :: new ( ) . into ( ) ) ;
314
+ while self . stable . borrow ( ) . last ( ) . map ( |x| x . len ( ) <= 2 * recent . len ( ) ) == Some ( true ) {
315
+ let last = self . stable . borrow_mut ( ) . pop ( ) . unwrap ( ) ;
316
+ recent = recent . merge ( last ) ;
317
+ }
318
+ self . stable . borrow_mut ( ) . push ( recent) ;
313
319
}
314
320
315
321
// 2. Move self.to_add into self.recent.
@@ -318,14 +324,25 @@ impl<Tuple: Ord> VariableTrait for Variable<Tuple> {
318
324
while let Some ( to_add_more) = self . to_add . borrow_mut ( ) . pop ( ) {
319
325
to_add = to_add. merge ( to_add_more) ;
320
326
}
321
- // 2b. Restrict `to_add` to tuples not in `self.tuples `.
327
+ // 2b. Restrict `to_add` to tuples not in `self.stable `.
322
328
if self . distinct {
323
- for batch in self . tuples . borrow ( ) . iter ( ) {
329
+ for batch in self . stable . borrow ( ) . iter ( ) {
324
330
let mut slice = & batch[ ..] ;
325
- to_add. elements . retain ( |x| {
326
- slice = join:: gallop ( slice, |y| y < x) ;
327
- slice. len ( ) == 0 || & slice[ 0 ] != x
328
- } )
331
+ // Only gallop if the slice is relatively large.
332
+ if slice. len ( ) > 4 * to_add. elements . len ( ) {
333
+ to_add. elements . retain ( |x| {
334
+ slice = join:: gallop ( slice, |y| y < x) ;
335
+ slice. len ( ) == 0 || & slice[ 0 ] != x
336
+ } ) ;
337
+ }
338
+ else {
339
+ to_add. elements . retain ( |x| {
340
+ while slice. len ( ) > 0 && & slice[ 0 ] < x {
341
+ slice = & slice[ 1 ..] ;
342
+ }
343
+ slice. len ( ) == 0 || & slice[ 0 ] != x
344
+ } ) ;
345
+ }
329
346
}
330
347
}
331
348
* self . recent . borrow_mut ( ) = to_add;
@@ -340,4 +357,14 @@ impl<Tuple: Ord> VariableTrait for Variable<Tuple> {
340
357
341
358
!self . recent . borrow ( ) . is_empty ( )
342
359
}
343
- }
360
+ }
361
+
362
+ // impl<Tuple: Ord> Drop for Variable<Tuple> {
363
+ // fn drop(&mut self) {
364
+ // let mut total = 0;
365
+ // for batch in self.tuples.borrow().iter() {
366
+ // total += batch.len();
367
+ // }
368
+ // println!("FINAL: {:?}\t{:?}", self.name, total);
369
+ // }
370
+ // }
0 commit comments