ruby-changes:22411
From: nobu <ko1@a...>
Date: Tue, 7 Feb 2012 14:52:26 +0900 (JST)
Subject: [ruby-changes:22411] nobu:r34460 (trunk): * st.c (st_update): table can be unpacked in the callback.
nobu 2012-02-07 14:52:15 +0900 (Tue, 07 Feb 2012) New Revision: 34460 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=34460 Log: * st.c (st_update): table can be unpacked in the callback. Modified files: trunk/ChangeLog trunk/ext/-test-/st/numhash/numhash.c trunk/st.c trunk/test/-ext-/st/test_numhash.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 34459) +++ ChangeLog (revision 34460) @@ -1,5 +1,7 @@ -Tue Feb 7 14:29:16 2012 Nobuyoshi Nakada <nobu@r...> +Tue Feb 7 14:52:10 2012 Nobuyoshi Nakada <nobu@r...> + * st.c (st_update): table can be unpacked in the callback. + * st.c (st_foreach): should not yield same pair when checking after unpacking. Index: st.c =================================================================== --- st.c (revision 34459) +++ st.c (revision 34460) @@ -761,12 +761,21 @@ st_index_t hash_val, bin_pos; register st_table_entry *ptr, **last, *tmp; st_data_t value; + int retval; if (table->entries_packed) { st_index_t i = find_packed_index(table, key); if (i < table->num_entries) { value = PVAL(table, i); - switch ((*func)(key, &value, arg)) { + retval = (*func)(key, &value, arg); + if (!table->entries_packed) { + hash_val = do_hash(key, table); + bin_pos = hash_val % table->num_bins; + ptr = find_entry(table, key, hash_val, bin_pos); + if (ptr == 0) return 0; + goto unpacked; + } + switch (retval) { case ST_CONTINUE: PVAL_SET(table, i, value); break; @@ -787,7 +796,9 @@ } else { value = ptr->record; - switch ((*func)(ptr->key, &value, arg)) { + retval = (*func)(ptr->key, &value, arg); + unpacked: + switch (retval) { case ST_CONTINUE: ptr->record = value; break; Index: ext/-test-/st/numhash/numhash.c =================================================================== --- ext/-test-/st/numhash/numhash.c (revision 34459) +++ ext/-test-/st/numhash/numhash.c (revision 34460) @@ -57,6 +57,30 @@ return st_foreach((st_table *)DATA_PTR(self), numhash_i, self) ? Qtrue : Qfalse; } +static int +update_func(st_data_t key, st_data_t *value, st_data_t arg) +{ + VALUE ret = rb_yield_values(2, (VALUE)key, (VALUE)*value); + switch (ret) { + case Qfalse: + return ST_STOP; + case Qnil: + return ST_DELETE; + default: + *value = ret; + return ST_CONTINUE; + } +} + +static VALUE +numhash_update(VALUE self, VALUE key) +{ + if (st_update((st_table *)DATA_PTR(self), (st_data_t)key, update_func, 0)) + return Qtrue; + else + return Qfalse; +} + void Init_numhash(void) { @@ -66,4 +90,6 @@ rb_define_method(st, "[]", numhash_aref, 1); rb_define_method(st, "[]=", numhash_aset, 2); rb_define_method(st, "each", numhash_each, 0); + rb_define_method(st, "update", numhash_update, 1); } + Index: test/-ext-/st/test_numhash.rb =================================================================== --- test/-ext-/st/test_numhash.rb (revision 34459) +++ test/-ext-/st/test_numhash.rb (revision 34460) @@ -17,5 +17,11 @@ end assert_equal([*0..5], keys) end + + def test_update + assert_equal(true, @tbl.update(0) {@tbl[5] = :x}) + assert_equal(:x, @tbl[0]) + assert_equal(:x, @tbl[5]) + end end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/