+
+void
+pivot_splits_destroy (struct pivot_splits *ps)
+{
+ if (!ps)
+ return;
+
+ for (size_t i = 0; i < ps->n; i++)
+ {
+ struct pivot_splits_var *psvar = &ps->vars[i];
+ struct pivot_splits_value *psval, *next;
+ HMAP_FOR_EACH_SAFE (psval, next, struct pivot_splits_value, hmap_node,
+ &psvar->values)
+ {
+ value_destroy (&psval->value, psvar->width);
+ hmap_delete (&psvar->values, &psval->hmap_node);
+ free (psval);
+ }
+ hmap_destroy (&psvar->values);
+ }
+ free (ps->vars);
+ free (ps->encoding);
+ free (ps);
+}
+
+static struct pivot_splits_value *
+pivot_splits_value_find (struct pivot_splits_var *psvar,
+ const union value *value)
+{
+ struct pivot_splits_value *psval;
+ HMAP_FOR_EACH_WITH_HASH (psval, struct pivot_splits_value, hmap_node,
+ value_hash (value, psvar->width, 0), &psvar->values)
+ if (value_equal (&psval->value, value, psvar->width))
+ return psval;
+ return NULL;
+}
+
+void
+pivot_splits_new_split (struct pivot_splits *ps, const struct ccase *c)
+{
+ if (!ps)
+ return;
+
+ for (size_t i = ps->n - 1; i < ps->n; i--)
+ {
+ struct pivot_splits_var *psvar = &ps->vars[i];
+ const union value *value = case_data_idx (c, psvar->idx);
+ struct pivot_splits_value *psval = pivot_splits_value_find (psvar, value);
+ if (!psval)
+ {
+ psval = xmalloc (sizeof *psval);
+ hmap_insert (&psvar->values, &psval->hmap_node,
+ value_hash (value, psvar->width, 0));
+ value_clone (&psval->value, value, psvar->width);
+ psval->leaf = pivot_category_create_leaf (
+ psvar->dimension->root,
+ pivot_value_new_value (value, psvar->width, &psvar->format,
+ ps->encoding));
+ }
+
+ ps->dindexes[i] = psval->leaf;
+ }
+}
+
+size_t
+pivot_splits_get_dindexes (const struct pivot_splits *ps, size_t *dindexes)
+{
+ if (!ps)
+ return 0;
+
+ assert (ps->dindexes[0] != SIZE_MAX);
+ for (size_t i = 0; i < ps->n; i++)
+ dindexes[i] = ps->dindexes[i];
+ return ps->n;
+}
+
+void
+pivot_splits_put1 (struct pivot_splits *ps, struct pivot_table *table,
+ size_t idx1, struct pivot_value *value)
+{
+ size_t dindexes[1 + MAX_SPLITS];
+ size_t *p = dindexes;
+ *p++ = idx1;
+ p += pivot_splits_get_dindexes (ps, p);
+ pivot_table_put (table, dindexes, p - dindexes, value);
+}
+
+void
+pivot_splits_put2 (struct pivot_splits *ps, struct pivot_table *table,
+ size_t idx1, size_t idx2, struct pivot_value *value)
+{
+ size_t dindexes[2 + MAX_SPLITS];
+ size_t *p = dindexes;
+ *p++ = idx1;
+ *p++ = idx2;
+ p += pivot_splits_get_dindexes (ps, p);
+ pivot_table_put (table, dindexes, p - dindexes, value);
+}
+
+void
+pivot_splits_put3 (struct pivot_splits *ps, struct pivot_table *table,
+ size_t idx1, size_t idx2, size_t idx3,
+ struct pivot_value *value)
+{
+ size_t dindexes[3 + MAX_SPLITS];
+ size_t *p = dindexes;
+ *p++ = idx1;
+ *p++ = idx2;
+ *p++ = idx3;
+ p += pivot_splits_get_dindexes (ps, p);
+ pivot_table_put (table, dindexes, p - dindexes, value);
+}
+
+void
+pivot_splits_put4 (struct pivot_splits *ps, struct pivot_table *table,
+ size_t idx1, size_t idx2, size_t idx3, size_t idx4,
+ struct pivot_value *value)
+{
+ size_t dindexes[4 + MAX_SPLITS];
+ size_t *p = dindexes;
+ *p++ = idx1;
+ *p++ = idx2;
+ *p++ = idx3;
+ *p++ = idx4;
+ p += pivot_splits_get_dindexes (ps, p);
+ pivot_table_put (table, dindexes, p - dindexes, value);
+}