diff --git a/sp_ar.c b/sp_ar.c index e11da5c85641d0..52d6ad73e2d2a6 100644 --- a/sp_ar.c +++ b/sp_ar.c @@ -286,8 +286,8 @@ sa_free_table(sa_table *table) sa_table_dealloc(table); } -int -sa_delete(sa_table *table, sa_index_t key, st_data_t *value) +static int +sa_delete_internal(sa_table *table, sa_index_t key, st_data_t *value) { sa_index_t pos, prev_pos = ~0; sa_entry *entry; @@ -314,9 +314,6 @@ sa_delete(sa_table *table, sa_index_t key, st_data_t *value) } } table->num_entries--; - if (table->num_entries < table->num_bins / 4) { - resize(table); - } return 1; } if (entry->next == SA_LAST) break; @@ -330,6 +327,16 @@ sa_delete(sa_table *table, sa_index_t key, st_data_t *value) return 0; } +int +sa_delete(sa_table *table, sa_index_t key, st_data_t *value) +{ + int res = sa_delete_internal(table, key, value); + if (res == 1 && table->num_entries < table->num_bins / 4) { + resize(table); + } + return res; +} + int sa_foreach(register sa_table *table, int (*func)(), st_data_t arg) { @@ -344,7 +351,17 @@ sa_foreach(register sa_table *table, int (*func)(), st_data_t arg) st_data_t val = table->entries[i].value; ret = (*func)(key, val, arg); if (ret == SA_STOP) break; - /* else if (ret == SA_DELETE) TODO: implement */ + else if (ret == SA_DELETE) { + /* it is stable only in term of single iteration */ + /* do not parallel iteration, please */ + sa_index_t next = table->entries[i].next; + sa_delete_internal(table, key, NULL); + /* if item remains after deletion, then it is other item, */ + /* moved from `next` position */ + if (next > i + SA_OFFSET && table->entries[i].next != SA_EMPTY) { + i--; + } + } } } return 0;
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: