From a59ca28e2cf92b1e4b300f3f5c58e58008f1a0b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Lecrenier?= Date: Sun, 19 Mar 2023 15:14:40 +0100 Subject: [PATCH] Add forgotten file --- .../new/ranking_rule_graph/dead_ends_cache.rs | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 milli/src/search/new/ranking_rule_graph/dead_ends_cache.rs diff --git a/milli/src/search/new/ranking_rule_graph/dead_ends_cache.rs b/milli/src/search/new/ranking_rule_graph/dead_ends_cache.rs new file mode 100644 index 000000000..ecb6ae8da --- /dev/null +++ b/milli/src/search/new/ranking_rule_graph/dead_ends_cache.rs @@ -0,0 +1,93 @@ +use crate::search::new::{ + interner::{FixedSizeInterner, Interned}, + small_bitmap::SmallBitmap, +}; + +pub struct DeadEndsCache { + conditions: Vec>, + next: Vec, + pub forbidden: SmallBitmap, +} +impl Clone for DeadEndsCache { + fn clone(&self) -> Self { + Self { + conditions: self.conditions.clone(), + next: self.next.clone(), + forbidden: self.forbidden.clone(), + } + } +} +impl DeadEndsCache { + pub fn new(for_interner: &FixedSizeInterner) -> Self { + Self { + conditions: vec![], + next: vec![], + forbidden: SmallBitmap::for_interned_values_in(for_interner), + } + } + pub fn forbid_condition(&mut self, condition: Interned) { + self.forbidden.insert(condition); + } + + pub fn advance(&mut self, condition: Interned) -> Option<&mut Self> { + if let Some(idx) = self.conditions.iter().position(|c| *c == condition) { + Some(&mut self.next[idx]) + } else { + None + } + } + pub fn forbidden_conditions_for_all_prefixes_up_to( + &mut self, + prefix: &[Interned], + ) -> SmallBitmap { + let mut forbidden = self.forbidden.clone(); + let mut cursor = self; + for c in prefix.iter() { + if let Some(next) = cursor.advance(*c) { + cursor = next; + forbidden.union(&cursor.forbidden); + } else { + break; + } + } + forbidden + } + pub fn forbidden_conditions_after_prefix( + &mut self, + prefix: &[Interned], + ) -> Option> { + let mut cursor = self; + for c in prefix.iter() { + if let Some(next) = cursor.advance(*c) { + cursor = next; + } else { + return None; + } + } + Some(cursor.forbidden.clone()) + } + pub fn forbid_condition_after_prefix( + &mut self, + mut prefix: impl Iterator>, + forbidden: Interned, + ) { + match prefix.next() { + None => { + self.forbidden.insert(forbidden); + } + Some(first_condition) => { + if let Some(idx) = self.conditions.iter().position(|c| *c == first_condition) { + return self.next[idx].forbid_condition_after_prefix(prefix, forbidden); + } + let mut rest = DeadEndsCache { + conditions: vec![], + next: vec![], + forbidden: SmallBitmap::new(self.forbidden.universe_length()), + }; + rest.forbid_condition_after_prefix(prefix, forbidden); + self.conditions.push(first_condition); + self.next.push(rest); + } + } + } +}