[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]