From dd7e2d85667e2dab4882a9cb2c3a727233e03b46 Mon Sep 17 00:00:00 2001 From: Evan Klitzke Date: Thu, 9 Apr 2009 23:41:29 -0700 Subject: [PATCH] GHashTables, oh boy oh boy --- LICENSE.md | 5 ++++ Makefile | 2 ++ README.md | 3 +++ counter.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ test_counter.c | 16 ++++++++++++ 5 files changed, 96 insertions(+) create mode 100644 LICENSE.md create mode 100644 Makefile create mode 100644 README.md create mode 100644 counter.c create mode 100644 test_counter.c diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..677ce41 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,5 @@ +This code is copyright Evan Klitkze, 2009 + +This code is currently licensed under the terms of the GPL, version 3. You can +find the full text of that license online at +[gnu.org](http://www.gnu.org/licenses/gpl-3.0.txt). diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..084b585 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +test_counter: test_counter.c counter.c + gcc -o test_counter test_counter.c $(pkg-config glib-2.0 --cflags --libs) diff --git a/README.md b/README.md new file mode 100644 index 0000000..7f276d1 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +Scribble +======== +Collect status, build high performance components. 'Nuff said. diff --git a/counter.c b/counter.c new file mode 100644 index 0000000..480af5b --- /dev/null +++ b/counter.c @@ -0,0 +1,70 @@ +/* This uses hash tables all over the place, which isn't optimal. + */ + +#include + +/* Create a new counter. This is really just a hash table. */ +GHashTable* new_counter() +{ + GHashTable *ht; + ht = g_hash_table_new(g_str_hash, g_str_equal); + return ht; +} + +/* This increments a key in for ht[major][minor] */ +void incr_counter(GHashTable *ht, char *major, char *minor) +{ + GHashTable *sub; + gchar *major_cpy, *minor_cpy; + guint *val; + + sub = g_hash_table_lookup(ht, major); + if (sub == NULL) { + major_cpy = g_strdup(major); + sub = g_hash_table_new(g_str_hash, g_str_equal); + g_hash_table_insert(ht, major_cpy, sub); + } + + val = g_hash_table_lookup(sub, minor); + if (val == NULL) { + minor_cpy = g_strdup(minor); + val = g_slice_alloc0(sizeof(guint)); + g_hash_table_insert(sub, minor_cpy, val); + } + (*val)++; +} + +void free_counter(GHashTable *ht) +{ + GHashTableIter iter_i, iter_j; + gpointer key_i, value_i, key_j, value_j; + + g_hash_table_iter_init(&iter_i, ht); + while (g_hash_table_iter_next(&iter_i, &key_i, &value_i)) { + g_hash_table_iter_remove(&iter_i); + g_free(key_i); + + g_hash_table_iter_init(&iter_j, value_i); + while (g_hash_table_iter_next(&iter_j, &key_j, &value_j)) { + g_hash_table_iter_remove(&iter_j); + g_free(key_j); + g_slice_free(guint, value_j); + } + g_hash_table_destroy(value_i); + } +} + +guint lookup_counter(GHashTable *ht, char *major, char *minor) +{ + GHashTable *sub; + guint *val; + + sub = g_hash_table_lookup(ht, major); + if (sub == NULL) + return 0; + + val = g_hash_table_lookup(sub, minor); + if (val == NULL) + return 0; + return *val; +} diff --git a/test_counter.c b/test_counter.c new file mode 100644 index 0000000..168d7cc --- /dev/null +++ b/test_counter.c @@ -0,0 +1,16 @@ +#include +#include "counter.c" +#include + +int main() +{ + GHashTable *ht = new_counter(); + incr_counter(ht, "foo", "bar"); + incr_counter(ht, "foo", "baz"); + incr_counter(ht, "foo", "bar"); + printf("foo.bar = %d\n", lookup_counter(ht, "foo", "bar")); + printf("foo.baz = %d\n", lookup_counter(ht, "foo", "baz")); + printf("foo.bad = %d\n", lookup_counter(ht, "foo", "bad")); + free_counter(ht); + return 0; +}