Feature #9889
Updated by shyouhei (Shyouhei Urabe) over 10 years ago
~~~Patch From b042711f88b74c9b260a8a6d82d3e040174c01d2 Mon Sep 17 00:00:00 2001 From: "Urabe, Shyouhei" <shyouhei@ruby-lang.org> Date: Sat, 31 May 2014 22:13:24 +0900 Subject: [PATCH] Hide Hash internal I chose struct RHash for several reasons: - I'm farmiliar with its internals so I'm 100% sure with this patch. - At least Ko1, Eric, and myself think current hash implementation needs improvements. So hiding its internal is urgent. - Hash is a relatively complex data strcture compared to Strings and Arrays, so its internals are seldom touched. Signed-off-by: Urabe, Shyouhei <shyouhei@ruby-lang.org> --- ChangeLog | 14 ++++++++++++++ hash.c | 29 ++++++++++++++++++++++++++--- include/ruby/intern.h | 3 +++ include/ruby/ruby.h | 13 +++---------- internal.h | 9 +++++++++ 5 files changed, 55 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8381daa..ea789cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +Sat May 31 22:10:32 2014 URABE Shyouhei <shyouhei@ruby-lang.org> + + * include/ruby/ruby.h (struct RHash): no longer. + + * internal.h (struct RHash): moved here. + + * hash.c (rb_hash_ifnone): compatibilty accessor function. + + * hash.c (rb_hash_iter_lev): ditto. + + * hash.c (rb_hash_size_): ditto. + + (note) rb_hash_size() already exists. + Sat May 31 21:15:43 2014 URABE Shyouhei <shyouhei@ruby-lang.org> * thread.c (rb_thread_atfork_internal): My compiler complains diff --git a/hash.c b/hash.c index 93efde7..59f79a9 100644 --- a/hash.c +++ b/hash.c @@ -235,14 +235,14 @@ hash_foreach_iter(st_data_t key, st_data_t value, st_data_t argp, int error) static VALUE hash_foreach_ensure_rollback(VALUE hash) { - RHASH_ITER_LEV(hash)++; + RHASH(hash)->iter_lev++; return 0; } static VALUE hash_foreach_ensure(VALUE hash) { - if (--RHASH_ITER_LEV(hash) == 0) { + if (--RHASH(hash)->iter_lev == 0) { if (FL_TEST(hash, HASH_DELETED)) { st_cleanup_safe(RHASH(hash)->ntbl, (st_data_t)Qundef); FL_UNSET(hash, HASH_DELETED); @@ -268,7 +268,7 @@ rb_hash_foreach(VALUE hash, int (*func)(ANYARGS), VALUE farg) if (!RHASH(hash)->ntbl) return; - RHASH_ITER_LEV(hash)++; + RHASH(hash)->iter_lev++; arg.hash = hash; arg.func = (rb_foreach_func *)func; arg.arg = farg; @@ -354,6 +354,29 @@ rb_hash_tbl_raw(VALUE hash) return hash_tbl(hash); } +VALUE +rb_hash_ifnone(VALUE hash) +{ + return RHASH(hash)->ifnone; +} + +int +rb_hash_iter_lev(VALUE hash) +{ + return RHASH(hash)->iter_lev; +} + +st_index_t +rb_hash_size_(VALUE hash) +{ + if (RHASH(hash)->ntbl) { + return RHASH(hash)->ntbl->num_entries; + } + else { + return 0; + } +} + static void rb_hash_modify(VALUE hash) { diff --git a/include/ruby/intern.h b/include/ruby/intern.h index 387f000..4758533 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -503,6 +503,9 @@ VALUE rb_hash_set_ifnone(VALUE hash, VALUE ifnone); typedef VALUE rb_hash_update_func(VALUE newkey, VALUE oldkey, VALUE value); VALUE rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func); struct st_table *rb_hash_tbl(VALUE); +VALUE rb_hash_ifnone(VALUE); +int rb_hash_iter_lev(VALUE); +st_index_t rb_hash_size_(VALUE); int rb_path_check(const char*); int rb_env_path_tainted(void); VALUE rb_env_clear(void); diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index 7c7cb67..f033f46 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -924,17 +924,11 @@ struct RRegexp { #define RREGEXP_SRC_LEN(r) RSTRING_LEN(RREGEXP(r)->src) #define RREGEXP_SRC_END(r) RSTRING_END(RREGEXP(r)->src) -struct RHash { - struct RBasic basic; - struct st_table *ntbl; /* possibly 0 */ - int iter_lev; - const VALUE ifnone; -}; /* RHASH_TBL allocates st_table if not available. */ #define RHASH_TBL(h) rb_hash_tbl(h) -#define RHASH_ITER_LEV(h) (RHASH(h)->iter_lev) -#define RHASH_IFNONE(h) (RHASH(h)->ifnone) -#define RHASH_SIZE(h) (RHASH(h)->ntbl ? (st_index_t)RHASH(h)->ntbl->num_entries : 0) +#define RHASH_ITER_LEV(h) rb_hash_iter_lev(h) +#define RHASH_IFNONE(h) rb_hash_ifnone(h) +#define RHASH_SIZE(h) rb_hash_size_(h) #define RHASH_EMPTY_P(h) (RHASH_SIZE(h) == 0) #define RHASH_SET_IFNONE(h, ifnone) rb_hash_set_ifnone((VALUE)h, ifnone) @@ -1081,7 +1075,6 @@ struct RStruct { #define RSTRING(obj) (R_CAST(RString)(obj)) #define RREGEXP(obj) (R_CAST(RRegexp)(obj)) #define RARRAY(obj) (R_CAST(RArray)(obj)) -#define RHASH(obj) (R_CAST(RHash)(obj)) #define RDATA(obj) (R_CAST(RData)(obj)) #define RTYPEDDATA(obj) (R_CAST(RTypedData)(obj)) #define RSTRUCT(obj) (R_CAST(RStruct)(obj)) diff --git a/internal.h b/internal.h index 2c1c6a3..854d9d9 100644 --- a/internal.h +++ b/internal.h @@ -420,6 +420,15 @@ struct RSymbol { #define RSYMBOL(obj) (R_CAST(RSymbol)(obj)) +struct RHash { + struct RBasic basic; + struct st_table *ntbl; /* possibly 0 */ + int iter_lev; + const VALUE ifnone; +}; + +#define RHASH(obj) (R_CAST(RHash)(obj)) + /* class.c */ void rb_class_subclass_add(VALUE super, VALUE klass); void rb_class_remove_from_super_subclasses(VALUE); -- 1.9.1 ~~~