diff options
author | tompng (tomoya ishida) <tomoyapenguin@gmail.com> | 2021-04-11 19:04:31 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2021-04-11 19:05:26 +0900 |
commit | 9f9045123efefbd11dd397b4d59596290765feec (patch) | |
tree | 7b7b4d76d96ca6be82e7c4d26eb3f5e161ea0d18 /st.c | |
parent | 60bdf03b6d982777656acc11bdeb2ca4b4c3f1ef (diff) | |
download | ruby-9f9045123efefbd11dd397b4d59596290765feec.tar.gz |
st.c: skip all deleted entries [Bug #17779]
Update the start entry skipping all already deleted entries.
Fixes performance issue of `Hash#first` in a certain case.
Diffstat (limited to 'st.c')
-rw-r--r-- | st.c | 9 |
1 files changed, 7 insertions, 2 deletions
@@ -1244,8 +1244,13 @@ update_range_for_deleted(st_table *tab, st_index_t n) { /* Do not update entries_bound here. Otherwise, we can fill all bins by deleted entry value before rebuilding the table. */ - if (tab->entries_start == n) - tab->entries_start = n + 1; + if (tab->entries_start == n) { + st_index_t start = n + 1; + st_index_t bound = tab->entries_bound; + st_table_entry *entries = tab->entries; + while (start < bound && DELETED_ENTRY_P(&entries[start])) start++; + tab->entries_start = start; + } } /* Delete entry with KEY from table TAB, set up *VALUE (unless |