return cnt;
}
\f
-/* How to copy a contiguous range of values between cases. */
-struct copy_map
- {
- size_t src_idx; /* Starting value index in source case. */
- size_t dst_idx; /* Starting value index in target case. */
- size_t cnt; /* Number of values. */
- };
-
-/* How to compact a case. */
-struct dict_compactor
- {
- struct copy_map *maps; /* Array of mappings. */
- size_t map_cnt; /* Number of mappings. */
- };
-
-/* Creates and returns a dict_compactor that can be used to
- compact cases for dictionary D.
-
- Compacting a case eliminates "holes" between values and after
- the last value. (Holes are created by deleting variables.)
-
- All variables are compacted if EXCLUDE_CLASSES is 0, or it may
- contain one or more of (1u << DC_ORDINARY), (1u << DC_SYSTEM),
- or (1u << DC_SCRATCH) to cause the corresponding type of
- variable to be deleted during compaction. */
-struct dict_compactor *
-dict_make_compactor (const struct dictionary *d, unsigned int exclude_classes)
-{
- struct dict_compactor *compactor;
- struct copy_map *map;
- size_t map_allocated;
- size_t value_idx;
- size_t i;
-
- assert ((exclude_classes & ~((1u << DC_ORDINARY)
- | (1u << DC_SYSTEM)
- | (1u << DC_SCRATCH))) == 0);
-
- compactor = xmalloc (sizeof *compactor);
- compactor->maps = NULL;
- compactor->map_cnt = 0;
- map_allocated = 0;
-
- value_idx = 0;
- map = NULL;
- for (i = 0; i < d->var_cnt; i++)
- {
- struct variable *v = d->var[i];
- enum dict_class class = dict_class_from_id (var_get_name (v));
- if (exclude_classes & (1u << class))
- continue;
-
- if (map != NULL && map->src_idx + map->cnt == var_get_case_index (v))
- map->cnt += var_get_value_cnt (v);
- else
- {
- if (compactor->map_cnt == map_allocated)
- compactor->maps = x2nrealloc (compactor->maps, &map_allocated,
- sizeof *compactor->maps);
- map = &compactor->maps[compactor->map_cnt++];
- map->src_idx = var_get_case_index (v);
- map->dst_idx = value_idx;
- map->cnt = var_get_value_cnt (v);
- }
- value_idx += var_get_value_cnt (v);
- }
-
- return compactor;
-}
-
-/* Compacts SRC by copying it to DST according to the scheme in
- COMPACTOR.
-
- Compacting a case eliminates "holes" between values and after
- the last value. (Holes are created by deleting variables.) */
-void
-dict_compactor_compact (const struct dict_compactor *compactor,
- struct ccase *dst, const struct ccase *src)
-{
- size_t i;
-
- for (i = 0; i < compactor->map_cnt; i++)
- {
- const struct copy_map *map = &compactor->maps[i];
- case_copy (dst, map->dst_idx, src, map->src_idx, map->cnt);
- }
-}
-
-/* Destroys COMPACTOR. */
-void
-dict_compactor_destroy (struct dict_compactor *compactor)
-{
- if (compactor != NULL)
- {
- free (compactor->maps);
- free (compactor);
- }
-}
-
/* Returns the SPLIT FILE vars (see cmd_split_file()). Call
dict_get_split_cnt() to determine how many SPLIT FILE vars
there are. Returns a null pointer if and only if there are no