1use std::collections::BTreeMap;
2
3use crate::lib::{job, job::config::ConfigGetSetup};
4
5pub fn engine_step3_data_sort<'a>(
10 sort_cfg: &job::ValidSortByConfig,
11 item_cfg: &job::ValidColumnItemConfig,
12 table: &'a mut job::ValidResultMainTab, ) -> &'a mut job::ValidResultMainTab {
14 if table.rows.is_empty() {
16 return table; }
18
19 let is_flat = match item_cfg.list {
21 job::ModeListForValidColumnItem::Flat => true,
22 job::ModeListForValidColumnItem::None => true,
23 job::ModeListForValidColumnItem::Tree => false,
24 };
25
26 let queries = sort_cfg.get();
28
29 if is_flat {
30 table.rows.sort_by(|a, b| queries.compare(a, b));
34 } else {
35 let mut tree_map: BTreeMap<usize, Vec<usize>> = BTreeMap::new();
40
41 for (i, row) in table.rows.iter().enumerate() {
42 let parent_id = row.node.id_path.last().copied().unwrap_or(0);
45 tree_map.entry(parent_id).or_default().push(i);
46 }
47
48 for indices in tree_map.values_mut() {
50 indices.sort_by(|&a, &b| queries.compare(&table.rows[a], &table.rows[b]));
51 }
52
53 let mut root_indices = tree_map.remove(&0).unwrap_or_default();
55
56 root_indices.sort_by(|&a, &b| queries.compare(&table.rows[a], &table.rows[b]));
58
59 let mut flat_indices = Vec::with_capacity(table.rows.len());
61 flatten(&root_indices, &tree_map, &table.rows, &mut flat_indices);
62
63 let total_rows = table.rows.len(); let old_rows = std::mem::replace(&mut table.rows, Vec::with_capacity(total_rows)); let mut temp_rows: Vec<Option<job::ValidResultMainRow>> = old_rows.into_iter().map(Some).collect();
68
69 for idx in flat_indices {
70 if let Some(row) = temp_rows[idx].take() {
71 table.rows.push(row);
72 }
73 }
74 }
75 table
76}
77
78fn flatten(
80 indices: &[usize],
81 tree_map: &BTreeMap<usize, Vec<usize>>,
82 rows: &[job::ValidResultMainRow],
83 out: &mut Vec<usize>,
84) {
85 for &idx in indices {
86 out.push(idx);
87
88 let my_id = rows[idx].node.id_self; if let Some(children) = tree_map.get(&my_id) {
92 flatten(children, tree_map, rows, out);
93 }
94 }
95}