/* PSPP - a program for statistical analysis.
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2009, 2010 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
-#include <data/variable.h>
-#include <data/value.h>
-#include <libpspp/compiler.h>
+
+#include "language/stats/freq.h"
#include <stdlib.h>
-#include "freq.h"
+#include "data/variable.h"
+#include "data/value.h"
+#include "libpspp/array.h"
+#include "libpspp/compiler.h"
-int
-compare_freq ( const void *_f1, const void *_f2, const void *_var)
+void
+freq_hmap_destroy (struct hmap *hmap, int width)
{
- const struct freq *f1 = _f1;
- const struct freq *f2 = _f2;
- const struct variable *var = _var;
+ struct freq *f, *next;
- return compare_values_short (f1->value, f2->value, var );
+ HMAP_FOR_EACH_SAFE (f, next, struct freq, hmap_node, hmap)
+ {
+ value_destroy (&f->value, width);
+ hmap_delete (hmap, &f->hmap_node);
+ free (f);
+ }
+ hmap_destroy (hmap);
}
-unsigned int
-hash_freq (const void *_f, const void *var)
+struct freq *
+freq_hmap_search (struct hmap *hmap,
+ const union value *value, int width, size_t hash)
{
- const struct freq *f = _f;
+ struct freq *f;
+
+ HMAP_FOR_EACH_WITH_HASH (f, struct freq, hmap_node, hash, hmap)
+ if (value_equal (value, &f->value, width))
+ return f;
- return hash_value_short (f->value, var);
+ return NULL;
}
-/* Free function to be used on FR whose value parameter has been copied */
-void
-free_freq_mutable_hash (void *fr, const void *var UNUSED)
+struct freq *
+freq_hmap_insert (struct hmap *hmap,
+ const union value *value, int width, size_t hash)
{
- struct freq_mutable *freq = fr;
- free (freq->value);
- free (freq);
+ struct freq *f = xmalloc (sizeof *f);
+ value_clone (&f->value, value, width);
+ f->count = 0;
+ hmap_insert (hmap, &f->hmap_node, hash);
+ return f;
}
-void
-free_freq_hash (void *fr, const void *var UNUSED)
+static int
+compare_freq_ptr_3way (const void *a_, const void *b_, const void *width_)
+{
+ const struct freq *const *ap = a_;
+ const struct freq *const *bp = b_;
+ const int *widthp = width_;
+
+ return value_compare_3way (&(*ap)->value, &(*bp)->value, *widthp);
+}
+
+struct freq **
+freq_hmap_sort (struct hmap *hmap, int width)
{
- free (fr);
+ size_t n_entries = hmap_count (hmap);
+ struct freq **entries;
+ struct freq *f;
+ size_t i;
+
+ entries = xnmalloc (n_entries, sizeof *entries);
+ i = 0;
+ HMAP_FOR_EACH (f, struct freq, hmap_node, hmap)
+ entries[i++] = f;
+ assert (i == n_entries);
+
+ sort (entries, n_entries, sizeof *entries, compare_freq_ptr_3way, &width);
+
+ return entries;
}
+
+struct freq *
+freq_hmap_extract (struct hmap *hmap)
+{
+ struct freq *freqs, *f;
+ size_t n_freqs;
+ size_t i;
+
+ n_freqs = hmap_count (hmap);
+ freqs = xnmalloc (n_freqs, sizeof *freqs);
+ i = 0;
+ HMAP_FOR_EACH (f, struct freq, hmap_node, hmap)
+ freqs[i++] = *f;
+ assert (i == n_freqs);
+
+ return freqs;
+}
+