summaryrefslogtreecommitdiff
path: root/src/hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/hash.c')
-rw-r--r--src/hash.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/hash.c b/src/hash.c
new file mode 100644
index 0000000..447601e
--- /dev/null
+++ b/src/hash.c
@@ -0,0 +1,97 @@
+/* hash.c - Alpine Package Keeper (APK)
+ *
+ * Copyright (C) 2005-2008 Natanael Copa <n@tanael.org>
+ * Copyright (C) 2008 Timo Teräs <timo.teras@iki.fi>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation. See http://www.gnu.org/ for details.
+ */
+
+#include "apk_defines.h"
+#include "apk_hash.h"
+
+unsigned long apk_hash_string(const char *str)
+{
+ unsigned long hash = 5381;
+ int c;
+
+ while ((c = *str++) != 0)
+ hash = hash * 33 + c;
+
+ return hash;
+}
+
+unsigned long apk_hash_csum(const void *ptr)
+{
+ return *(const unsigned long *) ptr;
+}
+
+void apk_hash_init(struct apk_hash *h, const struct apk_hash_ops *ops,
+ int num_buckets)
+{
+ h->ops = ops;
+ h->buckets = apk_hash_array_resize(NULL, num_buckets);
+ h->num_items = 0;
+}
+
+void apk_hash_free(struct apk_hash *h)
+{
+ apk_hash_foreach(h, (apk_hash_enumerator_f) h->ops->delete_item, NULL);
+ free(h->buckets);
+}
+
+int apk_hash_foreach(struct apk_hash *h, apk_hash_enumerator_f e, void *ctx)
+{
+ apk_hash_node *pos, *n;
+ ptrdiff_t offset = h->ops->node_offset;
+ int i, r;
+
+ for (i = 0; i < h->buckets->num; i++) {
+ hlist_for_each_safe(pos, n, &h->buckets->item[i]) {
+ r = e(((void *) pos) - offset, ctx);
+ if (r != 0)
+ return r;
+ }
+ }
+
+ return 0;
+}
+
+apk_hash_item apk_hash_get(struct apk_hash *h, apk_hash_key key)
+{
+ ptrdiff_t offset = h->ops->node_offset;
+ unsigned long hash;
+ apk_hash_node *pos;
+ apk_hash_item item;
+ apk_hash_key itemkey;
+
+ hash = h->ops->hash_key(key) % h->buckets->num;
+ hlist_for_each(pos, &h->buckets->item[hash]) {
+ item = ((void *) pos) - offset;
+ itemkey = h->ops->get_key(item);
+ if (h->ops->compare(key, itemkey) == 0)
+ return item;
+ }
+
+ return NULL;
+}
+
+void apk_hash_insert(struct apk_hash *h, apk_hash_item item)
+{
+ apk_hash_key key;
+ unsigned long hash;
+ apk_hash_node *node;
+
+ key = h->ops->get_key(item);
+ hash = h->ops->hash_key(key) % h->buckets->num;
+ node = (apk_hash_node *) (item + h->ops->node_offset);
+ hlist_add_head(node, &h->buckets->item[hash]);
+ h->num_items++;
+}
+
+void apk_hash_delete(struct apk_hash *h, apk_hash_key key)
+{
+}
+