1use alloc::{
2 rc::Rc,
3 string::{String, ToString},
4 vec::Vec,
5};
6use hashbrown::HashMap;
7
8use crate::types::CyclingCounter;
9use crate::utils::utils_fns::{n_to_base62, pull_n, push_n, push_n_add};
10use crate::{CellProps, IndexCell, MaxMap, TableCell, str_err};
11
12#[derive(Debug, Clone)]
13pub struct Index {
14 pub iid_to_row: HashMap<Rc<str>, usize>,
15 pub cells: Vec<IndexCell>,
16 pub iid_ctr: CyclingCounter,
17 pub empty_par: Rc<str>,
18}
19
20impl Index {
21 pub(crate) fn new() -> Self {
22 Index {
23 iid_to_row: HashMap::new(),
24 cells: Vec::new(),
25 iid_ctr: CyclingCounter::new(),
26 empty_par: Rc::from("".to_string()),
27 }
28 }
29
30 pub(crate) fn reset(&mut self) {
32 self.iid_to_row.clear();
33 self.cells.clear();
34 self.iid_ctr = CyclingCounter::new();
35 }
36
37 pub(crate) fn clone_props(&self, row: &usize) -> Option<CellProps> {
39 self.cells.get(*row).and_then(|cell| cell.props.clone())
40 }
41
42 pub(crate) fn clone_table_props(&self, row: &usize, col: &usize) -> Option<CellProps> {
44 self.cells.get(*row).and_then(|icell| {
45 icell
46 .vals
47 .get(col)
48 .and_then(|table_cell| table_cell.props.clone())
49 })
50 }
51
52 pub(crate) fn add_rows_just_push_hm(&mut self, sorted_seq: &[usize]) {
55 for (_, row) in self.iid_to_row.iter_mut() {
57 *row = push_n(*row, &sorted_seq);
58 }
59 }
60
61 pub(crate) fn del_rows_just_pull_hm(&mut self, sorted_seq: &[usize]) {
64 for (_, row) in self.iid_to_row.iter_mut() {
66 *row = pull_n(*row, sorted_seq);
67 }
68 }
69
70 #[inline(always)]
72 pub(crate) fn add_row(&mut self, pos: usize, iid: Rc<str>, cell: IndexCell) {
73 self.iid_to_row.insert(iid, pos);
74 self.cells.insert(pos, cell);
75 }
76
77 #[inline(always)]
79 pub(crate) fn push_row(&mut self, pos: usize, iid: Rc<str>, cell: IndexCell) {
80 self.iid_to_row.insert(iid, pos);
81 self.cells.push(cell);
82 }
83
84 pub(crate) fn add_rows(&mut self, to_add: Vec<(usize, IndexCell)>) {
86 for (_, row) in self.iid_to_row.iter_mut() {
88 *row = push_n_add(*row, &to_add);
89 }
90 for (pos, cell) in to_add.into_iter() {
92 self.iid_to_row.insert(cell.iid.clone(), pos);
93 self.cells.insert(pos, cell);
94 }
95 }
96
97 pub(crate) fn del_rows(
99 &mut self,
100 sorted_seq: &[usize],
101 ) -> Result<Vec<(usize, IndexCell)>, String> {
102 let largest_pos = *sorted_seq
103 .last()
104 .ok_or_else(|| str_err!("To delete is empty."))?;
105 if largest_pos >= self.cells.len() {
106 return Err(str_err!(
107 "Deletion pos: {} out of bounds of index len: {}",
108 largest_pos,
109 self.cells.len()
110 ));
111 }
112 let mut removed = Vec::with_capacity(sorted_seq.len());
113 for (i, &pos) in sorted_seq.iter().enumerate() {
114 let cell = self.cells.remove(pos - i);
115 self.iid_to_row.remove(&cell.iid);
116 removed.push((pos, cell));
117 }
118 for (_, pos) in self.iid_to_row.iter_mut() {
120 *pos = pull_n(*pos, sorted_seq);
121 }
122 Ok(removed)
123 }
124
125 pub(crate) fn move_rows(&mut self, full_new_to_old: &[usize]) -> Result<(), String> {
126 let n = self.cells.len();
127 if n == 0 {
128 return Ok(());
129 }
130 if full_new_to_old.len() != n {
131 return Err(str_err!(
132 "move_rows: length mismatch (got {}, expected {})",
133 full_new_to_old.len(),
134 n
135 ));
136 }
137
138 #[cfg(any(debug_assertions, feature = "safety"))]
139 {
140 use alloc::vec;
141
142 let mut seen = vec![false; n];
143 for &old_idx in full_new_to_old {
144 if old_idx >= n || seen[old_idx] {
145 return Err(str_err!("Mapping error: invalid old index {}", old_idx));
146 }
147 seen[old_idx] = true;
148 }
149 }
150
151 let mut old_cells = core::mem::take(&mut self.cells)
152 .into_iter()
153 .map(Some)
154 .collect::<Vec<_>>();
155
156 self.cells = Vec::with_capacity(n);
157
158 for (new_idx, &old_idx) in full_new_to_old.iter().enumerate() {
159 let cell = old_cells
160 .get_mut(old_idx)
161 .and_then(Option::take)
162 .ok_or_else(|| str_err!("Mapping error: invalid or duplicate index {}", old_idx))?;
163
164 if let Some(row) = self.iid_to_row.get_mut(&cell.iid) {
165 *row = new_idx; }
167 self.cells.push(cell);
168 }
169
170 Ok(())
171 }
172
173 pub(crate) fn add_cols(
175 &mut self,
176 to_add: Option<Vec<(usize, Vec<(usize, TableCell)>)>>,
177 sorted_seq: &[usize],
178 ) {
179 for icell in self.cells.iter_mut() {
181 let index_row_vals = &mut icell.vals;
182 index_row_vals.hm = index_row_vals
183 .hm
184 .drain()
185 .map(|(k, v)| (push_n(k, sorted_seq), v))
186 .collect();
187 index_row_vals.maxk = index_row_vals.maxk.map(|max| push_n(max, sorted_seq));
188 }
189
190 if let Some(to_add) = to_add {
192 for (colk, rows) in to_add {
193 for (rowk, val) in rows {
194 if let Some(row) = self.cells.get_mut(rowk) {
195 let index_row_vals: &mut MaxMap<TableCell> = &mut row.vals;
196 index_row_vals.insert(colk, val);
197 }
198 }
199 }
200 }
201 }
202
203 pub(crate) fn del_cols(
204 &mut self,
205 sorted_seq: &[usize],
206 ) -> Vec<(usize, Vec<(usize, TableCell)>)> {
207 let mut removed: Vec<(usize, Vec<(usize, TableCell)>)> = Vec::new();
208
209 for (rowk, icell) in self.cells.iter_mut().enumerate() {
211 let mut row_removed: Vec<(usize, TableCell)> = Vec::new();
212 let mut redo_maxk = false;
213 let row = &mut icell.vals;
214
215 for &colk in sorted_seq {
217 if let Some(val) = row.hm.remove(&colk) {
218 row_removed.push((colk, val));
219 if row.maxk == Some(colk) {
220 redo_maxk = true;
221 }
222 }
223 }
224
225 if !row_removed.is_empty() {
227 removed.push((rowk, row_removed));
228 }
229
230 row.hm = row
231 .hm
232 .drain()
233 .map(|(k, v)| (pull_n(k, sorted_seq), v))
234 .collect();
235
236 if redo_maxk {
237 let mut new_maxk = None;
238 for k in (0..row.maxk.unwrap_or(0)).rev() {
239 if row.hm.contains_key(&k) {
240 new_maxk = Some(k);
241 break;
242 }
243 }
244 row.maxk = new_maxk;
245 } else {
246 row.maxk = row.maxk.map(|k| pull_n(k, sorted_seq));
247 }
248 }
249
250 removed
251 }
252
253 pub(crate) fn move_cols(&mut self, full_old_to_new: &[usize]) {
254 for icell in self.cells.iter_mut() {
255 let max_map = &mut icell.vals;
256 if max_map.is_empty() {
257 continue;
258 }
259 let mut new_hm: HashMap<usize, TableCell> = HashMap::new();
260 let mut max: usize = 0;
261 for (old_pos, new_pos) in full_old_to_new.iter().enumerate() {
262 if let Some(cell) = max_map.hm.remove(&old_pos) {
263 new_hm.insert(*new_pos, cell);
264 if *new_pos > max {
265 max = *new_pos;
266 }
267 }
268 }
269 max_map.hm = new_hm;
270 max_map.maxk = Some(max);
271 }
272 }
273
274 #[inline]
275 pub(crate) fn new_iid(&mut self) -> Result<String, String> {
276 let mut iid = n_to_base62(
277 self.iid_ctr
278 .next()
279 .ok_or_else(|| str_err!("Cycling counter should never end"))?,
280 );
281 if self.iid_to_row.contains_key(iid.as_str()) {
282 let mut cycles: usize = 0;
283 while self.iid_to_row.contains_key(iid.as_str()) {
284 if cycles == usize::MAX {
285 return Err(str_err!("Row limit reached."));
286 }
287 iid = n_to_base62(
288 self.iid_ctr
289 .next()
290 .ok_or_else(|| str_err!("Cycling counter should never end"))?,
291 );
292 cycles = cycles.saturating_add(1);
293 }
294 }
295 Ok(iid)
296 }
297}