mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
[Bug #19969] Compact st_table after deleted if possible
This commit is contained in:
parent
2a442121d1
commit
9eac9d7178
3 changed files with 57 additions and 11 deletions
40
st.c
40
st.c
|
@ -717,6 +717,8 @@ count_collision(const struct st_hash_type *type)
|
|||
#error "REBUILD_THRESHOLD should be >= 2"
|
||||
#endif
|
||||
|
||||
static void rebuild_table_with(st_table *new_tab, st_table *tab);
|
||||
|
||||
/* Rebuild table TAB. Rebuilding removes all deleted bins and entries
|
||||
and can change size of the table entries and bins arrays.
|
||||
Rebuilding is implemented by creation of a new table or by
|
||||
|
@ -724,14 +726,6 @@ count_collision(const struct st_hash_type *type)
|
|||
static void
|
||||
rebuild_table(st_table *tab)
|
||||
{
|
||||
st_index_t i, ni;
|
||||
unsigned int size_ind;
|
||||
st_table *new_tab;
|
||||
st_table_entry *new_entries;
|
||||
st_table_entry *curr_entry_ptr;
|
||||
st_index_t *bins;
|
||||
st_index_t bin_ind;
|
||||
|
||||
if ((2 * tab->num_entries <= get_allocated_entries(tab)
|
||||
&& REBUILD_THRESHOLD * tab->num_entries > get_allocated_entries(tab))
|
||||
|| tab->num_entries < (1 << MINIMAL_POWER2)) {
|
||||
|
@ -739,17 +733,30 @@ rebuild_table(st_table *tab)
|
|||
tab->num_entries = 0;
|
||||
if (tab->bins != NULL)
|
||||
initialize_bins(tab);
|
||||
new_tab = tab;
|
||||
new_entries = tab->entries;
|
||||
rebuild_table_with(tab, tab);
|
||||
}
|
||||
else {
|
||||
st_table *new_tab;
|
||||
/* This allocation could trigger GC and compaction. If tab is the
|
||||
* gen_iv_tbl, then tab could have changed in size due to objects being
|
||||
* freed and/or moved. Do not store attributes of tab before this line. */
|
||||
new_tab = st_init_table_with_size(tab->type,
|
||||
2 * tab->num_entries - 1);
|
||||
new_entries = new_tab->entries;
|
||||
rebuild_table_with(new_tab, tab);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rebuild_table_with(st_table *new_tab, st_table *tab)
|
||||
{
|
||||
st_index_t i, ni;
|
||||
unsigned int size_ind;
|
||||
st_table_entry *new_entries;
|
||||
st_table_entry *curr_entry_ptr;
|
||||
st_index_t *bins;
|
||||
st_index_t bin_ind;
|
||||
|
||||
new_entries = new_tab->entries;
|
||||
|
||||
ni = 0;
|
||||
bins = new_tab->bins;
|
||||
|
@ -2296,4 +2303,15 @@ rb_st_nth_key(st_table *tab, st_index_t index)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
rb_st_compact_table(st_table *tab)
|
||||
{
|
||||
st_index_t num = tab->num_entries;
|
||||
if (REBUILD_THRESHOLD * num <= get_allocated_entries(tab)) {
|
||||
/* Compaction: */
|
||||
st_table *new_tab = st_init_table_with_size(tab->type, 2 * num);
|
||||
rebuild_table_with(new_tab, tab);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue