+static struct ctables_subtable *
+ctables_subtable_insert (struct ctables_table *t, struct ctables_freq *f)
+{
+ size_t hash = 0;
+ for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++)
+ {
+ size_t idx = f->axes[a].vaa_idx;
+ const struct var_array *va = &t->vaas[a].vas[idx];
+ hash = hash_int (idx, hash);
+ for (size_t i = 0; i < va->n; i++)
+ if (i != va->scale_idx && i != va->subtable_idx)
+ hash = value_hash (&f->axes[a].values[i],
+ var_get_width (va->vars[i]), hash);
+ }
+
+ struct ctables_subtable *st;
+ HMAP_FOR_EACH_WITH_HASH (st, struct ctables_subtable, node, hash, &t->subtables)
+ {
+ const struct ctables_freq *stf = st->example;
+ for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++)
+ {
+ size_t idx = f->axes[a].vaa_idx;
+ if (idx != stf->axes[a].vaa_idx)
+ goto not_equal;
+
+ const struct var_array *va = &t->vaas[a].vas[idx];
+ for (size_t i = 0; i < va->n; i++)
+ if (i != va->scale_idx && i != va->subtable_idx
+ && !value_equal (&stf->axes[a].values[i],
+ &f->axes[a].values[i],
+ var_get_width (va->vars[i])))
+ goto not_equal;
+ }
+
+ return st;
+
+ not_equal: ;
+ }
+
+ st = xmalloc (sizeof *st);
+ *st = (struct ctables_subtable) { .example = f };
+ hmap_insert (&t->subtables, &st->node, hash);
+ return st;
+}
+