Project

General

Profile

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 
 ~~~

Back