+ timesearch: TimeSearcher,
+
+ print_chunks: bool,
+}
+
+#[derive(Default)]
+struct TimeSearcher {
+ idx: usize,
+ base: u64,
+ sbase: u32,
+ cur_len: u32,
+ cur_mul: u32,
+}
+
+impl TimeSearcher {
+ fn new() -> Self { Self::default() }
+ fn reset(&mut self) {
+ *self = Self::default();
+ }
+ fn map_time(&mut self, sample: u32, tts: &Vec<(u32, u32)>) -> u64 {
+ if tts.is_empty() {
+ u64::from(sample)
+ } else if sample >= self.sbase {
+ let mut sample = sample - self.sbase;
+ if self.idx == 0 {
+ let (cur_len, cur_mul) = tts[0];
+ self.cur_len = cur_len;
+ self.cur_mul = cur_mul;
+ self.idx += 1;
+ }
+ while self.idx < tts.len() && sample > self.cur_len {
+ sample -= self.cur_len;
+ self.sbase += self.cur_len;
+ self.base += u64::from(self.cur_len) * u64::from(self.cur_mul);
+ self.cur_len = tts[self.idx].0;
+ self.cur_mul = tts[self.idx].1;
+ self.idx += 1;
+ }
+ self.base + u64::from(sample) * u64::from(self.cur_mul)
+ } else {
+ self.reset();
+ self.map_time(sample, tts)
+ }
+ }
+}
+
+#[derive(Default)]
+struct RLESearcher<T> {
+ array: Vec<(u32, T)>,
+ idx: usize,
+ start: u64,
+ next: u64,
+}
+
+impl<T:Default+Copy> RLESearcher<T> {
+ fn new() -> Self { Self::default() }
+ fn resize(&mut self, size: usize) {
+ self.array.truncate(0);
+ self.array.reserve(size);
+ }
+ fn add(&mut self, len: u32, val: T) {
+ self.array.push((len, val));
+ }
+ fn reset(&mut self) {
+ self.start = 0;
+ if !self.array.is_empty() {
+ self.idx = 0;
+ self.next = u64::from(self.array[0].0);
+ } else {
+ self.idx = self.array.len();
+ self.next = 0;
+ }
+ }
+ fn map(&mut self, sample: u64) -> Option<T> {
+ if sample < self.start {
+ self.reset();
+ }
+ if self.idx < self.array.len() {
+ if sample < self.next {
+ Some(self.array[self.idx].1)
+ } else {
+ while (self.idx < self.array.len()) && (sample >= self.next) {
+ self.start = self.next;
+ self.idx += 1;
+ if self.idx < self.array.len() {
+ self.next += u64::from(self.array[self.idx].0);
+ }
+ }
+ if self.idx < self.array.len() {
+ Some(self.array[self.idx].1)
+ } else {
+ None
+ }
+ }
+ } else {
+ None
+ }
+ }