calc hash value directly for strings, symbols and numbers

This commit is contained in:
Yukihiro "Matz" Matsumoto
2014-03-15 15:53:12 +09:00
parent 048bca43c9
commit 62505d51cc
2 changed files with 37 additions and 8 deletions
+4 -4
View File
@@ -86,8 +86,8 @@ mrb_obj_to_sym(mrb_state *mrb, mrb_value name)
return id;
}
static mrb_int
float_id(mrb_float f)
mrb_int
mrb_float_id(mrb_float f)
{
const char *p = (const char*)&f;
int len = sizeof(f);
@@ -123,9 +123,9 @@ mrb_obj_id(mrb_value obj)
case MRB_TT_SYMBOL:
return MakeID(mrb_symbol(obj));
case MRB_TT_FIXNUM:
return MakeID2(float_id((mrb_float)mrb_fixnum(obj)), MRB_TT_FLOAT);
return MakeID2(mrb_float_id((mrb_float)mrb_fixnum(obj)), MRB_TT_FLOAT);
case MRB_TT_FLOAT:
return MakeID(float_id(mrb_float(obj)));
return MakeID(mrb_float_id(mrb_float(obj)));
case MRB_TT_STRING:
case MRB_TT_OBJECT:
case MRB_TT_CLASS:
+33 -4
View File
@@ -12,14 +12,43 @@
#include "mruby/string.h"
#include "mruby/variable.h"
/* a function to get hash value of a float number */
mrb_int mrb_float_id(mrb_float f);
static inline khint_t
mrb_hash_ht_hash_func(mrb_state *mrb, mrb_value key)
{
khint_t h = (khint_t)mrb_type(key) << 24;
mrb_value h2;
enum mrb_vtype t = mrb_type(key);
mrb_value hv;
const char *p;
mrb_int i, len;
khint_t h;
h2 = mrb_funcall(mrb, key, "hash", 0);
h ^= h2.value.i;
switch (t) {
case MRB_TT_STRING:
p = RSTRING_PTR(key);
len = RSTRING_LEN(key);
break;
case MRB_TT_SYMBOL:
p = mrb_sym2name_len(mrb, mrb_symbol(key), &len);
break;
case MRB_TT_FIXNUM:
return (khint_t)mrb_float_id((mrb_float)mrb_fixnum(key));
case MRB_TT_FLOAT:
return (khint_t)mrb_float_id(mrb_float(key));
default:
hv = mrb_funcall(mrb, key, "hash", 0);
return (khint_t)t ^ mrb_fixnum(hv);
}
h = 0;
for (i=0; i<len; i++) {
h = (h << 5) - h + *p++;
}
return h;
}