summaryrefslogtreecommitdiff
path: root/st.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-08-24 07:36:02 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-08-24 07:36:02 +0000
commit355e0f4efd94526c6de4afed0c5b2bd6992b19ac (patch)
tree4f91494b3726253e1dc9e7afd7d6061f63bc992a /st.c
parent16fc2951b1a52c35a81662cd4380f7b022c525a9 (diff)
* st.c (st_delete_safe): deals with packed entries.
[ruby-core:25080] * st.c (st_cleanup_safe): ditto. [ruby-core:25081] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24637 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'st.c')
-rw-r--r--st.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/st.c b/st.c
index 01f2a43..7866d03 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) {