hash.c: move Hash specific functions
* hash.c (rb_ident_hash): move compare_by_identity specific function from st.c. * hash.c (rb_ident_hash_new): ditto from thread.c. * st.c (st_numhash): remove ruby's Hash specific implementation. * thread.c (recursive_list_access): use rb_ident_hash_new(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49386 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
51efda1ef3
commit
059ea6e4d8
42
hash.c
42
hash.c
@ -177,7 +177,39 @@ static const struct st_hash_type objhash = {
|
|||||||
rb_any_hash,
|
rb_any_hash,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define identhash st_hashtype_num
|
#define rb_ident_cmp st_numcmp
|
||||||
|
|
||||||
|
static st_index_t
|
||||||
|
rb_ident_hash(st_data_t n)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This hash function is lightly-tuned for Ruby. Further tuning
|
||||||
|
* should be possible. Notes:
|
||||||
|
*
|
||||||
|
* - (n >> 3) alone is great for heap objects and OK for fixnum,
|
||||||
|
* however symbols perform poorly.
|
||||||
|
* - (n >> (RUBY_SPECIAL_SHIFT+3)) was added to make symbols hash well,
|
||||||
|
* n.b.: +3 to remove ID scope, +1 worked well initially, too
|
||||||
|
* - (n << 3) was finally added to avoid losing bits for fixnums
|
||||||
|
* - avoid expensive modulo instructions, it is currently only
|
||||||
|
* shifts and bitmask operations.
|
||||||
|
* - flonum (on 64-bit) is pathologically bad, mix the actual
|
||||||
|
* float value in, but do not use the float value as-is since
|
||||||
|
* many integers get interpreted as 2.0 or -2.0 [Bug #10761]
|
||||||
|
*/
|
||||||
|
#ifdef USE_FLONUM /* RUBY */
|
||||||
|
if (FLONUM_P(n)) {
|
||||||
|
n ^= (st_data_t)rb_float_value(n);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return (st_index_t)((n>>(RUBY_SPECIAL_SHIFT+3)|(n<<3)) ^ (n>>3));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct st_hash_type identhash = {
|
||||||
|
rb_ident_cmp,
|
||||||
|
rb_ident_hash,
|
||||||
|
};
|
||||||
|
|
||||||
typedef int st_foreach_func(st_data_t, st_data_t, st_data_t);
|
typedef int st_foreach_func(st_data_t, st_data_t, st_data_t);
|
||||||
|
|
||||||
@ -2509,6 +2541,14 @@ rb_hash_compare_by_id_p(VALUE hash)
|
|||||||
return Qfalse;
|
return Qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_ident_hash_new(void)
|
||||||
|
{
|
||||||
|
VALUE hash = rb_hash_new();
|
||||||
|
RHASH(hash)->ntbl = st_init_table(&identhash);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
any_p_i(VALUE key, VALUE value, VALUE arg)
|
any_p_i(VALUE key, VALUE value, VALUE arg)
|
||||||
{
|
{
|
||||||
|
@ -701,6 +701,7 @@ struct st_table *rb_hash_tbl_raw(VALUE hash);
|
|||||||
VALUE rb_hash_has_key(VALUE hash, VALUE key);
|
VALUE rb_hash_has_key(VALUE hash, VALUE key);
|
||||||
VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc);
|
VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc);
|
||||||
long rb_objid_hash(st_index_t index);
|
long rb_objid_hash(st_index_t index);
|
||||||
|
VALUE rb_ident_hash_new(void);
|
||||||
|
|
||||||
#define RHASH_TBL_RAW(h) rb_hash_tbl_raw(h)
|
#define RHASH_TBL_RAW(h) rb_hash_tbl_raw(h)
|
||||||
VALUE rb_hash_keys(VALUE hash);
|
VALUE rb_hash_keys(VALUE hash);
|
||||||
@ -952,9 +953,6 @@ extern int ruby_enable_coredump;
|
|||||||
int rb_get_next_signal(void);
|
int rb_get_next_signal(void);
|
||||||
int rb_sigaltstack_size(void);
|
int rb_sigaltstack_size(void);
|
||||||
|
|
||||||
/* st.c */
|
|
||||||
extern const struct st_hash_type st_hashtype_num;
|
|
||||||
|
|
||||||
/* strftime.c */
|
/* strftime.c */
|
||||||
#ifdef RUBY_ENCODING_H
|
#ifdef RUBY_ENCODING_H
|
||||||
size_t rb_strftime_timespec(char *s, size_t maxsize, const char *format, rb_encoding *enc,
|
size_t rb_strftime_timespec(char *s, size_t maxsize, const char *format, rb_encoding *enc,
|
||||||
|
24
st.c
24
st.c
@ -1750,26 +1750,6 @@ st_numcmp(st_data_t x, st_data_t y)
|
|||||||
st_index_t
|
st_index_t
|
||||||
st_numhash(st_data_t n)
|
st_numhash(st_data_t n)
|
||||||
{
|
{
|
||||||
/*
|
enum {s1 = 11, s2 = 3};
|
||||||
* This hash function is lightly-tuned for Ruby. Further tuning
|
return (st_index_t)((n>>s1|(n<<s2)) ^ (n>>s2));
|
||||||
* should be possible. Notes:
|
|
||||||
*
|
|
||||||
* - (n >> 3) alone is great for heap objects and OK for fixnum,
|
|
||||||
* however symbols perform poorly.
|
|
||||||
* - (n >> (RUBY_SPECIAL_SHIFT+3)) was added to make symbols hash well,
|
|
||||||
* n.b.: +3 to remove ID scope, +1 worked well initially, too
|
|
||||||
* - (n << 3) was finally added to avoid losing bits for fixnums
|
|
||||||
* - avoid expensive modulo instructions, it is currently only
|
|
||||||
* shifts and bitmask operations.
|
|
||||||
* - flonum (on 64-bit) is pathologically bad, mix the actual
|
|
||||||
* float value in, but do not use the float value as-is since
|
|
||||||
* many integers get interpreted as 2.0 or -2.0 [Bug #10761]
|
|
||||||
*/
|
|
||||||
#ifdef USE_FLONUM /* RUBY */
|
|
||||||
if (FLONUM_P(n)) {
|
|
||||||
n ^= (st_data_t)rb_float_value(n);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return (st_index_t)((n>>(RUBY_SPECIAL_SHIFT+3)|(n<<3)) ^ (n>>3));
|
|
||||||
}
|
}
|
||||||
|
12
thread.c
12
thread.c
@ -4675,14 +4675,6 @@ rb_thread_shield_destroy(VALUE self)
|
|||||||
return rb_thread_shield_waiting(self) > 0 ? Qtrue : Qfalse;
|
return rb_thread_shield_waiting(self) > 0 ? Qtrue : Qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
|
||||||
ident_hash_new(void)
|
|
||||||
{
|
|
||||||
VALUE hash = rb_hash_new();
|
|
||||||
rb_hash_tbl_raw(hash)->type = &st_hashtype_num;
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
threadptr_recursive_hash(rb_thread_t *th)
|
threadptr_recursive_hash(rb_thread_t *th)
|
||||||
{
|
{
|
||||||
@ -4710,7 +4702,7 @@ recursive_list_access(VALUE sym)
|
|||||||
VALUE hash = threadptr_recursive_hash(th);
|
VALUE hash = threadptr_recursive_hash(th);
|
||||||
VALUE list;
|
VALUE list;
|
||||||
if (NIL_P(hash) || !RB_TYPE_P(hash, T_HASH)) {
|
if (NIL_P(hash) || !RB_TYPE_P(hash, T_HASH)) {
|
||||||
hash = ident_hash_new();
|
hash = rb_ident_hash_new();
|
||||||
threadptr_recursive_hash_set(th, hash);
|
threadptr_recursive_hash_set(th, hash);
|
||||||
list = Qnil;
|
list = Qnil;
|
||||||
}
|
}
|
||||||
@ -4718,7 +4710,7 @@ recursive_list_access(VALUE sym)
|
|||||||
list = rb_hash_aref(hash, sym);
|
list = rb_hash_aref(hash, sym);
|
||||||
}
|
}
|
||||||
if (NIL_P(list) || !RB_TYPE_P(list, T_HASH)) {
|
if (NIL_P(list) || !RB_TYPE_P(list, T_HASH)) {
|
||||||
list = ident_hash_new();
|
list = rb_ident_hash_new();
|
||||||
rb_hash_aset(hash, sym, list);
|
rb_hash_aset(hash, sym, list);
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user