Skip to content

Commit e471a08

Browse files
authored
Merge pull request #35 from ecstatic-morse/leaper-cache-keys
Cache results of previous `Key` search in `Leaper`s
2 parents 0973cdd + e52718d commit e471a08

File tree

1 file changed

+55
-17
lines changed

1 file changed

+55
-17
lines changed

src/treefrog.rs

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ pub(crate) mod extend_with {
377377
start: usize,
378378
end: usize,
379379
key_func: Func,
380+
old_key: Option<Key>,
380381
phantom: ::std::marker::PhantomData<Tuple>,
381382
}
382383

@@ -394,6 +395,7 @@ pub(crate) mod extend_with {
394395
start: 0,
395396
end: 0,
396397
key_func,
398+
old_key: None,
397399
phantom: ::std::marker::PhantomData,
398400
}
399401
}
@@ -409,11 +411,16 @@ pub(crate) mod extend_with {
409411
{
410412
fn count(&mut self, prefix: &Tuple) -> usize {
411413
let key = (self.key_func)(prefix);
412-
self.start = binary_search(&self.relation.elements, |x| &x.0 < &key);
413-
let slice1 = &self.relation[self.start..];
414-
let slice2 = gallop(slice1, |x| &x.0 <= &key);
415-
self.end = self.relation.len() - slice2.len();
416-
slice1.len() - slice2.len()
414+
if self.old_key.as_ref() != Some(&key) {
415+
self.start = binary_search(&self.relation.elements, |x| &x.0 < &key);
416+
let slice1 = &self.relation[self.start..];
417+
let slice2 = gallop(slice1, |x| &x.0 <= &key);
418+
self.end = self.relation.len() - slice2.len();
419+
420+
self.old_key = Some(key);
421+
}
422+
423+
self.end - self.start
417424
}
418425
fn propose(&mut self, _prefix: &Tuple, values: &mut Vec<&'leap Val>) {
419426
let slice = &self.relation[self.start..self.end];
@@ -452,6 +459,8 @@ pub(crate) mod extend_with {
452459
}
453460

454461
pub(crate) mod extend_anti {
462+
use std::ops::Range;
463+
455464
use super::{binary_search, Leaper, Relation};
456465
use crate::join::gallop;
457466

@@ -465,6 +474,7 @@ pub(crate) mod extend_anti {
465474
{
466475
relation: &'leap Relation<(Key, Val)>,
467476
key_func: Func,
477+
old_key: Option<(Key, Range<usize>)>,
468478
phantom: ::std::marker::PhantomData<Tuple>,
469479
}
470480

@@ -480,6 +490,7 @@ pub(crate) mod extend_anti {
480490
ExtendAnti {
481491
relation,
482492
key_func,
493+
old_key: None,
483494
phantom: ::std::marker::PhantomData,
484495
}
485496
}
@@ -501,10 +512,23 @@ pub(crate) mod extend_anti {
501512
}
502513
fn intersect(&mut self, prefix: &Tuple, values: &mut Vec<&'leap Val>) {
503514
let key = (self.key_func)(prefix);
504-
let start = binary_search(&self.relation.elements, |x| &x.0 < &key);
505-
let slice1 = &self.relation[start..];
506-
let slice2 = gallop(slice1, |x| &x.0 <= &key);
507-
let mut slice = &slice1[..(slice1.len() - slice2.len())];
515+
516+
let range = match self.old_key.as_ref() {
517+
Some((old, range)) if old == &key => range.clone(),
518+
519+
_ => {
520+
let start = binary_search(&self.relation.elements, |x| &x.0 < &key);
521+
let slice1 = &self.relation[start..];
522+
let slice2 = gallop(slice1, |x| &x.0 <= &key);
523+
let range = start..self.relation.len()-slice2.len();
524+
525+
self.old_key = Some((key, range.clone()));
526+
527+
range
528+
}
529+
};
530+
531+
let mut slice = &self.relation[range];
508532
if !slice.is_empty() {
509533
values.retain(|v| {
510534
slice = gallop(slice, |kv| &kv.1 < v);
@@ -529,6 +553,7 @@ pub(crate) mod filter_with {
529553
{
530554
relation: &'leap Relation<(Key, Val)>,
531555
key_func: Func,
556+
old_key_val: Option<((Key, Val), bool)>,
532557
phantom: ::std::marker::PhantomData<Tuple>,
533558
}
534559

@@ -544,6 +569,7 @@ pub(crate) mod filter_with {
544569
FilterWith {
545570
relation,
546571
key_func,
572+
old_key_val: None,
547573
phantom: ::std::marker::PhantomData,
548574
}
549575
}
@@ -559,11 +585,16 @@ pub(crate) mod filter_with {
559585
{
560586
fn count(&mut self, prefix: &Tuple) -> usize {
561587
let key_val = (self.key_func)(prefix);
562-
if self.relation.binary_search(&key_val).is_ok() {
563-
usize::max_value()
564-
} else {
565-
0
588+
589+
if let Some((ref old_key_val, is_present)) = self.old_key_val {
590+
if old_key_val == &key_val {
591+
return if is_present { usize::MAX } else { 0 };
592+
}
566593
}
594+
595+
let is_present = self.relation.binary_search(&key_val).is_ok();
596+
self.old_key_val = Some((key_val, is_present));
597+
if is_present { usize::MAX } else { 0 }
567598
}
568599
fn propose(&mut self, _prefix: &Tuple, _values: &mut Vec<&'leap Val2>) {
569600
panic!("FilterWith::propose(): variable apparently unbound.");
@@ -615,6 +646,7 @@ pub(crate) mod filter_anti {
615646
{
616647
relation: &'leap Relation<(Key, Val)>,
617648
key_func: Func,
649+
old_key_val: Option<((Key, Val), bool)>,
618650
phantom: ::std::marker::PhantomData<Tuple>,
619651
}
620652

@@ -630,6 +662,7 @@ pub(crate) mod filter_anti {
630662
FilterAnti {
631663
relation,
632664
key_func,
665+
old_key_val: None,
633666
phantom: ::std::marker::PhantomData,
634667
}
635668
}
@@ -645,11 +678,16 @@ pub(crate) mod filter_anti {
645678
{
646679
fn count(&mut self, prefix: &Tuple) -> usize {
647680
let key_val = (self.key_func)(prefix);
648-
if self.relation.binary_search(&key_val).is_ok() {
649-
0
650-
} else {
651-
usize::max_value()
681+
682+
if let Some((ref old_key_val, is_present)) = self.old_key_val {
683+
if old_key_val == &key_val {
684+
return if is_present { 0 } else { usize::MAX };
685+
}
652686
}
687+
688+
let is_present = self.relation.binary_search(&key_val).is_ok();
689+
self.old_key_val = Some((key_val, is_present));
690+
if is_present { 0 } else { usize::MAX }
653691
}
654692
fn propose(&mut self, _prefix: &Tuple, _values: &mut Vec<&'leap Val2>) {
655693
panic!("FilterAnti::propose(): variable apparently unbound.");

0 commit comments

Comments
 (0)