1use super::*;
2
3struct DeltaReplace<'a, V, Attr> {
4 value: &'a V,
5 attr: &'a Attr,
6 delete: usize,
7}
8
9impl<V: DeltaValue, Attr: DeltaAttr> DeltaRope<V, Attr> {
10 pub fn compose(&mut self, other: &Self) {
11 if self.is_empty() {
13 *self = other.clone();
14 return;
15 }
16
17 let mut index = 0;
19
20 let mut push_rest = false;
21 for item in other.iter() {
22 if index >= self.len() {
23 self.push_retain(index - self.len(), Attr::default());
24 push_rest = true;
25 }
26
27 if push_rest {
28 self.push(item.clone());
29 continue;
30 }
31
32 match item {
33 DeltaItem::Retain { len, attr } => {
34 if self.len() < index + len {
35 self.push_retain(index + len - self.len(), Default::default());
36 }
37 if !attr.attr_is_empty() {
38 self.update_attr_in_range(index..index + len, attr);
39 }
40 index += len;
41 }
42 DeltaItem::Replace {
43 value: this_value,
44 attr: this_attr,
45 delete,
46 } => {
47 self._compose_replace(
48 DeltaReplace {
49 value: this_value,
50 attr: this_attr,
51 delete: *delete,
52 },
53 &mut index,
54 );
55 }
56 }
57 }
58
59 }
61
62 pub fn delete(&mut self, mut index: usize, len: usize) {
63 self._compose_replace(
64 DeltaReplace {
65 value: &Default::default(),
66 attr: &Default::default(),
67 delete: len,
68 },
69 &mut index,
70 );
71 }
72
73 fn _compose_replace(
74 &mut self,
75 delta_replace_item @ DeltaReplace {
76 value: this_value,
77 attr: this_attr,
78 delete,
79 }: DeltaReplace<V, Attr>,
80 index: &mut usize,
81 ) {
82 let mut should_insert = this_value.rle_len() > 0;
83 let mut left_del_len = delete;
84 if *index > self.len() {
85 self.push_retain(*index - self.len(), Attr::default());
86 }
87
88 if delete > 0 && *index != self.len() {
89 let range = *index..(*index + left_del_len).min(self.len());
90 let from = self.tree.query::<LengthFinder>(&range.start).unwrap();
91 let to = self.tree.query::<LengthFinder>(&range.end).unwrap();
92 if from.cursor.leaf == to.cursor.leaf {
93 self._replace_on_single_leaf(from, to, left_del_len, delta_replace_item);
94 should_insert = false;
95 left_del_len = 0;
96 } else {
97 self._replace_batch_leaves(from, to, &mut left_del_len);
98 }
99 }
100
101 if left_del_len > 0 || should_insert {
102 let replace = DeltaItem::Replace {
103 value: if should_insert {
104 this_value.clone()
105 } else {
106 Default::default()
107 },
108 attr: if should_insert {
109 this_attr.clone()
110 } else {
111 Default::default()
112 },
113 delete: left_del_len,
114 };
115 self.insert_values(*index, [replace]);
116 }
117
118 *index += this_value.rle_len();
119 }
120
121 fn _replace_batch_leaves(
122 &mut self,
123 from: generic_btree::QueryResult,
124 to: generic_btree::QueryResult,
125 left_del_len: &mut usize,
126 ) {
127 self.tree.update(from.cursor..to.cursor, &mut |item| {
128 if *left_del_len == 0 {
131 return None;
132 }
133
134 match item {
135 DeltaItem::Retain { len, .. } => {
136 assert!(*len <= *left_del_len);
137 *left_del_len -= *len;
138 let diff = -(*len as isize);
139 *item = DeltaItem::Replace {
140 delete: *len,
141 value: Default::default(),
142 attr: Default::default(),
143 };
144 Some(Len {
145 data_len: diff,
146 delta_len: 0,
147 })
148 }
149 DeltaItem::Replace { value, attr, .. } => {
150 if *left_del_len >= value.rle_len() {
151 let diff = value.rle_len() as isize;
152 *left_del_len -= value.rle_len();
153 *value = Default::default();
154 *attr = Default::default();
155 Some(Len {
156 data_len: -diff,
157 delta_len: -diff,
158 })
159 } else {
160 unreachable!()
161 }
162 }
163 }
164 });
165 }
166
167 fn _replace_on_single_leaf(
168 &mut self,
169 from: generic_btree::QueryResult,
170 to: generic_btree::QueryResult,
171 left_del_len: usize,
172 DeltaReplace {
173 value: this_value,
174 attr: this_attr,
175 delete: _,
176 }: DeltaReplace<V, Attr>,
177 ) {
178 self.tree.update_leaf(from.cursor.leaf, |item| match item {
179 DeltaItem::Retain {
180 len: retain_len, ..
181 } => {
182 let start = from.cursor.offset;
183 let end = to.cursor.offset;
184 debug_assert!(end <= *retain_len);
185 let (l, r) = item.update_with_split(start..end, |item| {
186 *item = DeltaItem::Replace {
187 delete: left_del_len,
188 value: this_value.clone(),
189 attr: this_attr.clone(),
190 };
191 });
192
193 (true, l, r)
194 }
195 DeltaItem::Replace { value, delete, .. } => {
196 let start = from.cursor.offset;
197 let end = to.cursor.offset;
198 let value_len = value.rle_len();
199 let value_start = start.min(value_len);
200 let value_end = value_len.min(end);
201 {
202 let left = left_del_len.saturating_sub(value_end - value_start);
206 *delete += left;
207 }
208
209 let (l, r) = item.update_with_split(value_start..value_end, |item| {
210 *item = DeltaItem::Replace {
211 value: this_value.clone(),
212 attr: this_attr.clone(),
213 delete: 0,
214 };
215 });
216
217 (true, l, r)
218 }
219 });
220 }
221}