summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--st.c28
2 files changed, 35 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index e89b47ab90..414a1e01e1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Mon Aug 24 16:35:57 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * st.c (st_delete_safe): deals with packed entries.
+ [ruby-core:25080]
+
+ * st.c (st_cleanup_safe): ditto. [ruby-core:25081]
+
Mon Aug 24 13:24:07 2009 NAKAMURA Usaku <usa@ruby-lang.org>
* win32/Makefile.sub (MAKEDIRS): define.
diff --git a/st.c b/st.c
index 01f2a43dc4..7866d03e45 100644
--- a/st.c
+++ b/st.c
@@ -624,6 +624,19 @@ st_delete_safe(register st_table *table, register st_data_t *key, st_data_t *val
unsigned int hash_val;
register st_table_entry *ptr;
+ if (table->entries_packed) {
+ st_index_t i;
+ for (i = 0; i < table->num_entries; i++) {
+ if ((st_data_t)table->bins[i*2] == *key) {
+ if (value != 0) *value = (st_data_t)table->bins[i*2+1];
+ table->bins[i*2] = (void *)never;
+ return 1;
+ }
+ }
+ if (value != 0) *value = 0;
+ return 0;
+ }
+
hash_val = do_hash_bin(*key, table);
ptr = table->bins[hash_val];
@@ -647,6 +660,21 @@ st_cleanup_safe(st_table *table, st_data_t never)
st_table_entry *ptr, **last, *tmp;
st_index_t i;
+ if (table->entries_packed) {
+ st_index_t i = 0, j = 0;
+ while ((st_data_t)table->bins[i*2] != never) {
+ if (i++ == table->num_entries) return;
+ }
+ for (j = i; ++i < table->num_entries;) {
+ if ((st_data_t)table->bins[i*2] == never) continue;
+ table->bins[j*2] = table->bins[i*2];
+ table->bins[j*2+1] = table->bins[i*2+1];
+ j++;
+ }
+ table->num_entries = j;
+ return;
+ }
+
for (i = 0; i < table->num_bins; i++) {
ptr = *(last = &table->bins[i]);
while (ptr != 0) {