<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">
From: &lt;blaisorblade_spam@yahoo.it&gt;

Just for now and just for UML; it will go away.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso &lt;blaisorblade_spam@yahoo.it&gt;
Signed-off-by: Andrew Morton &lt;akpm@osdl.org&gt;
---

 25-akpm/include/linux/ghash.h |  236 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 236 insertions(+)

diff -puN /dev/null include/linux/ghash.h
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/include/linux/ghash.h	2004-07-05 16:00:14.793771456 -0700
@@ -0,0 +1,236 @@
+/*
+ * include/linux/ghash.h -- generic hashing with fuzzy retrieval
+ *
+ * (C) 1997 Thomas Schoebel-Theuer
+ *
+ * The algorithms implemented here seem to be a completely new invention,
+ * and I'll publish the fundamentals in a paper.
+ */
+
+#ifndef _GHASH_H
+#define _GHASH_H
+/* HASHSIZE _must_ be a power of two!!! */
+
+
+#define DEF_HASH_FUZZY_STRUCTS(NAME,HASHSIZE,TYPE) \
+\
+struct NAME##_table {\
+	TYPE * hashtable[HASHSIZE];\
+	TYPE * sorted_list;\
+	int nr_entries;\
+};\
+\
+struct NAME##_ptrs {\
+	TYPE * next_hash;\
+	TYPE * prev_hash;\
+	TYPE * next_sorted;\
+	TYPE * prev_sorted;\
+};
+
+#define DEF_HASH_FUZZY(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\
+\
+LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
+{\
+	int ix = HASHFN(elem-&gt;KEY);\
+	TYPE ** base = &amp;tbl-&gt;hashtable[ix];\
+	TYPE * ptr = *base;\
+	TYPE * prev = NULL;\
+\
+	tbl-&gt;nr_entries++;\
+	while(ptr &amp;&amp; KEYCMP(ptr-&gt;KEY, elem-&gt;KEY)) {\
+		base = &amp;ptr-&gt;PTRS.next_hash;\
+		prev = ptr;\
+		ptr = *base;\
+	}\
+	elem-&gt;PTRS.next_hash = ptr;\
+	elem-&gt;PTRS.prev_hash = prev;\
+	if(ptr) {\
+		ptr-&gt;PTRS.prev_hash = elem;\
+	}\
+	*base = elem;\
+\
+	ptr = prev;\
+	if(!ptr) {\
+		ptr = tbl-&gt;sorted_list;\
+		prev = NULL;\
+	} else {\
+		prev = ptr-&gt;PTRS.prev_sorted;\
+	}\
+	while(ptr) {\
+		TYPE * next = ptr-&gt;PTRS.next_hash;\
+		if(next &amp;&amp; KEYCMP(next-&gt;KEY, elem-&gt;KEY)) {\
+			prev = ptr;\
+			ptr = next;\
+		} else if(KEYCMP(ptr-&gt;KEY, elem-&gt;KEY)) {\
+			prev = ptr;\
+			ptr = ptr-&gt;PTRS.next_sorted;\
+		} else\
+			break;\
+	}\
+	elem-&gt;PTRS.next_sorted = ptr;\
+	elem-&gt;PTRS.prev_sorted = prev;\
+	if(ptr) {\
+		ptr-&gt;PTRS.prev_sorted = elem;\
+	}\
+	if(prev) {\
+		prev-&gt;PTRS.next_sorted = elem;\
+	} else {\
+		tbl-&gt;sorted_list = elem;\
+	}\
+}\
+\
+LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
+{\
+	TYPE * next = elem-&gt;PTRS.next_hash;\
+	TYPE * prev = elem-&gt;PTRS.prev_hash;\
+\
+	tbl-&gt;nr_entries--;\
+	if(next)\
+		next-&gt;PTRS.prev_hash = prev;\
+	if(prev)\
+		prev-&gt;PTRS.next_hash = next;\
+	else {\
+		int ix = HASHFN(elem-&gt;KEY);\
+		tbl-&gt;hashtable[ix] = next;\
+	}\
+\
+	next = elem-&gt;PTRS.next_sorted;\
+	prev = elem-&gt;PTRS.prev_sorted;\
+	if(next)\
+		next-&gt;PTRS.prev_sorted = prev;\
+	if(prev)\
+		prev-&gt;PTRS.next_sorted = next;\
+	else\
+		tbl-&gt;sorted_list = next;\
+}\
+\
+LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
+{\
+	int ix = hashfn(pos);\
+	TYPE * ptr = tbl-&gt;hashtable[ix];\
+	while(ptr &amp;&amp; KEYCMP(ptr-&gt;KEY, pos))\
+		ptr = ptr-&gt;PTRS.next_hash;\
+	if(ptr &amp;&amp; !KEYEQ(ptr-&gt;KEY, pos))\
+		ptr = NULL;\
+	return ptr;\
+}\
+\
+LINKAGE TYPE * find_##NAME##_hash_fuzzy(struct NAME##_table * tbl, KEYTYPE pos)\
+{\
+	int ix;\
+	int offset;\
+	TYPE * ptr;\
+	TYPE * next;\
+\
+	ptr = tbl-&gt;sorted_list;\
+	if(!ptr || KEYCMP(pos, ptr-&gt;KEY))\
+		return NULL;\
+	ix = HASHFN(pos);\
+	offset = HASHSIZE;\
+	do {\
+		offset &gt;&gt;= 1;\
+		next = tbl-&gt;hashtable[(ix+offset) &amp; ((HASHSIZE)-1)];\
+		if(next &amp;&amp; (KEYCMP(next-&gt;KEY, pos) || KEYEQ(next-&gt;KEY, pos))\
+		   &amp;&amp; KEYCMP(ptr-&gt;KEY, next-&gt;KEY))\
+			ptr = next;\
+	} while(offset);\
+\
+	for(;;) {\
+		next = ptr-&gt;PTRS.next_hash;\
+		if(next) {\
+			if(KEYCMP(next-&gt;KEY, pos)) {\
+				ptr = next;\
+				continue;\
+			}\
+		}\
+		next = ptr-&gt;PTRS.next_sorted;\
+		if(next &amp;&amp; KEYCMP(next-&gt;KEY, pos)) {\
+			ptr = next;\
+			continue;\
+		}\
+		return ptr;\
+	}\
+	return NULL;\
+}
+
+/* LINKAGE - empty or "static", depending on whether you want the definitions to
+ *	be public or not
+ * NAME - a string to stick in names to make this hash table type distinct from
+ * 	any others
+ * HASHSIZE - number of buckets
+ * TYPE - type of data contained in the buckets - must be a structure, one
+ * 	field is of type NAME_ptrs, another is the hash key
+ * PTRS - TYPE must contain a field of type NAME_ptrs, PTRS is the name of that
+ * 	field
+ * KEYTYPE - type of the key field within TYPE
+ * KEY - name of the key field within TYPE
+ * KEYCMP - pointer to function that compares KEYTYPEs to each other - the
+ * 	prototype is int KEYCMP(KEYTYPE, KEYTYPE), it returns zero for equal,
+ * 	non-zero for not equal
+ * HASHFN - the hash function - the prototype is int HASHFN(KEYTYPE),
+ * 	it returns a number in the range 0 ... HASHSIZE - 1
+ * Call DEF_HASH_STRUCTS, define your hash table as a NAME_table, then call
+ * DEF_HASH.
+ */
+
+#define DEF_HASH_STRUCTS(NAME,HASHSIZE,TYPE) \
+\
+struct NAME##_table {\
+	TYPE * hashtable[HASHSIZE];\
+	int nr_entries;\
+};\
+\
+struct NAME##_ptrs {\
+	TYPE * next_hash;\
+	TYPE * prev_hash;\
+};
+
+#define DEF_HASH(LINKAGE,NAME,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,HASHFN)\
+\
+LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
+{\
+	int ix = HASHFN(elem-&gt;KEY);\
+	TYPE ** base = &amp;tbl-&gt;hashtable[ix];\
+	TYPE * ptr = *base;\
+	TYPE * prev = NULL;\
+\
+	tbl-&gt;nr_entries++;\
+	while(ptr &amp;&amp; KEYCMP(ptr-&gt;KEY, elem-&gt;KEY)) {\
+		base = &amp;ptr-&gt;PTRS.next_hash;\
+		prev = ptr;\
+		ptr = *base;\
+	}\
+	elem-&gt;PTRS.next_hash = ptr;\
+	elem-&gt;PTRS.prev_hash = prev;\
+	if(ptr) {\
+		ptr-&gt;PTRS.prev_hash = elem;\
+	}\
+	*base = elem;\
+}\
+\
+LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
+{\
+	TYPE * next = elem-&gt;PTRS.next_hash;\
+	TYPE * prev = elem-&gt;PTRS.prev_hash;\
+\
+	tbl-&gt;nr_entries--;\
+	if(next)\
+		next-&gt;PTRS.prev_hash = prev;\
+	if(prev)\
+		prev-&gt;PTRS.next_hash = next;\
+	else {\
+		int ix = HASHFN(elem-&gt;KEY);\
+		tbl-&gt;hashtable[ix] = next;\
+	}\
+}\
+\
+LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
+{\
+	int ix = HASHFN(pos);\
+	TYPE * ptr = tbl-&gt;hashtable[ix];\
+	while(ptr &amp;&amp; KEYCMP(ptr-&gt;KEY, pos))\
+		ptr = ptr-&gt;PTRS.next_hash;\
+	return ptr;\
+}
+
+#endif
_
</pre></body></html>