use std::collections::HashMap;
use super::node::SuffixNode;
use crate::value::DictionaryValue;
use crate::CharUnit;
#[derive(Debug)]
#[cfg_attr(
feature = "serialization",
derive(serde::Serialize, serde::Deserialize)
)]
#[cfg_attr(
all(feature = "serialization", not(feature = "persistent-artrie")),
serde(bound(
serialize = "U: serde::Serialize, V: serde::Serialize",
deserialize = "U: serde::Deserialize<'de>, V: serde::Deserialize<'de>",
))
)]
#[cfg_attr(
all(feature = "serialization", feature = "persistent-artrie"),
serde(bound(
serialize = "U: serde::Serialize, V: serde::Serialize",
deserialize = "U: serde::de::DeserializeOwned, V: serde::de::DeserializeOwned",
))
)]
pub struct SuffixAutomatonInner<U: CharUnit, V: DictionaryValue = ()> {
pub nodes: Vec<SuffixNode<U, V>>,
pub last_state: usize,
pub string_count: usize,
pub source_texts: Vec<String>,
pub positions: HashMap<usize, Vec<(usize, usize)>>,
pub needs_compaction: bool,
}
impl<U: CharUnit, V: DictionaryValue> SuffixAutomatonInner<U, V> {
pub fn new() -> Self {
Self {
nodes: vec![SuffixNode::root()],
last_state: 0,
string_count: 0,
source_texts: Vec::new(),
positions: HashMap::new(),
needs_compaction: false,
}
}
pub fn extend(&mut self, unit: U) {
let cur = self.nodes.len();
let mut new_node = SuffixNode::new(self.nodes[self.last_state].max_length + 1);
new_node.is_final = true;
self.nodes.push(new_node);
let mut p = Some(self.last_state);
while let Some(p_idx) = p {
if self.nodes[p_idx].find_edge(unit).is_some() {
break;
}
self.nodes[p_idx].add_edge(unit, cur);
p = self.nodes[p_idx].suffix_link;
}
if let Some(p_idx) = p {
let q = self.nodes[p_idx]
.find_edge(unit)
.expect("suffix-link walk exited with a known edge for unit at p_idx");
if self.nodes[p_idx].max_length + 1 == self.nodes[q].max_length {
self.nodes[cur].suffix_link = Some(q);
} else {
let clone = self.nodes.len();
let mut cloned_node = self.nodes[q].clone();
cloned_node.max_length = self.nodes[p_idx].max_length + 1;
cloned_node.is_final = true;
self.nodes.push(cloned_node);
self.nodes[cur].suffix_link = Some(clone);
self.nodes[q].suffix_link = Some(clone);
let mut p2 = Some(p_idx);
while let Some(p2_idx) = p2 {
if let Some(target) = self.nodes[p2_idx].find_edge(unit) {
if target == q {
self.nodes[p2_idx].update_edge(unit, clone);
p2 = self.nodes[p2_idx].suffix_link;
} else {
break;
}
} else {
break;
}
}
}
} else {
self.nodes[cur].suffix_link = Some(0);
}
self.last_state = cur;
}
}
impl<U: CharUnit, V: DictionaryValue> Default for SuffixAutomatonInner<U, V> {
fn default() -> Self {
Self::new()
}
}