Remove a bunch more unneeded index fields.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 6 Apr 2025 19:11:34 +0000 (12:11 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 6 Apr 2025 19:11:34 +0000 (12:11 -0700)
rust/pspp/src/output/pivot/mod.rs
rust/pspp/src/output/pivot/output.rs

index f90beb2a55c7aaaf042e6b94eb79e5fc34a90289..ed18ff50819c2c91ad78cd5ebeb058cb58b897e7 100644 (file)
@@ -72,6 +72,7 @@ use color::{palette::css::TRANSPARENT, AlphaColor, Rgba8, Srgb};
 use encoding_rs::UTF_8;
 use enum_iterator::Sequence;
 use enum_map::{enum_map, Enum, EnumMap};
+use itertools::Itertools;
 use look_xml::TableProperties;
 use quick_xml::{de::from_str, DeError};
 use serde::{de::Visitor, Deserialize};
@@ -325,11 +326,6 @@ impl PivotTable {
 /// data.)
 #[derive(Clone, Debug)]
 pub struct Dimension {
-    /// The index within the dimension.
-    ///
-    /// This [Dimension] is `pivot_table.dimensions[top_index]`.
-    top_index: usize,
-
     /// Hierarchy of categories within the dimension.  The groups and categories
     /// are sorted in the order that should be used for display.  This might be
     /// different from the original order produced for output if the user
@@ -341,17 +337,16 @@ pub struct Dimension {
 
     ///  All of the leaves reachable via the root.
     ///
-    ///  The indexing for presentation_leaves is presentation order, thus
-    ///  `presentation_leaves[i]->presentation_index == i`.  This order is the
-    ///  same as would be produced by an in-order traversal of the groups.  It
-    ///  is the order into which the user reordered or sorted the categories.
-    ///
     ///  The indexing for `data_leaves` is that used for `idx` in [Cell], thus
     ///  `data_leaves[i]->data_index == i`.  This might differ from what an
     ///  in-order traversal of `root` would yield, if the user reordered
     ///  categories.
     data_leaves: Vec<Arc<Leaf>>,
-    presentation_leaves: Vec<Arc<Leaf>>,
+
+    /// Ordering of leaves for presentation.
+    ///
+    /// This is a permutation of `0..n` where `n` is the number of leaves.
+    presentation_order: Vec<usize>,
 
     /// Display.
     hide_all_labels: bool,
@@ -419,10 +414,9 @@ impl DimensionBuilder {
         self.root.assign_label_depth(label_position, true);
         let root = self.root.build(label_position, None, &mut leaves);
         Dimension {
-            top_index,
             root,
-            data_leaves: leaves.clone(),
-            presentation_leaves: leaves,
+            presentation_order: (0..leaves.len()).collect(),
+            data_leaves: leaves,
             hide_all_labels: self.hide_all_labels,
         }
     }
@@ -570,9 +564,6 @@ impl CategoryBuilder {
                     name,
                     label_depth,
                     extra_depth,
-                    group_index,
-                    data_index: leaves.len(),
-                    presentation_index: leaves.len(),
                     class,
                 });
                 leaves.push(leaf.clone());
@@ -694,11 +685,6 @@ pub struct Leaf {
     label_depth: usize,
     extra_depth: usize,
 
-    /// `parent.children[group_index]` is this.
-    group_index: usize,
-    data_index: usize,
-    presentation_index: usize,
-
     /// Default format for values in this category.
     class: Option<Class>,
 }
@@ -710,9 +696,6 @@ impl Leaf {
             name: Box::new(name),
             label_depth: 0,
             extra_depth: 0,
-            group_index: 0,
-            data_index: 0,
-            presentation_index: 0,
             class: None,
         }
     }
@@ -1600,11 +1583,13 @@ impl PivotTable {
         presentation_indexes: EnumMap<Axis3, &[usize]>,
     ) -> SmallVec<[usize; 4]> {
         let mut data_indexes = SmallVec::from_elem(0, self.dimensions.len());
-        for axis in enum_iterator::all::<Axis3>() {
-            for (i, dimension) in self.axis_dimensions(axis).enumerate() {
-                let pindex = presentation_indexes[axis][i];
-                data_indexes[dimension.top_index] =
-                    dimension.presentation_leaves[pindex].data_index;
+        for (axis, presentation_indexes) in presentation_indexes {
+            for (&dim_index, &pindex) in self.axes[axis]
+                .dimensions
+                .iter()
+                .zip(presentation_indexes.iter())
+            {
+                data_indexes[dim_index] = self.dimensions[dim_index].presentation_order[pindex];
             }
         }
         data_indexes
@@ -1644,7 +1629,8 @@ impl PivotTable {
         self.axes[axis]
             .dimensions
             .iter()
-            .map(|index| &self.dimensions[*index])
+            .copied()
+            .map(|index| &self.dimensions[index])
     }
 
     fn find_dimension(&self, dim_index: usize) -> Option<(Axis3, usize)> {
index 0f8d7584796bbb3a74d7200c394edd1d99f47e90..f094fcd3b6211d8de712af5f690589c3ea8ddbb7 100644 (file)
@@ -348,7 +348,7 @@ fn find_category<'a>(
     mut row_ofs: usize,
 ) -> Option<Category> {
     let index = indexes[dim_index];
-    let mut c = Category::Leaf(Arc::clone(&d.presentation_leaves[index]));
+    let mut c = Category::Leaf(Arc::clone(&d.data_leaves[d.presentation_order[index]]));
     while row_ofs != c.extra_depth() {
         row_ofs = row_ofs.checked_sub(1 + c.extra_depth())?;
         c = Category::Group(Arc::clone(&c.parent()?));