1const LOWER16: u64 = 0xffff;
9const FACTOR16: u64 = 1 << 16;
10
11fn make_recover(index: usize, offset: usize) -> u64 {
12 index as u64 + (offset as u64) * FACTOR16
13}
14fn recover_index(value: u64) -> usize {
15 (value & LOWER16) as usize
16}
17fn recover_offset(value: u64) -> usize {
18 ((value - (value & LOWER16)) / FACTOR16) as usize
19}
20
21pub const DEL_SIDE: u8 = 8;
23const DEL_BEFORE: u8 = 1;
24const DEL_AFTER: u8 = 2;
25const DEL_ACROSS: u8 = 4;
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
30pub struct MapResult {
31 pub pos: usize,
33 del_info: u8,
34 recover: Option<u64>,
35}
36
37impl MapResult {
38 pub fn deleted(&self) -> bool {
41 self.del_info & DEL_SIDE > 0
42 }
43 pub fn deleted_before(&self) -> bool {
45 self.del_info & (DEL_BEFORE | DEL_ACROSS) > 0
46 }
47 pub fn deleted_after(&self) -> bool {
49 self.del_info & (DEL_AFTER | DEL_ACROSS) > 0
50 }
51 pub fn deleted_across(&self) -> bool {
53 self.del_info & DEL_ACROSS > 0
54 }
55}
56
57#[derive(Debug, Clone, PartialEq, Eq)]
60pub struct StepMap {
61 ranges: Vec<usize>,
62 inverted: bool,
63}
64
65impl StepMap {
66 pub fn new(ranges: Vec<usize>) -> Self {
68 debug_assert!(ranges.len() % 3 == 0);
69 StepMap {
70 ranges,
71 inverted: false,
72 }
73 }
74
75 pub fn identity() -> Self {
77 StepMap {
78 ranges: Vec::new(),
79 inverted: false,
80 }
81 }
82
83 pub fn invert(&self) -> StepMap {
85 StepMap {
86 ranges: self.ranges.clone(),
87 inverted: !self.inverted,
88 }
89 }
90
91 fn recover(&self, value: u64) -> usize {
92 let mut diff: i64 = 0;
93 let index = recover_index(value);
94 if !self.inverted {
95 for i in 0..index {
96 diff += self.ranges[i * 3 + 2] as i64 - self.ranges[i * 3 + 1] as i64;
97 }
98 }
99 (self.ranges[index * 3] as i64 + diff + recover_offset(value) as i64) as usize
100 }
101
102 pub fn map(&self, pos: usize, assoc: i32) -> usize {
105 self.map_inner(pos, assoc).pos
106 }
107
108 pub fn map_result(&self, pos: usize, assoc: i32) -> MapResult {
110 self.map_inner(pos, assoc)
111 }
112
113 fn map_inner(&self, pos: usize, assoc: i32) -> MapResult {
114 let mut diff: i64 = 0;
115 let mut i = 0;
116 while i < self.ranges.len() {
117 let start_raw = self.ranges[i] as i64 - if self.inverted { diff } else { 0 };
118 if start_raw > pos as i64 {
119 break;
120 }
121 let start = start_raw as usize;
122 let old_size = self.ranges[i + if self.inverted { 2 } else { 1 }];
123 let new_size = self.ranges[i + if self.inverted { 1 } else { 2 }];
124 let end = start + old_size;
125 if pos <= end {
126 let side = if old_size == 0 {
127 assoc
128 } else if pos == start {
129 -1
130 } else if pos == end {
131 1
132 } else {
133 assoc
134 };
135 let result =
136 (start as i64 + diff + if side < 0 { 0 } else { new_size as i64 }) as usize;
137 let edge = if assoc < 0 { start } else { end };
138 let recover = if pos == edge {
139 None
140 } else {
141 Some(make_recover(i / 3, pos - start))
142 };
143 let mut del_info = if pos == start {
144 DEL_AFTER
145 } else if pos == end {
146 DEL_BEFORE
147 } else {
148 DEL_ACROSS
149 };
150 let on_edge = if assoc < 0 { pos != start } else { pos != end };
151 if on_edge {
152 del_info |= DEL_SIDE;
153 }
154 return MapResult {
155 pos: result,
156 del_info,
157 recover,
158 };
159 }
160 diff += new_size as i64 - old_size as i64;
161 i += 3;
162 }
163 MapResult {
164 pos: (pos as i64 + diff) as usize,
165 del_info: 0,
166 recover: None,
167 }
168 }
169}
170
171#[derive(Debug, Clone, Default)]
174pub struct Mapping {
175 maps: Vec<StepMap>,
176 mirror: Vec<usize>,
178}
179
180impl Mapping {
181 pub fn new() -> Self {
183 Mapping::default()
184 }
185
186 pub fn len(&self) -> usize {
188 self.maps.len()
189 }
190
191 pub fn is_empty(&self) -> bool {
193 self.maps.is_empty()
194 }
195
196 pub fn maps(&self) -> &[StepMap] {
198 &self.maps
199 }
200
201 pub fn append_map(&mut self, map: StepMap) {
203 self.maps.push(map);
204 }
205
206 pub fn append_map_mirrored(&mut self, map: StepMap, mirrors: usize) {
208 self.maps.push(map);
209 let n = self.maps.len() - 1;
210 self.mirror.push(mirrors);
211 self.mirror.push(n);
212 }
213
214 fn get_mirror(&self, n: usize) -> Option<usize> {
215 let mut i = 0;
216 while i < self.mirror.len() {
217 if self.mirror[i] == n {
218 return Some(self.mirror[i + 1]);
219 }
220 if self.mirror[i + 1] == n {
221 return Some(self.mirror[i]);
222 }
223 i += 2;
224 }
225 None
226 }
227
228 pub fn map(&self, pos: usize, assoc: i32) -> usize {
230 let mut pos = pos;
231 let mut i = 0;
232 while i < self.maps.len() {
233 pos = self.maps[i].map(pos, assoc);
234 i += 1;
235 }
236 pos
237 }
238
239 pub fn map_result(&self, pos: usize, assoc: i32) -> MapResult {
242 let mut del_info = 0u8;
243 let mut pos = pos;
244 let mut i = 0;
245 while i < self.maps.len() {
246 let result = self.maps[i].map_result(pos, assoc);
247 if let Some(rec) = result.recover {
248 if let Some(corr) = self.get_mirror(i) {
249 if corr > i && corr < self.maps.len() {
250 i = corr;
251 pos = self.maps[corr].recover(rec);
252 i += 1;
253 continue;
254 }
255 }
256 }
257 del_info |= result.del_info;
258 pos = result.pos;
259 i += 1;
260 }
261 MapResult {
262 pos,
263 del_info,
264 recover: None,
265 }
266 }
267}