From: Ben Pfaff Date: Thu, 30 Dec 2021 19:47:17 +0000 (-0800) Subject: freqtabs are per-table X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pspp;a=commitdiff_plain;h=91240a3a96a0ffed8b1bcc4866378b4d865e6f6e freqtabs are per-table --- diff --git a/src/language/stats/ctables.c b/src/language/stats/ctables.c index 268a44692e..dc761ade72 100644 --- a/src/language/stats/ctables.c +++ b/src/language/stats/ctables.c @@ -256,6 +256,9 @@ struct ctables_table struct ctables_chisq *chisq; struct ctables_pairwise *pairwise; + + struct ctables_freqtab **fts; + size_t n_fts; }; struct ctables_var @@ -1379,11 +1382,10 @@ compare_freq_3way (const void *a_, const void *b_, const void *vars_) static bool ctables_execute (struct dataset *ds, struct ctables *ct) { - struct ctables_freqtab **fts = NULL; - size_t n_fts = 0; - size_t allocated_fts = 0; for (size_t i = 0; i < ct->n_tables; i++) { + size_t allocated_fts = 0; + struct ctables_table *t = &ct->tables[i]; struct var_array2 vaa = enumerate_fts (t->axes[PIVOT_AXIS_ROW]); vaa = nest_fts (vaa, enumerate_fts (t->axes[PIVOT_AXIS_COLUMN])); @@ -1401,15 +1403,15 @@ ctables_execute (struct dataset *ds, struct ctables *ct) for (size_t j = 0; j < vaa.n; j++) { - if (n_fts >= allocated_fts) - fts = x2nrealloc (fts, &allocated_fts, sizeof *fts); - struct ctables_freqtab *ft = xmalloc (sizeof *ft); *ft = (struct ctables_freqtab) { .vars = vaa.vas[j], .data = HMAP_INITIALIZER (ft->data), }; - fts[n_fts++] = ft; + + if (t->n_fts >= allocated_fts) + t->fts = x2nrealloc (t->fts, &allocated_fts, sizeof *t->fts); + t->fts[t->n_fts++] = ft; } free (vaa.vas); @@ -1424,83 +1426,99 @@ ctables_execute (struct dataset *ds, struct ctables *ct) { double weight = dict_get_case_weight (dataset_dict (ds), c, &warn_on_invalid); - for (size_t i = 0; i < n_fts; i++) - { - struct ctables_freqtab *ft = fts[i]; - size_t hash = 0; + for (size_t i = 0; i < ct->n_tables; i++) + { + struct ctables_table *t = &ct->tables[i]; - for (size_t j = 0; j < ft->vars.n; j++) + for (size_t j = 0; j < t->n_fts; j++) { - const struct variable *var = ft->vars.vars[j]; - hash = value_hash (case_data (c, var), var_get_width (var), hash); - } + struct ctables_freqtab *ft = t->fts[j]; - struct freq *f; - HMAP_FOR_EACH_WITH_HASH (f, struct freq, node, hash, &ft->data) - { - for (size_t j = 0; j < ft->vars.n; j++) + size_t hash = 0; + + for (size_t k = 0; k < ft->vars.n; k++) { - const struct variable *var = ft->vars.vars[j]; - if (!value_equal (case_data (c, var), &f->values[j], - var_get_width (var))) - goto next_hash_node; + const struct variable *var = ft->vars.vars[k]; + hash = value_hash (case_data (c, var), var_get_width (var), hash); } - f->count += weight; - goto next_ft; + struct freq *f; + HMAP_FOR_EACH_WITH_HASH (f, struct freq, node, hash, &ft->data) + { + for (size_t k = 0; k < ft->vars.n; k++) + { + const struct variable *var = ft->vars.vars[k]; + if (!value_equal (case_data (c, var), &f->values[k], + var_get_width (var))) + goto next_hash_node; + } - next_hash_node: ; - } + f->count += weight; + goto next_ft; - f = xmalloc (table_entry_size (ft->vars.n)); - f->count = weight; - for (size_t j = 0; j < ft->vars.n; j++) - { - const struct variable *var = ft->vars.vars[j]; - value_clone (&f->values[j], case_data (c, var), - var_get_width (var)); - } - hmap_insert (&ft->data, &f->node, hash); + next_hash_node: ; + } - next_ft: ; + f = xmalloc (table_entry_size (ft->vars.n)); + f->count = weight; + for (size_t k = 0; k < ft->vars.n; k++) + { + const struct variable *var = ft->vars.vars[k]; + value_clone (&f->values[k], case_data (c, var), + var_get_width (var)); + } + hmap_insert (&ft->data, &f->node, hash); + + next_ft: ; + } } } casereader_destroy (input); - for (size_t i = 0; i < n_fts; i++) + for (size_t i = 0; i < ct->n_tables; i++) { - struct ctables_freqtab *ft = fts[i]; - ft->sorted = xnmalloc (ft->data.count, sizeof *ft->sorted); - - struct freq *f; - size_t n = 0; - HMAP_FOR_EACH (f, struct freq, node, &ft->data) - ft->sorted[n++] = f; - sort (ft->sorted, ft->data.count, sizeof *ft->sorted, - compare_freq_3way, &ft->vars); + struct ctables_table *t = &ct->tables[i]; + + for (size_t j = 0; j < t->n_fts; j++) + { + struct ctables_freqtab *ft = t->fts[j]; + ft->sorted = xnmalloc (ft->data.count, sizeof *ft->sorted); + + struct freq *f; + size_t n = 0; + HMAP_FOR_EACH (f, struct freq, node, &ft->data) + ft->sorted[n++] = f; + sort (ft->sorted, ft->data.count, sizeof *ft->sorted, + compare_freq_3way, &ft->vars); + } } - for (size_t i = 0; i < n_fts; i++) + for (size_t i = 0; i < ct->n_tables; i++) { - struct ctables_freqtab *ft = fts[i]; - struct freq *f, *next; - HMAP_FOR_EACH_SAFE (f, next, struct freq, node, &ft->data) + struct ctables_table *t = &ct->tables[i]; + + for (size_t j = 0; j < t->n_fts; j++) { - hmap_delete (&ft->data, &f->node); - for (size_t j = 0; j < ft->vars.n; j++) + struct ctables_freqtab *ft = t->fts[j]; + struct freq *f, *next; + HMAP_FOR_EACH_SAFE (f, next, struct freq, node, &ft->data) { - const struct variable *var = ft->vars.vars[j]; - value_destroy (&f->values[j], var_get_width (var)); + hmap_delete (&ft->data, &f->node); + for (size_t k = 0; k < ft->vars.n; k++) + { + const struct variable *var = ft->vars.vars[k]; + value_destroy (&f->values[k], var_get_width (var)); + } + free (f); } - free (f); + hmap_destroy (&ft->data); + free (ft->sorted); + var_array_uninit (&ft->vars); + free (ft); } - hmap_destroy (&ft->data); - free (ft->sorted); - var_array_uninit (&ft->vars); - free (ft); + free (t->fts); } - free (fts); return proc_commit (ds); }