mirror of
https://github.com/meilisearch/MeiliSearch
synced 2024-11-26 23:04:26 +01:00
Merge #200
200: Fix plane sweep algorithm r=Kerollmops a=LegendreM Fix plain sweep algorithm after creating some tests on proximity. Co-authored-by: many <maxime@meilisearch.com>
This commit is contained in:
commit
76b9178b16
@ -324,18 +324,30 @@ fn resolve_plane_sweep_candidates(
|
|||||||
// take the inner proximity of the first group as initial
|
// take the inner proximity of the first group as initial
|
||||||
let (_, (_, mut proximity, _)) = groups.first()?;
|
let (_, (_, mut proximity, _)) = groups.first()?;
|
||||||
let (_, (left_most_pos, _, _)) = groups.first()?;
|
let (_, (left_most_pos, _, _)) = groups.first()?;
|
||||||
let (_, (_, _, right_most_pos)) = groups.last()?;
|
let (_, (_, _, right_most_pos)) = groups.iter().max_by_key(|(_, (_, _, right_most_pos))| right_most_pos)?;
|
||||||
|
|
||||||
for pair in groups.windows(2) {
|
for pair in groups.windows(2) {
|
||||||
if let [(i1, (_, _, rpos1)), (i2, (lpos2, prox2, _))] = pair {
|
if let [(i1, (lpos1, _, rpos1)), (i2, (lpos2, prox2, rpos2))] = pair {
|
||||||
// if a pair overlap, meaning that they share at least a word, we return None
|
// if two positions are equal, meaning that they share at least a word, we return None
|
||||||
if rpos1 >= lpos2 { return None }
|
if rpos1 == rpos2 || lpos1 == lpos2 || rpos1 == lpos2 || lpos1 == rpos2 {
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
|
||||||
|
let pair_proximity = {
|
||||||
|
// if intervals are disjoint [..].(..)
|
||||||
|
if lpos2 > rpos1 { lpos2 - rpos1 }
|
||||||
|
// if the second interval is a subset of the first [.(..).]
|
||||||
|
else if rpos2 < rpos1 { (lpos2 - lpos1).min(rpos1 - rpos2) }
|
||||||
|
// if intervals overlaps [.(..].)
|
||||||
|
else { (lpos2 - lpos1).min(rpos2 - rpos1) }
|
||||||
|
};
|
||||||
|
|
||||||
// if groups are in the good order (query order) we remove 1 to the proximity
|
// if groups are in the good order (query order) we remove 1 to the proximity
|
||||||
// the proximity is clamped to 7
|
// the proximity is clamped to 7
|
||||||
let pair_proximity = if i1 < i2 {
|
let pair_proximity = if i1 < i2 {
|
||||||
(*lpos2 - *rpos1 - 1).min(7)
|
(pair_proximity - 1).min(7)
|
||||||
} else {
|
} else {
|
||||||
(*lpos2 - *rpos1).min(7)
|
pair_proximity.min(7)
|
||||||
};
|
};
|
||||||
|
|
||||||
proximity += pair_proximity as u8 + prox2;
|
proximity += pair_proximity as u8 + prox2;
|
||||||
@ -385,26 +397,21 @@ fn resolve_plane_sweep_candidates(
|
|||||||
// let q be the position q of second group of the interval.
|
// let q be the position q of second group of the interval.
|
||||||
let q = current[1];
|
let q = current[1];
|
||||||
|
|
||||||
let mut leftmost_index = 0;
|
|
||||||
|
|
||||||
// If p > r, then the interval [l, r] is minimal and
|
// If p > r, then the interval [l, r] is minimal and
|
||||||
// we insert it into the heap according to its size.
|
// we insert it into the heap according to its size.
|
||||||
if p.map_or(true, |p| p.1 > rightmost.1) {
|
if p.map_or(true, |p| p.1 > rightmost.1) {
|
||||||
leftmost_index = current[0].0;
|
|
||||||
if let Some(group) = compute_groups_proximity(¤t, consecutive) {
|
if let Some(group) = compute_groups_proximity(¤t, consecutive) {
|
||||||
output.push(group);
|
output.push(group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO not sure about breaking here or when the p list is found empty.
|
|
||||||
let p = match p {
|
let p = match p {
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
None => break,
|
None => break,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Remove the leftmost group P in the interval,
|
// Replace the leftmost group P in the interval.
|
||||||
// and pop the same group from a list.
|
current[0] = p;
|
||||||
current[leftmost_index] = p;
|
|
||||||
|
|
||||||
if p.1 > rightmost.1 {
|
if p.1 > rightmost.1 {
|
||||||
// if [l, r] is minimal, let r = p and l = q.
|
// if [l, r] is minimal, let r = p and l = q.
|
||||||
|
Loading…
Reference in New Issue
Block a user