about summary refs log tree commit diff
path: root/hash.h
diff options
context:
space:
mode:
Diffstat (limited to 'hash.h')
-rw-r--r--hash.h68
1 files changed, 68 insertions, 0 deletions
diff --git a/hash.h b/hash.h
new file mode 100644
index 0000000..3e18736
--- /dev/null
+++ b/hash.h
@@ -0,0 +1,68 @@
+/*
+ * hash.h - generic hash template, akin to queue.h & tree.h
+ *
+ * Copyright (c) 2005 Marius Eriksen <marius@monkey.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HASH_H_		/* Possibly this is too generic. */
+#define _HASH_H_
+
+#include <sys/tree.h>
+
+#define HASH_ENTRY SPLAY_ENTRY
+
+#define HASH_HEAD(name, type, nbuckets) 			\
+	SPLAY_HEAD(name##_HASH_TREE, type);			\
+	struct name {						\
+		struct name##_HASH_TREE buckets[nbuckets];	\
+		unsigned int (*hashfn)(struct type *elm);	\
+	};
+
+#define HASH_NBUCKETS(head)					\
+	(sizeof((head)->buckets)/sizeof((head)->buckets[0]))
+
+#define HASH_INIT(head, fn) do {			\
+	int i;						\
+	for (i = 0; i < HASH_NBUCKETS(head); i++) {	\
+		SPLAY_INIT(&(head)->buckets[i]);	\
+	}						\
+	(head)->hashfn = fn;				\
+} while (0)
+
+#define HASH_PROTOTYPE(name, type, field, cmp)				\
+SPLAY_PROTOTYPE(name##_HASH_TREE, type, field, cmp)			\
+struct type *name##_HASH_TREE_FIND(struct name *head, struct type *find); \
+void name##_HASH_TREE_INSERT(struct name *head, struct type *insert);
+
+#define HASH_GENERATE(name, type, field, cmp)				\
+SPLAY_GENERATE(name##_HASH_TREE, type, field, cmp)			\
+struct type *name##_HASH_TREE_FIND(struct name *head, struct type *find) \
+{									\
+	struct name##_HASH_TREE *bucket =				\
+	    &head->buckets[(*head->hashfn)(find) % HASH_NBUCKETS(head)]; \
+	return SPLAY_FIND(name##_HASH_TREE, bucket, find);		\
+}									\
+void name##_HASH_TREE_INSERT(struct name *head, struct type *insert)	\
+{									\
+	struct name##_HASH_TREE *bucket =				\
+	    &head->buckets[(*head->hashfn)(insert) % HASH_NBUCKETS(head)]; \
+									\
+	SPLAY_INSERT(name##_HASH_TREE, bucket, insert);			\
+}
+
+#define HASH_FIND(name, head, find) name##_HASH_TREE_FIND((head), (find))
+#define HASH_INSERT(name, head, insert) name##_HASH_TREE_INSERT((head), (insert))
+
+#endif /* _HASH_H_ */