block_map.rs

  1use std::cmp;
  2
  3use super::wrap_map::{Edit as WrapEdit, Snapshot as WrapSnapshot};
  4use buffer::Bias;
  5use parking_lot::Mutex;
  6use sum_tree::SumTree;
  7
  8struct BlockMap {
  9    transforms: Mutex<SumTree<Transform>>,
 10}
 11
 12struct BlockMapWriter<'a>(&'a mut BlockMap);
 13
 14struct BlockSnapshot {}
 15
 16#[derive(Clone)]
 17struct Transform {
 18    summary: TransformSummary,
 19}
 20
 21#[derive(Copy, Clone, Debug, Default)]
 22struct TransformSummary {
 23    input_rows: u32,
 24    output_rows: u32,
 25}
 26
 27#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
 28struct InputRow(u32);
 29
 30#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
 31struct OutputRow(u32);
 32
 33impl BlockMap {
 34    fn new(wrap_snapshot: WrapSnapshot) -> Self {
 35        Self {
 36            transforms: Mutex::new(SumTree::from_item(
 37                Transform::isomorphic(wrap_snapshot.max_point().row() + 1),
 38                &(),
 39            )),
 40        }
 41    }
 42
 43    fn read(&self, wrap_snapshot: WrapSnapshot, edits: Vec<WrapEdit>) -> BlockSnapshot {
 44        self.sync(wrap_snapshot, edits);
 45        BlockSnapshot {}
 46    }
 47
 48    fn write(&mut self, wrap_snapshot: WrapSnapshot, edits: Vec<WrapEdit>) -> BlockMapWriter {
 49        self.sync(wrap_snapshot, edits);
 50        BlockMapWriter(self)
 51    }
 52
 53    fn sync(&self, wrap_snapshot: WrapSnapshot, edits: Vec<WrapEdit>) {
 54        let transforms = self.transforms.lock();
 55        let mut new_transforms = SumTree::new();
 56        let mut cursor = transforms.cursor::<InputRow>();
 57        let mut edits = edits.into_iter().peekable();
 58        while let Some(mut edit) = edits.next() {
 59            new_transforms.push_tree(
 60                cursor.slice(&InputRow(edit.old.start), Bias::Left, &()),
 61                &(),
 62            );
 63
 64            let transform_start = cursor.start().0;
 65            edit.new.start -= edit.old.start - transform_start;
 66            edit.old.start = transform_start;
 67
 68            loop {
 69                if edit.old.end > cursor.start().0 {
 70                    cursor.seek(&InputRow(edit.old.end), Bias::Left, &());
 71                    cursor.next(&());
 72                    let transform_end = cursor.start().0;
 73                    edit.new.end += transform_end - edit.old.end;
 74                    edit.old.end = transform_end;
 75                }
 76
 77                if let Some(next_edit) = edits.peek() {
 78                    if edit.old.end >= next_edit.old.start {
 79                        edit.old.end = cmp::max(next_edit.old.end, edit.old.end);
 80                        edit.new.end += (edit.new.len() as i32 - edit.old.len() as i32) as u32;
 81                        edits.next();
 82                    } else {
 83                        break;
 84                    }
 85                } else {
 86                    break;
 87                }
 88            }
 89
 90            // TODO: process injections
 91
 92            let new_transforms_end = new_transforms.summary().input_rows;
 93            if new_transforms_end < edit.new.end {
 94                new_transforms.push(
 95                    Transform::isomorphic(edit.new.end - new_transforms_end),
 96                    &(),
 97                );
 98            }
 99        }
100        new_transforms.push_tree(cursor.suffix(&()), &());
101    }
102}
103
104impl Transform {
105    fn isomorphic(rows: u32) -> Self {
106        Self {
107            summary: TransformSummary {
108                input_rows: rows,
109                output_rows: rows,
110            },
111        }
112    }
113}
114
115impl sum_tree::Item for Transform {
116    type Summary = TransformSummary;
117
118    fn summary(&self) -> Self::Summary {
119        self.summary
120    }
121}
122
123impl sum_tree::Summary for TransformSummary {
124    type Context = ();
125
126    fn add_summary(&mut self, summary: &Self, _: &()) {
127        self.input_rows += summary.input_rows;
128        self.output_rows += summary.output_rows;
129    }
130}
131
132impl<'a> sum_tree::Dimension<'a, TransformSummary> for InputRow {
133    fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
134        self.0 += summary.input_rows;
135    }
136}
137
138impl<'a> sum_tree::Dimension<'a, TransformSummary> for OutputRow {
139    fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
140        self.0 += summary.output_rows;
141    }
142}