diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-03-10 14:52:19 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-03-10 14:52:19 +0000 |
commit | a73d958c33904fdabac95f49d9834779ca33c599 () | |
tree | 18cde65b79b9002421da9848fcf35e4324a8ea67 /st.c | |
parent | efae6194582001cb12108bc101d22dc1ed9a660c (diff) |
* st.c: add st_foreach_check for fixing iteration over packed table
and st_delete_safe. ed by Sokolov Yura at https://.com/ruby/ruby/pull/84 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34963 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | st.c | 97 |
1 files changed, 85 insertions, 12 deletions
@@ -866,18 +866,19 @@ st_update(st_table *table, st_data_t key, int (*func)(st_data_t key, st_data_t * } int -st_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg) { st_table_entry *ptr, **last, *tmp; enum st_retval retval; st_index_t i; if (table->entries_packed) { - for (i = 0; i < table->real_entries; i++) { - st_data_t key, val; - key = PKEY(table, i); - val = PVAL(table, i); - retval = (*func)(key, val, arg); if (!table->entries_packed) { FIND_ENTRY(table, ptr, key, i); if (retval == ST_CHECK) { @@ -886,8 +887,11 @@ st_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg) } goto unpacked; } - switch (retval) { case ST_CHECK: /* check if hash is modified during iteration */ if (i != find_packed_index(table, key)) { goto deleted; } @@ -898,11 +902,11 @@ st_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg) return 0; case ST_DELETE: remove_packed_entry(table, i); - i--; - break; - } - } - return 0; } else { ptr = table->head; @@ -910,6 +914,8 @@ st_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg) if (ptr != 0) { do { i = ptr->hash % table->num_bins; retval = (*func)(ptr->key, ptr->record, arg); unpacked: @@ -949,6 +955,73 @@ st_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg) return 0; } #if 0 /* unused right now */ int st_reverse_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg) |