give CTABLES its own freq structure
authorBen Pfaff <blp@cs.stanford.edu>
Fri, 31 Dec 2021 00:43:29 +0000 (16:43 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 13 Mar 2022 23:56:02 +0000 (16:56 -0700)
src/language/stats/ctables.c

index 333b8f8c5413008adb2ee56195f212141a3d7741..7a18ac5f134e4768f1cc6fdb939d5c16b4f95ee6 100644 (file)
@@ -24,7 +24,6 @@
 #include "language/lexer/format-parser.h"
 #include "language/lexer/lexer.h"
 #include "language/lexer/variable-parser.h"
-#include "language/stats/freq.h"
 #include "libpspp/array.h"
 #include "libpspp/assertion.h"
 #include "libpspp/hmap.h"
@@ -1339,19 +1338,33 @@ enumerate_fts (const struct ctables_axis *a)
   NOT_REACHED ();
 }
 
+struct ctables_freq
+  {
+    struct hmap_node node;      /* Element in hash table. */
+    double count;
+    union value values[];      /* The value. */
+  };
+
+static struct ctables_freq *
+ctables_freq_allocate (size_t n_values)
+{
+  struct ctables_freq *f;
+  return xmalloc (sizeof *f + n_values * sizeof *f->values);
+}
+
 struct ctables_freqtab
   {
     struct var_array vars;
-    struct hmap data;           /* Contains "struct freq"s. */
-    struct freq **sorted;
+    struct hmap data;           /* Contains "struct ctables_freq"s. */
+    struct ctables_freq **sorted;
   };
 
 static int
-compare_freq_3way (const void *a_, const void *b_, const void *vars_)
+ctables_freq_compare_3way (const void *a_, const void *b_, const void *vars_)
 {
   const struct var_array *vars = vars_;
-  struct freq *const *a = a_;
-  struct freq *const *b = b_;
+  struct ctables_freq *const *a = a_;
+  struct ctables_freq *const *b = b_;
 
   for (size_t i = 0; i < vars->n; i++)
     {
@@ -1360,7 +1373,6 @@ compare_freq_3way (const void *a_, const void *b_, const void *vars_)
       if (cmp)
         return cmp;
     }
-  
   return 0;
 }
 
@@ -1442,8 +1454,8 @@ ctables_execute (struct dataset *ds, struct ctables *ct)
                   hash = value_hash (case_data (c, var), var_get_width (var), hash);
                 }
 
-              struct freq *f;
-              HMAP_FOR_EACH_WITH_HASH (f, struct freq, node, hash, &ft->data)
+              struct ctables_freq *f;
+              HMAP_FOR_EACH_WITH_HASH (f, struct ctables_freq, node, hash, &ft->data)
                 {
                   for (size_t k = 0; k < ft->vars.n; k++)
                     {
@@ -1459,7 +1471,7 @@ ctables_execute (struct dataset *ds, struct ctables *ct)
                 next_hash_node: ;
                 }
 
-              f = xmalloc (table_entry_size (ft->vars.n));
+              f = ctables_freq_allocate (ft->vars.n);
               f->count = weight;
               for (size_t k = 0; k < ft->vars.n; k++)
                 {
@@ -1487,20 +1499,20 @@ ctables_execute (struct dataset *ds, struct ctables *ct)
           struct ctables_freqtab *ft = t->fts[j];
           ft->sorted = xnmalloc (ft->data.count, sizeof *ft->sorted);
 
-          struct freq *f;
+          struct ctables_freq *f;
           size_t n = 0;
-          HMAP_FOR_EACH (f, struct freq, node, &ft->data)
+          HMAP_FOR_EACH (f, struct ctables_freq, node, &ft->data)
             ft->sorted[n++] = f;
           assert (n == ft->data.count);
           sort (ft->sorted, n, sizeof *ft->sorted,
-                compare_freq_3way, &ft->vars);
+                ctables_freq_compare_3way, &ft->vars);
 
           struct pivot_category **groups = xnmalloc (ft->vars.n,
                                                      sizeof *groups);
           for (size_t k = 0; k < n; k++)
             {
-              struct freq *prev = k > 0 ? ft->sorted[k - 1] : NULL;
-              struct freq *f = ft->sorted[k];
+              struct ctables_freq *prev = k > 0 ? ft->sorted[k - 1] : NULL;
+              struct ctables_freq *f = ft->sorted[k];
 
               size_t n_common = 0;
               if (prev)
@@ -1548,8 +1560,8 @@ ctables_execute (struct dataset *ds, struct ctables *ct)
       for (size_t j = 0; j < t->n_fts; j++)
         {
           struct ctables_freqtab *ft = t->fts[j];
-          struct freq *f, *next;
-          HMAP_FOR_EACH_SAFE (f, next, struct freq, node, &ft->data)
+          struct ctables_freq *f, *next;
+          HMAP_FOR_EACH_SAFE (f, next, struct ctables_freq, node, &ft->data)
             {
               hmap_delete (&ft->data, &f->node);
               for (size_t k = 0; k < ft->vars.n; k++)