work on docs
[pspp] / src / language / stats / ctables.c
index 15c45b3042f29374bb9f745d7d089abdc97131a6..a573afaad1ba99075265128c73a58b47fae3c557 100644 (file)
@@ -109,7 +109,7 @@ struct ctables_domain
 
     const struct ctables_cell *example;
 
-    int sequence;
+    size_t sequence;
     double d_valid;             /* Dictionary weight. */
     double d_count;
     double d_total;
@@ -3311,6 +3311,25 @@ ctables_cell_compare_3way (const void *a_, const void *b_, const void *aux_)
   return 0;
 }
 
+static int
+ctables_cell_compare_leaf_3way (const void *a_, const void *b_,
+                                const void *aux UNUSED)
+{
+  struct ctables_cell *const *ap = a_;
+  struct ctables_cell *const *bp = b_;
+  const struct ctables_cell *a = *ap;
+  const struct ctables_cell *b = *bp;
+
+  for (enum pivot_axis_type axis = 0; axis < PIVOT_N_AXES; axis++)
+    {
+      int al = a->axes[axis].leaf;
+      int bl = b->axes[axis].leaf;
+      if (al != bl)
+        return al > bl ? 1 : -1;
+    }
+  return 0;
+}
+
 /* Algorithm:
 
    For each row:
@@ -4412,7 +4431,7 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t)
               {
                 struct ctables_section *s = &t->sections[j];
                 sections[n_sections++] = s;
-                n_total_cells += s->cells.count;
+                n_total_cells += hmap_count (&s->cells);
 
                 size_t depth = s->nests[a]->n;
                 max_depth = MAX (depth, max_depth);
@@ -4436,6 +4455,24 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t)
           struct ctables_cell_sort_aux aux = { .nest = nest, .a = a };
           sort (sorted, n_sorted, sizeof *sorted, ctables_cell_compare_3way, &aux);
 
+#if 0
+          if (a == PIVOT_AXIS_ROW)
+            {
+              size_t ids[N_CTDTS];
+              memset (ids, 0, sizeof ids);
+              for (size_t j = 0; j < n_sorted; j++)
+                {
+                  struct ctables_cell *cell = sorted[j];
+                  for (enum ctables_domain_type dt = 0; dt < N_CTDTS; dt++)
+                    {
+                      struct ctables_domain *domain = cell->domains[dt];
+                      if (!domain->sequence)
+                        domain->sequence = ++ids[dt];
+                    }
+                }
+            }
+#endif
+
 #if 0
           for (size_t j = 0; j < n_sorted; j++)
             {
@@ -4517,19 +4554,6 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t)
               struct ctables_cell *cell = sorted[j];
               struct ctables_cell *prev = j > 0 ? sorted[j - 1] : NULL;
 
-              struct ctables_domain *domain = cell->domains[CTDT_SUBTABLE];
-              if (!domain->sequence)
-                {
-                  static int x;
-                  domain->sequence = ++x;
-                }
-              domain = cell->domains[CTDT_TABLE];
-              if (!domain->sequence)
-                {
-                  static int x;
-                  domain->sequence = ++x;
-                }
-
               size_t n_common = 0;
               if (j > 0)
                 {
@@ -4606,6 +4630,40 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t)
         }
     }
 
+  {
+    size_t n_total_cells = 0;
+    for (size_t j = 0; j < t->n_sections; j++)
+      n_total_cells += hmap_count (&t->sections[j].cells);
+
+    struct ctables_cell **sorted = xnmalloc (n_total_cells, sizeof *sorted);
+    size_t n_sorted = 0;
+    for (size_t j = 0; j < t->n_sections; j++)
+      {
+        const struct ctables_section *s = &t->sections[j];
+        struct ctables_cell *cell;
+        HMAP_FOR_EACH (cell, struct ctables_cell, node, &s->cells)
+          if (!cell->hide)
+            sorted[n_sorted++] = cell;
+      }
+    assert (n_sorted <= n_total_cells);
+    sort (sorted, n_sorted, sizeof *sorted, ctables_cell_compare_leaf_3way,
+          NULL);
+    size_t ids[N_CTDTS];
+    memset (ids, 0, sizeof ids);
+    for (size_t j = 0; j < n_sorted; j++)
+      {
+        struct ctables_cell *cell = sorted[j];
+        for (enum ctables_domain_type dt = 0; dt < N_CTDTS; dt++)
+          {
+            struct ctables_domain *domain = cell->domains[dt];
+            if (!domain->sequence)
+              domain->sequence = ++ids[dt];
+          }
+      }
+
+    free (sorted);
+  }
+
   for (size_t i = 0; i < t->n_sections; i++)
     {
       struct ctables_section *s = &t->sections[i];