From 62505d51cc9c0600677acdae734475cda7095103 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 15 Mar 2014 15:53:12 +0900 Subject: calc hash value directly for strings, symbols and numbers --- src/etc.c | 8 ++++---- src/hash.c | 37 +++++++++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/etc.c b/src/etc.c index cf7547c2d..8398aeebd 100644 --- a/src/etc.c +++ b/src/etc.c @@ -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: diff --git a/src/hash.c b/src/hash.c index 86ad4c63d..ed71d6ee2 100644 --- a/src/hash.c +++ b/src/hash.c @@ -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; + + 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); + } - h2 = mrb_funcall(mrb, key, "hash", 0); - h ^= h2.value.i; + h = 0; + for (i=0; i