Refactor rb_hash_replace to use hash_copy

This commit is contained in:
Peter Zhu 2023-06-29 09:14:55 -04:00
parent 3cfcd3d166
commit df2b3a2998
Notes: git 2023-06-29 15:17:10 +00:00

49
hash.c
View File

@ -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;
}