add jhash.h, copied from linux/jhash.h

Allow using arbitrary length data as hashtable key:
Copy jhash.h implementation from the linux kernel.
Apply osmo_ prefix to all global symbols.

Add jhash_test to ensure the code import works as intended.

First application will be a hashtable keyed by umts_cell_id in
osmo-hnbgw.git.

Related: SYS#6773
Change-Id: I0c9652bbc9e2a18b1200e7d63bb6f64ded7d75fa
diff --git a/tests/jhash/jhash_test.c b/tests/jhash/jhash_test.c
new file mode 100644
index 0000000..e2c8c71
--- /dev/null
+++ b/tests/jhash/jhash_test.c
@@ -0,0 +1,56 @@
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/hashtable.h>
+#include <osmocom/core/jhash.h>
+
+struct item {
+	const char blob[32];
+	struct hlist_node node;
+};
+
+struct item items[] = {
+	{ "blob one", },
+	{ "blob two and five are the same", },
+	{ "third blob", },
+	{ "fourth blob", },
+	{ "blob two and five are the same", },
+};
+
+uint32_t item_hash(const struct item *item)
+{
+	return osmo_jhash(item->blob, strlen(item->blob), 0);
+}
+
+int main(void)
+{
+	int i;
+	struct item *item;
+
+	DECLARE_HASHTABLE(haystack, 5);
+	hash_init(haystack);
+
+	printf("add:\n");
+	for (i = 0; i < ARRAY_SIZE(items); i++) {
+		uint32_t hash;
+		item = &items[i];
+		hash_add(haystack, &item->node, hash = item_hash(item));
+		printf("- adding items[%d]#%x = %s\n", i, hash, item->blob);
+	}
+
+	printf("list:\n");
+	hash_for_each (haystack, i, item, node)
+		printf("- %s [%d]\n", item->blob, (int)(item - items));
+
+	printf("find:\n");
+	for (i = 0; i < ARRAY_SIZE(items); i++) {
+		uint32_t hash;
+		struct item *needle = &items[i];
+		hash = item_hash(needle);
+		printf("- looking up items[%d]#%x = %s\n", i, hash, needle->blob);
+		hash_for_each_possible (haystack, item, node, hash)
+			printf("  - %s items[%d]\n",
+			       (item == needle) ? "found" : "not",
+			       (int)(item - items));
+	}
+
+	return 0;
+}
diff --git a/tests/jhash/jhash_test.ok b/tests/jhash/jhash_test.ok
new file mode 100644
index 0000000..e28ccc4
--- /dev/null
+++ b/tests/jhash/jhash_test.ok
@@ -0,0 +1,25 @@
+add:
+- adding items[0]#b286bb61 = blob one
+- adding items[1]#ad4eb7b = blob two and five are the same
+- adding items[2]#6b8eae61 = third blob
+- adding items[3]#24a546dc = fourth blob
+- adding items[4]#ad4eb7b = blob two and five are the same
+list:
+- blob two and five are the same [4]
+- blob two and five are the same [1]
+- blob one [0]
+- fourth blob [3]
+- third blob [2]
+find:
+- looking up items[0]#b286bb61 = blob one
+  - found items[0]
+- looking up items[1]#ad4eb7b = blob two and five are the same
+  - not items[4]
+  - found items[1]
+- looking up items[2]#6b8eae61 = third blob
+  - found items[2]
+- looking up items[3]#24a546dc = fourth blob
+  - found items[3]
+- looking up items[4]#ad4eb7b = blob two and five are the same
+  - found items[4]
+  - not items[1]