|
@@ -9,8 +9,8 @@ pub struct Cursor<'a> {
|
|
|
pub(crate) delta: &'a Delta,
|
|
|
pub(crate) origin_iv: Interval,
|
|
|
pub(crate) next_iv: Interval,
|
|
|
- pub(crate) iter_char_count: usize,
|
|
|
- pub(crate) iter_op_index: usize,
|
|
|
+ pub(crate) cur_char_count: usize,
|
|
|
+ pub(crate) cur_op_index: usize,
|
|
|
iter: Enumerate<Iter<'a, Operation>>,
|
|
|
next_op: Option<Operation>,
|
|
|
}
|
|
@@ -22,8 +22,8 @@ impl<'a> Cursor<'a> {
|
|
|
delta,
|
|
|
origin_iv: interval,
|
|
|
next_iv: interval,
|
|
|
- iter_char_count: 0,
|
|
|
- iter_op_index: 0,
|
|
|
+ cur_char_count: 0,
|
|
|
+ cur_op_index: 0,
|
|
|
iter: delta.ops.iter().enumerate(),
|
|
|
next_op: None,
|
|
|
};
|
|
@@ -31,11 +31,13 @@ impl<'a> Cursor<'a> {
|
|
|
cursor
|
|
|
}
|
|
|
|
|
|
- pub fn next_iv(&self) -> Interval { self.next_op_iv_before(None) }
|
|
|
+ // get the next operation interval
|
|
|
+ pub fn next_iv(&self) -> Interval { self.next_iv_before(None) }
|
|
|
|
|
|
pub fn next_op(&mut self) -> Option<Operation> { self.next_op_before(None) }
|
|
|
|
|
|
- pub fn next_op_before(&mut self, b_index: Option<usize>) -> Option<Operation> {
|
|
|
+ // get the last operation before the index
|
|
|
+ pub fn next_op_before(&mut self, index: Option<usize>) -> Option<Operation> {
|
|
|
let mut find_op = None;
|
|
|
let next_op = self.next_op.take();
|
|
|
let mut next_op = next_op.as_ref();
|
|
@@ -44,35 +46,35 @@ impl<'a> Cursor<'a> {
|
|
|
next_op = find_next_op(self);
|
|
|
}
|
|
|
|
|
|
- let old_iter_char_count = self.iter_char_count;
|
|
|
+ let pre_char_count = self.cur_char_count;
|
|
|
while find_op.is_none() && next_op.is_some() {
|
|
|
let op = next_op.take().unwrap();
|
|
|
- let interval = self.next_op_iv_before(b_index);
|
|
|
+ let interval = self.next_iv_before(index);
|
|
|
if interval.is_empty() {
|
|
|
self.next_op = Some(op.clone());
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
find_op = op.shrink(interval);
|
|
|
- let suffix = Interval::new(0, op.length()).suffix(interval);
|
|
|
+ let suffix = Interval::new(0, op.len()).suffix(interval);
|
|
|
if !suffix.is_empty() {
|
|
|
self.next_op = op.shrink(suffix);
|
|
|
}
|
|
|
|
|
|
- self.iter_char_count += interval.end;
|
|
|
- self.next_iv.start = self.iter_char_count;
|
|
|
+ self.cur_char_count += interval.end;
|
|
|
+ self.next_iv.start = self.cur_char_count;
|
|
|
|
|
|
if find_op.is_none() {
|
|
|
next_op = find_next_op(self);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if find_op.is_some() {
|
|
|
- let last = self.iter_char_count - old_iter_char_count;
|
|
|
- let force_len = b_index.unwrap_or(0);
|
|
|
- if force_len > last {
|
|
|
- let len = force_len - last;
|
|
|
- return self.next_op_before(Some(len));
|
|
|
+ if find_op.is_some() && index.is_some() {
|
|
|
+ // try to find the next op before the index if iter_char_count less than index
|
|
|
+ let pos = self.cur_char_count - pre_char_count;
|
|
|
+ let end = index.unwrap();
|
|
|
+ if end > pos {
|
|
|
+ return self.next_op_before(Some(end - pos));
|
|
|
}
|
|
|
}
|
|
|
return find_op;
|
|
@@ -83,16 +85,16 @@ impl<'a> Cursor<'a> {
|
|
|
fn descend(&mut self, index: usize) {
|
|
|
self.next_iv.start += index;
|
|
|
|
|
|
- if self.iter_char_count >= self.next_iv.start {
|
|
|
+ if self.cur_char_count >= self.next_iv.start {
|
|
|
return;
|
|
|
}
|
|
|
while let Some((o_index, op)) = self.iter.next() {
|
|
|
- self.iter_op_index = o_index;
|
|
|
- let start = self.iter_char_count;
|
|
|
- let end = start + op.length();
|
|
|
+ self.cur_op_index = o_index;
|
|
|
+ let start = self.cur_char_count;
|
|
|
+ let end = start + op.len();
|
|
|
let intersect = Interval::new(start, end).intersect(self.next_iv);
|
|
|
if intersect.is_empty() {
|
|
|
- self.iter_char_count += op.length();
|
|
|
+ self.cur_char_count += op.len();
|
|
|
} else {
|
|
|
self.next_op = Some(op.clone());
|
|
|
break;
|
|
@@ -105,8 +107,8 @@ impl<'a> Cursor<'a> {
|
|
|
if next_op.is_none() {
|
|
|
let mut offset = 0;
|
|
|
for op in &self.delta.ops {
|
|
|
- offset += op.length();
|
|
|
- if offset > self.iter_char_count {
|
|
|
+ offset += op.len();
|
|
|
+ if offset > self.cur_char_count {
|
|
|
next_op = Some(op);
|
|
|
break;
|
|
|
}
|
|
@@ -115,17 +117,17 @@ impl<'a> Cursor<'a> {
|
|
|
next_op
|
|
|
}
|
|
|
|
|
|
- fn next_op_iv_before(&self, b_index: Option<usize>) -> Interval {
|
|
|
+ fn next_iv_before(&self, index: Option<usize>) -> Interval {
|
|
|
let next_op = self.next_iter_op();
|
|
|
if next_op.is_none() {
|
|
|
return Interval::new(0, 0);
|
|
|
}
|
|
|
|
|
|
let op = next_op.unwrap();
|
|
|
- let start = self.iter_char_count;
|
|
|
- let end = match b_index {
|
|
|
- None => self.iter_char_count + op.length(),
|
|
|
- Some(b_index) => self.iter_char_count + min(b_index, op.length()),
|
|
|
+ let start = self.cur_char_count;
|
|
|
+ let end = match index {
|
|
|
+ None => self.cur_char_count + op.len(),
|
|
|
+ Some(index) => self.cur_char_count + min(index, op.len()),
|
|
|
};
|
|
|
let intersect = Interval::new(start, end).intersect(self.next_iv);
|
|
|
let interval = intersect.translate_neg(start);
|
|
@@ -137,7 +139,7 @@ fn find_next_op<'a>(cursor: &mut Cursor<'a>) -> Option<&'a Operation> {
|
|
|
match cursor.iter.next() {
|
|
|
None => None,
|
|
|
Some((o_index, op)) => {
|
|
|
- cursor.iter_op_index = o_index;
|
|
|
+ cursor.cur_op_index = o_index;
|
|
|
Some(op)
|
|
|
},
|
|
|
}
|
|
@@ -152,11 +154,11 @@ pub struct OpMetric {}
|
|
|
|
|
|
impl Metric for OpMetric {
|
|
|
fn seek(cursor: &mut Cursor, index: usize) -> SeekResult {
|
|
|
- let _ = check_bound(cursor.iter_op_index, index)?;
|
|
|
- let mut temp_cursor = Cursor::new(cursor.delta, cursor.origin_iv);
|
|
|
+ let _ = check_bound(cursor.cur_op_index, index)?;
|
|
|
+ let mut seek_cursor = Cursor::new(cursor.delta, cursor.origin_iv);
|
|
|
let mut offset = 0;
|
|
|
- while let Some((_, op)) = temp_cursor.iter.next() {
|
|
|
- offset += op.length();
|
|
|
+ while let Some((_, op)) = seek_cursor.iter.next() {
|
|
|
+ offset += op.len();
|
|
|
if offset > index {
|
|
|
break;
|
|
|
}
|
|
@@ -170,7 +172,7 @@ pub struct CharMetric {}
|
|
|
|
|
|
impl Metric for CharMetric {
|
|
|
fn seek(cursor: &mut Cursor, index: usize) -> SeekResult {
|
|
|
- let _ = check_bound(cursor.iter_char_count, index)?;
|
|
|
+ let _ = check_bound(cursor.cur_char_count, index)?;
|
|
|
let _ = cursor.next_op_before(Some(index));
|
|
|
|
|
|
Ok(())
|