- for (i = 0; i < arc->var_cnt; i++)
- hsh_destroy (arc->src_values[i]);
- free (arc->src_values);
- }
- pool_destroy (arc->src_values_pool);
-}
-
-\f
-/* AUTORECODE transformation. */
-
-static void
-recode (const struct autorecode_pgm *arc)
-{
- struct autorecode_trns *trns;
- size_t i;
-
- trns = pool_create_container (struct autorecode_trns, pool);
- trns->specs = pool_nalloc (trns->pool, arc->var_cnt, sizeof *trns->specs);
- trns->spec_cnt = arc->var_cnt;
- for (i = 0; i < arc->var_cnt; i++)
- {
- struct arc_spec *spec = &trns->specs[i];
- void *const *p = hsh_sort (arc->src_values[i]);
- int count = hsh_count (arc->src_values[i]);
- int j;
-
- spec->src = arc->src_vars[i];
- spec->dest = arc->dst_vars[i];
-
- if (arc->src_vars[i]->type == ALPHA)
- spec->items = hsh_create (2 * count, compare_alpha_value,
- hash_alpha_value, NULL, arc->src_vars[i]);
- else
- spec->items = hsh_create (2 * count, compare_numeric_value,
- hash_numeric_value, NULL, NULL);
-
- for (j = 0; *p; p++, j++)
- {
- struct arc_item *item = pool_alloc (trns->pool, sizeof *item);
- union value *vp = *p;
-
- if (arc->src_vars[i]->type == NUMERIC)
- item->from.f = vp->f;
- else
- item->from.c = pool_clone (trns->pool, vp->c,
- arc->src_vars[i]->width);
- item->to = arc->direction == ASCENDING ? j + 1 : count - j;
- hsh_force_insert (spec->items, item);
- }
- }
- add_transformation (autorecode_trns_proc, autorecode_trns_free, trns);
-}
-
-/* Executes an AUTORECODE transformation. */
-static int
-autorecode_trns_proc (void *trns_, struct ccase *c, int case_idx UNUSED)
-{
- struct autorecode_trns *trns = trns_;
- size_t i;
-
- for (i = 0; i < trns->spec_cnt; i++)
- {
- struct arc_spec *spec = &trns->specs[i];
- struct arc_item *item;
- union value v;
-
- if (spec->src->type == NUMERIC)
- v.f = case_num (c, spec->src->fv);
- else
- v.c = (char *) case_str (c, spec->src->fv);
- item = hsh_force_find (spec->items, &v);
-
- case_data_rw (c, spec->dest->fv)->f = item->to;
+ for (i = 0; i < arc->n_specs; i++)
+ {
+ struct arc_spec *spec = &arc->specs[i];
+ int width = var_get_width (spec->src);
+ struct arc_item *item, *next;
+
+ HMAP_FOR_EACH_SAFE (item, next, struct arc_item, hmap_node,
+ &spec->items)
+ {
+ value_destroy (&item->from, width);
+ hmap_delete (&spec->items, &item->hmap_node);
+ free (item);
+ }
+ hmap_destroy (&spec->items);
+ }
+ free (arc->specs);
+ free (arc);