ext/rumourhash/rumourhash.c in antlr4-runtime-0.2.3 vs ext/rumourhash/rumourhash.c in antlr4-runtime-0.2.4
- old
+ new
@@ -4,42 +4,86 @@
#define c2 0x1B873593
#define r1 15
#define r2 13
#define m 5
#define n 0xE6546B64
+#define defaultSeed 7
-static VALUE rumour_hash_update_int(VALUE self, VALUE hashv, VALUE valuev) {
- long hash = NUM2LONG(hashv);
- long value = NUM2LONG(valuev);
-
+static long rumour_hash_update_int_impl(VALUE self, long hash, long value) {
long k = value;
k *= c1;
k = (k << r1) | (k >> (32 - r1));
k *= c2;
hash = hash ^ k;
hash = (hash << r2) | (hash >> (32 - r2));
hash *= m + n;
- return LONG2NUM(hash);
+ return hash;
}
-static VALUE rumour_hash_finish(VALUE self, VALUE hashv, VALUE n_wordsv) {
+static VALUE rumour_hash_update_int(VALUE self, VALUE hashv, VALUE valuev) {
long hash = NUM2LONG(hashv);
- long n_words = NUM2LONG(n_wordsv);
+ long value = NUM2LONG(valuev);
+ hash = rumour_hash_update_int_impl(self, hash, value);
+ return LONG2NUM(hash);
+}
+static long rumour_hash_finish_impl(VALUE self, long hash, long n_words) {
hash = hash ^ (n_words * 4);
hash = hash ^ (hash >> 16);
hash *= 0x85EBCA6B;
hash = hash ^ (hash >> 13);
hash *= 0xC2B2AE35;
hash ^= (hash >> 16);
+ return hash;
+}
+
+static VALUE rumour_hash_finish(VALUE self, VALUE hashv, VALUE n_wordsv) {
+ long hash = NUM2LONG(hashv);
+ long n_words = NUM2LONG(n_wordsv);
+ hash = rumour_hash_finish_impl(self, hash, n_words);
return LONG2NUM(hash);
}
-static VALUE bit_count(VALUE self, VALUE v) {
+static VALUE rumour_hash_calculate(int argc, VALUE* argv, VALUE self) {
+ VALUE itemsv;
+ VALUE seed;
+
+ rb_scan_args(argc, argv, "11", &itemsv, &seed);
+
+ long hash;
+
+ if (seed == Qnil) {
+ hash = defaultSeed;
+ } else {
+ hash = NUM2LONG(seed);
+ }
+
+ for (int i = 0; i < RARRAY_LEN(itemsv); i ++) {
+ VALUE current = RARRAY_AREF(itemsv, i);
+ long val;
+
+ if (current == Qnil || current == Qfalse) {
+ val = 0;
+ } else if (current == Qtrue) {
+ val = 1;
+ } else if (CLASS_OF(current) == rb_cInteger) {
+ val = NUM2LONG(current);
+ } else {
+ val = NUM2LONG(rb_hash(current));
+ }
+
+ hash = rumour_hash_update_int_impl(self, hash, val);
+ }
+
+ hash = rumour_hash_finish_impl(self, hash, RARRAY_LEN(itemsv));
+ return LONG2NUM(hash);
+}
+
+static VALUE rumour_hash_bit_count(VALUE self, VALUE v) {
long num = NUM2LONG(v);
int count = 0;
while (num)
{
@@ -50,10 +94,10 @@
return INT2NUM(count);
}
void Init_rumourhash() {
VALUE mod = rb_define_module("RumourHash");
- rb_define_method(mod, "rumour_hash_update_int", rumour_hash_update_int, 2);
- rb_define_method(mod, "rumour_hash_finish", rumour_hash_finish, 2);
- rb_define_method(mod, "bit_count", bit_count, 1);
+ rb_define_singleton_method(mod, "calculate", rumour_hash_calculate, -1);
+ rb_define_singleton_method(mod, "update_int", rumour_hash_update_int, 2);
+ rb_define_singleton_method(mod, "finish", rumour_hash_finish, 2);
+ rb_define_singleton_method(mod, "bit_count", rumour_hash_bit_count, 1);
}
-