use std::cmp;
use crate::{Utf16Char, Utf16String};
pub fn shrink(tail: Utf16String, mut begs: Vec<i32>, mut lens: Vec<Utf16Char>)
-> (Utf16String, Vec<i32>, Vec<Utf16Char>) {
let mut new_tail: Utf16String;
{
let sorted: Vec<TailString> = {
let mut list = Vec::with_capacity(begs.len());
for i in 0..begs.len() {
list.push(TailString {
id: i,
s: &tail[(begs[i] as usize)..(begs[i] as usize + lens[i] as usize)]
});
}
list.sort();
list
};
new_tail = Vec::new();
for i in 0..sorted.len() {
let ts = &sorted[i];
let mut beg_index = new_tail.len();
if i > 0 && sorted[i - 1].s.ends_with(ts.s) {
beg_index -= ts.s.len(); } else {
new_tail.extend_from_slice(ts.s); }
begs[ts.id] = beg_index as i32;
lens[ts.id] = ts.s.len() as Utf16Char;
}
}
(new_tail, begs, lens)
}
struct TailString<'a> {
id: usize,
s: &'a [Utf16Char]
}
impl<'a> cmp::Ord for TailString<'a> {
fn cmp(&self, ts: &Self) -> cmp::Ordering {
let mut i = self.s.len() as isize - 1;
let mut j = ts.s.len() as isize - 1;
loop {
if i < 0 {
if j < 0 {
return cmp::Ordering::Equal;
} else {
return cmp::Ordering::Greater;
}
} else if j < 0 || self.s[i as usize] > ts.s[j as usize] {
return cmp::Ordering::Less;
} else if self.s[i as usize] < ts.s[j as usize] {
return cmp::Ordering::Greater;
}
i -= 1;
j -= 1;
}
}
}
impl<'a> cmp::PartialOrd for TailString<'a> {
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
Some(self.cmp(other))
}
}
impl<'a> cmp::PartialEq for TailString<'a> {
fn eq(&self, other: &Self) -> bool {
self.s.eq(other.s)
}
}
impl<'a> cmp::Eq for TailString<'a> {}