use plain sweep in proximity criterion

This commit is contained in:
many 2021-03-04 16:07:07 +01:00 committed by Kerollmops
parent ae47bb3594
commit 2606c92ef9
No known key found for this signature in database
GPG Key ID: 92ADA4E935E71FA4

View File

@ -1,4 +1,4 @@
use std::collections::{BTreeMap, HashMap}; use std::collections::{BTreeMap, HashMap, btree_map};
use std::mem::take; use std::mem::take;
use roaring::RoaringBitmap; use roaring::RoaringBitmap;
@ -16,6 +16,7 @@ pub struct Proximity<'t> {
bucket_candidates: RoaringBitmap, bucket_candidates: RoaringBitmap,
parent: Option<Box<dyn Criterion + 't>>, parent: Option<Box<dyn Criterion + 't>>,
candidates_cache: HashMap<(Operation, u8), Vec<(Query, Query, RoaringBitmap)>>, candidates_cache: HashMap<(Operation, u8), Vec<(Query, Query, RoaringBitmap)>>,
plane_sweep_cache: Option<btree_map::IntoIter<u8, RoaringBitmap>>,
} }
impl<'t> Proximity<'t> { impl<'t> Proximity<'t> {
@ -33,6 +34,7 @@ impl<'t> Proximity<'t> {
bucket_candidates: RoaringBitmap::new(), bucket_candidates: RoaringBitmap::new(),
parent: None, parent: None,
candidates_cache: HashMap::new(), candidates_cache: HashMap::new(),
plane_sweep_cache: None,
} }
} }
@ -45,6 +47,7 @@ impl<'t> Proximity<'t> {
bucket_candidates: RoaringBitmap::new(), bucket_candidates: RoaringBitmap::new(),
parent: Some(parent), parent: Some(parent),
candidates_cache: HashMap::new(), candidates_cache: HashMap::new(),
plane_sweep_cache: None,
} }
} }
} }
@ -69,15 +72,42 @@ impl<'t> Criterion for Proximity<'t> {
}, },
(Some((max_prox, query_tree)), Allowed(candidates)) => { (Some((max_prox, query_tree)), Allowed(candidates)) => {
if self.proximity as usize > *max_prox { if self.proximity as usize > *max_prox {
// reset state to (None, Forbidden(_))
self.query_tree = None; self.query_tree = None;
self.candidates = Candidates::default(); self.candidates = Candidates::default();
} else { } else {
let mut new_candidates = resolve_candidates( let mut new_candidates = if candidates.len() <= 1000 {
self.ctx, if let Some(cache) = self.plane_sweep_cache.as_mut() {
&query_tree, match cache.next() {
self.proximity, Some((p, candidates)) => {
&mut self.candidates_cache, self.proximity = p;
)?; candidates
},
None => {
// reset state to (None, Forbidden(_))
self.query_tree = None;
self.candidates = Candidates::default();
continue
},
}
} else {
let cache = resolve_plane_sweep_candidates(
self.ctx,
query_tree,
candidates
)?;
self.plane_sweep_cache = Some(cache.into_iter());
continue
}
} else { // use set theory based algorithm
resolve_candidates(
self.ctx,
&query_tree,
self.proximity,
&mut self.candidates_cache,
)?
};
new_candidates.intersect_with(&candidates); new_candidates.intersect_with(&candidates);
candidates.difference_with(&new_candidates); candidates.difference_with(&new_candidates);
@ -140,6 +170,7 @@ impl<'t> Criterion for Proximity<'t> {
self.proximity = 0; self.proximity = 0;
self.candidates = Candidates::Allowed(candidates); self.candidates = Candidates::Allowed(candidates);
self.bucket_candidates.union_with(&bucket_candidates); self.bucket_candidates.union_with(&bucket_candidates);
self.plane_sweep_cache = None;
}, },
None => return Ok(None), None => return Ok(None),
} }