aboutsummaryrefslogtreecommitdiffstats
path: root/st.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-03-29 07:36:12 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-03-29 07:36:12 +0000
commit30cea657676db0ba703ae769fed4eafd5abc27fc (patch)
tree0f607ae4ea699393cb7ae9bfdf97cb600c30112c /st.c
parent95b30b0d07c40a3f7e0f0d8c74b1ae058034c8ad (diff)
downloadruby-30cea657676db0ba703ae769fed4eafd5abc27fc.tar.gz
* st.c (st_update): add existing parameter to the callback function.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35170 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'st.c')
-rw-r--r--st.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/st.c b/st.c
index ad943e925d..bb802cfd22 100644
--- a/st.c
+++ b/st.c
@@ -825,12 +825,12 @@ st_cleanup_safe(st_table *table, st_data_t never)
}
int
-st_update(st_table *table, st_data_t key, int (*func)(st_data_t key, st_data_t *value, st_data_t arg), st_data_t arg)
+st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg)
{
st_index_t hash_val, bin_pos;
register st_table_entry *ptr, **last, *tmp;
- st_data_t value;
- int retval;
+ st_data_t value = 0;
+ int retval, existing = 0;
hash_val = do_hash(key, table);
@@ -838,38 +838,49 @@ st_update(st_table *table, st_data_t key, int (*func)(st_data_t key, st_data_t *
st_index_t i = find_packed_index(table, hash_val, key);
if (i < table->real_entries) {
value = PVAL(table, i);
- retval = (*func)(key, &value, arg);
+ existing = 1;
+ }
+ {
+ retval = (*func)(key, &value, arg, existing);
if (!table->entries_packed) {
FIND_ENTRY(table, ptr, hash_val, bin_pos);
- if (ptr == 0) return 0;
goto unpacked;
}
switch (retval) {
case ST_CONTINUE:
+ if (!existing) {
+ add_packed_direct(table, key, value, hash_val);
+ break;
+ }
PVAL_SET(table, i, value);
break;
case ST_DELETE:
+ if (!existing) break;
remove_packed_entry(table, i);
}
- return 1;
}
- return 0;
+ return existing;
}
FIND_ENTRY(table, ptr, hash_val, bin_pos);
- if (ptr == 0) {
- return 0;
- }
- else {
+ if (ptr != 0) {
value = ptr->record;
- retval = (*func)(ptr->key, &value, arg);
+ existing = 1;
+ }
+ {
+ retval = (*func)(ptr->key, &value, arg, existing);
unpacked:
switch (retval) {
case ST_CONTINUE:
+ if (!existing) {
+ add_direct(table, key, value, hash_val, hash_val % table->num_bins);
+ break;
+ }
ptr->record = value;
break;
case ST_DELETE:
+ if (!existing) break;
last = &table->bins[bin_pos];
for (; (tmp = *last) != 0; last = &tmp->next) {
if (ptr == tmp) {
@@ -882,7 +893,7 @@ st_update(st_table *table, st_data_t key, int (*func)(st_data_t key, st_data_t *
}
break;
}
- return 1;
+ return existing;
}
}