use std::ops::Range;
use crate::backtrack_encoder::BacktrackEncoder;
use crate::byte_pair_encoding::BytePairEncoding;
pub struct IntervalEncoding<'a> {
bpe: &'a BytePairEncoding,
text: &'a [u8],
last_token: Vec<u32>,
tree_id: Vec<u32>,
tree_end: Vec<u32>,
tree_depth: Vec<u32>,
}
impl<'a> IntervalEncoding<'a> {
pub fn new(bpe: &'a BytePairEncoding, text: &'a [u8]) -> Self {
let last_token = bpe.encode_all_prefixes(text);
let mut tree_size = vec![1; text.len() + 1];
for (id, token) in last_token.iter().copied().enumerate().rev() {
let id = id + 1;
tree_size[id - bpe.token_len(token)] += tree_size[id];
}
let mut tree_end = vec![1];
let mut tree_id = vec![0];
let mut tree_depth = vec![0];
for (id, token) in last_token.iter().copied().enumerate() {
let id = id + 1;
let parent = id - bpe.token_len(token);
tree_id.push(tree_end[parent]);
tree_end.push(tree_end[parent] + 1);
tree_depth.push(tree_depth[parent] + 1);
tree_end[parent] += tree_size[id];
}
Self {
bpe,
text,
last_token,
tree_id,
tree_end,
tree_depth,
}
}
pub fn count(&self, range: Range<usize>) -> usize {
let leaf = self.tree_id[range.end];
let mut encoder = BacktrackEncoder::with_capacity(self.bpe, &self.text[range.clone()], 8);
while let Some(next_token) = encoder.step() {
if let Some(prev_token) = encoder.last_token() {
let end_pos = encoder.pos() + range.start;
if (self.tree_id[end_pos]..self.tree_end[end_pos]).contains(&leaf)
&& self.last_token[end_pos - 1] == prev_token
&& self.last_token[end_pos - 1 + self.bpe.token_len(next_token)] == next_token
{
return encoder.count()
+ (self.tree_depth[range.end] - self.tree_depth[end_pos]) as usize;
}
}
}
encoder.count()
}
}