summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-12-10 17:56:14 -0800
committerEric Wong <normalperson@yhbt.net>2010-12-10 17:57:06 -0800
commit93e36dd664a9d3f95456769ca2d29c48503bd0e7 (patch)
tree7a5a243989d60d33daf5a2d47c054686a003a98e
parent4e4166437ac88aa6df4ffcd4ed8452cb5eb8750e (diff)
It's nice to have common hash functions available...
-rw-r--r--ext/tdb/hash_functions.c40
-rw-r--r--ext/tdb/tdb.c1
-rw-r--r--test/test_tdb_hash_functions.rb15
3 files changed, 56 insertions, 0 deletions
diff --git a/ext/tdb/hash_functions.c b/ext/tdb/hash_functions.c
new file mode 100644
index 0000000..7cf69f1
--- /dev/null
+++ b/ext/tdb/hash_functions.c
@@ -0,0 +1,40 @@
+#include "rbtdb.h"
+
+#define HASH_FN(fn) \
+static VALUE fn(VALUE self,VALUE str) \
+{ \
+        TDB_DATA data; \
+        StringValue(str); \
+        data.dptr = (unsigned char *)RSTRING_PTR(str); \
+        data.dsize = RSTRING_LEN(str); \
+        return UINT2NUM(rbtdb_##fn(&data)); \
+}
+
+HASH_FN(murmur1)
+HASH_FN(murmur1_aligned)
+HASH_FN(murmur2)
+HASH_FN(murmur2a)
+HASH_FN(murmur2_neutral)
+HASH_FN(murmur2_aligned)
+HASH_FN(fnv1a)
+HASH_FN(djb2)
+HASH_FN(djb3)
+HASH_FN(jenkins_lookup3)
+
+#define HASH_M(fn) rb_define_method(mHashFunctions, "tdb_hash_"#fn, fn, 1)
+void rbtdb_init_tdb_hash_functions(void)
+{
+        VALUE cTDB = rb_const_get(rb_cObject, rb_intern("TDB"));
+        VALUE mHashFunctions = rb_define_module_under(cTDB, "HashFunctions");
+
+        HASH_M(murmur1);
+        HASH_M(murmur1_aligned);
+        HASH_M(murmur2);
+        HASH_M(murmur2a);
+        HASH_M(murmur2_neutral);
+        HASH_M(murmur2_aligned);
+        HASH_M(fnv1a);
+        HASH_M(djb2);
+        HASH_M(djb3);
+        HASH_M(jenkins_lookup3);
+}
diff --git a/ext/tdb/tdb.c b/ext/tdb/tdb.c
index d1b573a..196e29d 100644
--- a/ext/tdb/tdb.c
+++ b/ext/tdb/tdb.c
@@ -737,6 +737,7 @@ void Init_tdb_ext(void)
         /* Better hashing, but can't be opened by tdb < 1.2.6. */
         rb_define_const(cTDB, "INCOMPATIBLE_HASH", UINT2NUM(TDB_INCOMPATIBLE_HASH));
 #endif
+        rbtdb_init_tdb_hash_functions();
 }
 
 /*
diff --git a/test/test_tdb_hash_functions.rb b/test/test_tdb_hash_functions.rb
new file mode 100644
index 0000000..86c599a
--- /dev/null
+++ b/test/test_tdb_hash_functions.rb
@@ -0,0 +1,15 @@
+# -*- encoding: binary -*-
+require 'test/unit'
+$-w = true
+require 'tdb'
+
+class TestHashFunctions < Test::Unit::TestCase
+  include TDB::HashFunctions
+
+  def test_hashes
+    TDB::HASHES.each do |name,_|
+      next if :default == name
+      assert_kind_of Integer, __send__("tdb_hash_#{name}", "hello")
+    end
+  end
+end