diff options
author | Peter Zhu <[email protected]> | 2023-06-29 09:14:55 -0400 |
---|---|---|
committer | Peter Zhu <[email protected]> | 2023-06-29 11:16:50 -0400 |
commit | df2b3a29987e9353596af76ed77f35d7366d654e (patch) | |
tree | 3b01c4925aa0a142150c42388fa46e9e09d526d2 /hash.c | |
parent | 3cfcd3d1663169ad68e22e5efef35f8057173993 (diff) |
Refactor rb_hash_replace to use hash_copy
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/8000
Diffstat (limited to 'hash.c')
-rw-r--r-- | hash.c | 49 |
1 files changed, 21 insertions, 28 deletions
@@ -1460,14 +1460,31 @@ rb_hash_new_capa(long capa) static VALUE hash_copy(VALUE ret, VALUE hash) { - if (!RHASH_EMPTY_P(hash)) { - if (RHASH_AR_TABLE_P(hash)) { + if (RHASH_AR_TABLE_P(hash)) { + if (RHASH_AR_TABLE_P(ret)) { ar_copy(ret, hash); } else { - RHASH_ST_TABLE_SET(ret, st_copy(RHASH_ST_TABLE(hash))); + st_table *tab = RHASH_ST_TABLE(ret); + rb_st_init_existing_table_with_size(tab, &objhash, RHASH_AR_TABLE_SIZE(hash)); + + int bound = RHASH_AR_TABLE_BOUND(hash); + for (int i = 0; i < bound; i++) { + if (ar_cleared_entry(hash, i)) continue; + + ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i); + st_add_direct(tab, pair->key, pair->val); + RB_OBJ_WRITTEN(ret, Qundef, pair->key); + RB_OBJ_WRITTEN(ret, Qundef, pair->val); + } } } + else { + HASH_ASSERT(sizeof(st_table) <= sizeof(ar_table)); + + RHASH_ST_TABLE_SET(ret, st_copy(RHASH_ST_TABLE(hash))); + rb_gc_writebarrier_remember(ret); + } return ret; } @@ -2877,31 +2894,7 @@ rb_hash_replace(VALUE hash, VALUE hash2) RHASH_ST_CLEAR(hash); } - if (RHASH_AR_TABLE_P(hash2)) { - if (RHASH_AR_TABLE_P(hash)) { - ar_copy(hash, hash2); - } - else { - st_table *tab = RHASH_ST_TABLE(hash); - rb_st_init_existing_table_with_size(tab, &objhash, RHASH_AR_TABLE_SIZE(hash2)); - - int bound = RHASH_AR_TABLE_BOUND(hash2); - for (int i = 0; i < bound; i++) { - if (ar_cleared_entry(hash2, i)) continue; - - ar_table_pair *pair = RHASH_AR_TABLE_REF(hash2, i); - st_add_direct(tab, pair->key, pair->val); - RB_OBJ_WRITTEN(hash, Qundef, pair->key); - RB_OBJ_WRITTEN(hash, Qundef, pair->val); - } - } - } - else { - HASH_ASSERT(sizeof(st_table) <= sizeof(ar_table)); - - RHASH_ST_TABLE_SET(hash, st_copy(RHASH_ST_TABLE(hash2))); - rb_gc_writebarrier_remember(hash); - } + hash_copy(hash, hash2); return hash; } |