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

ruby-changes:35774

From: normal <ko1@a...>
Date: Thu, 9 Oct 2014 16:16:26 +0900 (JST)
Subject: [ruby-changes:35774] normal:r47856 (trunk): st: test packed-to-unpacked transitions during iteration

normal	2014-10-09 16:16:19 +0900 (Thu, 09 Oct 2014)

  New Revision: 47856

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=47856

  Log:
    st: test packed-to-unpacked transitions during iteration
    
    The st_foreach and st_foreach_check functions support transitioning
    from a packed to an unpacked state during iteration.  However, this
    functionality did not get exercised by the current test suite until
    now.  This should help us prevent breakage when making modifications
    to st.
    
    * ext/-test-/st/foreach/extconf.rb: new file
    * ext/-test-/st/foreach/foreach.c: ditto
    * test/-ext-/st/test_foreach.rb: ditto
      [Feature #10321]

  Added directories:
    trunk/ext/-test-/st/foreach/
  Added files:
    trunk/ext/-test-/st/foreach/extconf.rb
    trunk/ext/-test-/st/foreach/foreach.c
    trunk/test/-ext-/st/test_foreach.rb
  Modified files:
    trunk/ChangeLog
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 47855)
+++ ChangeLog	(revision 47856)
@@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Oct  9 16:15:26 2014  Eric Wong  <e@8...>
+
+	* ext/-test-/st/foreach/extconf.rb: new file
+	* ext/-test-/st/foreach/foreach.c: ditto
+	* test/-ext-/st/test_foreach.rb: ditto
+	  [Feature #10321]
+
 Thu Oct  9 12:40:28 2014  Eric Wong  <e@8...>
 
 	* benchmark/bm_hash_aref_sym*.rb: force static symbols
Index: ext/-test-/st/foreach/extconf.rb
===================================================================
--- ext/-test-/st/foreach/extconf.rb	(revision 0)
+++ ext/-test-/st/foreach/extconf.rb	(revision 47856)
@@ -0,0 +1 @@
+create_makefile("-test-/st/foreach")
Index: ext/-test-/st/foreach/foreach.c
===================================================================
--- ext/-test-/st/foreach/foreach.c	(revision 0)
+++ ext/-test-/st/foreach/foreach.c	(revision 47856)
@@ -0,0 +1,175 @@ https://github.com/ruby/ruby/blob/trunk/ext/-test-/st/foreach/foreach.c#L1
+#include <ruby.h>
+#include <ruby/st.h>
+
+static st_data_t expect_size = 32;
+struct checker {
+    st_table *tbl;
+    st_index_t nr;
+    VALUE test;
+};
+
+static void
+force_unpack_check(struct checker *c, st_data_t key, st_data_t val)
+{
+    if (c->nr == 0) {
+	st_data_t i;
+
+	if (!c->tbl->entries_packed) rb_bug("should be packed\n");
+
+	/* force unpacking during iteration: */
+	for (i = 1; i < expect_size; i++)
+	    st_add_direct(c->tbl, i, i);
+
+	if (c->tbl->entries_packed) rb_bug("should be unpacked\n");
+    }
+
+    if (key != c->nr) {
+	rb_bug("unexpected key: %lu (expected %lu)\n", key, c->nr);
+    }
+    if (val != c->nr) {
+	rb_bug("unexpected val: %lu (expected %lu)\n", val, c->nr);
+    }
+
+    c->nr++;
+}
+
+static int
+unp_fec_i(st_data_t key, st_data_t val, st_data_t args, int error)
+{
+    struct checker *c = (struct checker *)args;
+
+    if (error) {
+	if (c->test == ID2SYM(rb_intern("delete2")))
+	    return ST_STOP;
+
+	rb_bug("unexpected error");
+    }
+
+    force_unpack_check(c, key, val);
+
+    if (c->test == ID2SYM(rb_intern("check"))) {
+	return ST_CHECK;
+    }
+    if (c->test == ID2SYM(rb_intern("delete1"))) {
+	if (c->nr == 1) return ST_DELETE;
+	return ST_CHECK;
+    }
+    if (c->test == ID2SYM(rb_intern("delete2"))) {
+	if (c->nr == 1) {
+	    st_data_t k = 0;
+	    st_data_t v;
+
+	    if (!st_delete(c->tbl, &k, &v)) {
+		rb_bug("failed to delete\n");
+	    }
+	    if (v != 0) {
+		rb_bug("unexpected value deleted: %lu (expected 0)", v);
+	    }
+	}
+	return ST_CHECK;
+    }
+
+    rb_raise(rb_eArgError, "unexpected arg: %+"PRIsVALUE, c->test);
+}
+
+static VALUE
+unp_fec(VALUE self, VALUE test)
+{
+    st_table *tbl = st_init_numtable();
+    struct checker c;
+
+    c.tbl = tbl;
+    c.nr = 0;
+    c.test = test;
+
+    st_add_direct(tbl, 0, 0);
+
+    if (!tbl->entries_packed) rb_bug("should still be packed\n");
+
+    st_foreach_check(tbl, unp_fec_i, (st_data_t)&c, -1);
+
+    if (c.test == ID2SYM(rb_intern("delete2"))) {
+	if (c.nr != 1) {
+	    rb_bug("mismatched iteration: %lu (expected 1)\n", c.nr);
+	}
+    }
+    else if (c.nr != expect_size) {
+	rb_bug("mismatched iteration: %lu (expected %lu)\n",
+		c.nr, expect_size);
+    }
+
+    if (tbl->entries_packed) rb_bug("should be unpacked\n");
+
+    st_free_table(tbl);
+
+    return Qnil;
+}
+
+static int
+unp_fe_i(st_data_t key, st_data_t val, st_data_t args, int error)
+{
+    struct checker *c = (struct checker *)args;
+
+    force_unpack_check(c, key, val);
+    if (c->test == ID2SYM(rb_intern("unpacked"))) {
+	return ST_CONTINUE;
+    }
+    else if (c->test == ID2SYM(rb_intern("unpack_delete"))) {
+	if (c->nr == 1) {
+	    st_data_t k = 0;
+	    st_data_t v;
+
+	    if (!st_delete(c->tbl, &k, &v)) {
+		rb_bug("failed to delete\n");
+	    }
+	    if (v != 0) {
+		rb_bug("unexpected value deleted: %lu (expected 0)", v);
+	    }
+	    return ST_CONTINUE;
+	}
+	rb_bug("should never get here\n");
+    }
+
+    rb_raise(rb_eArgError, "unexpected arg: %+"PRIsVALUE, c->test);
+}
+
+static VALUE
+unp_fe(VALUE self, VALUE test)
+{
+    st_table *tbl = st_init_numtable();
+    struct checker c;
+
+    c.tbl = tbl;
+    c.nr = 0;
+    c.test = test;
+
+    st_add_direct(tbl, 0, 0);
+
+    if (!tbl->entries_packed) rb_bug("should still be packed\n");
+
+    st_foreach(tbl, unp_fe_i, (st_data_t)&c);
+
+    if (c.test == ID2SYM(rb_intern("unpack_delete"))) {
+	if (c.nr != 1) {
+	    rb_bug("mismatched iteration: %lu (expected 1)\n", c.nr);
+	}
+    }
+    else if (c.nr != expect_size) {
+	rb_bug("mismatched iteration: %lu (expected %lu)\n",
+		c.nr, expect_size);
+    }
+
+    if (tbl->entries_packed) rb_bug("should be unpacked\n");
+
+    st_free_table(tbl);
+
+    return Qnil;
+}
+
+void
+Init_foreach(void)
+{
+    VALUE bug = rb_define_module("Bug");
+    rb_define_singleton_method(bug, "unp_st_foreach_check", unp_fec, 1);
+    rb_define_singleton_method(bug, "unp_st_foreach", unp_fe, 1);
+}
Index: test/-ext-/st/test_foreach.rb
===================================================================
--- test/-ext-/st/test_foreach.rb	(revision 0)
+++ test/-ext-/st/test_foreach.rb	(revision 47856)
@@ -0,0 +1,15 @@ https://github.com/ruby/ruby/blob/trunk/test/-ext-/st/test_foreach.rb#L1
+require 'test/unit'
+require '-test-/st/foreach'
+
+class Test_StForeachUnpack < Test::Unit::TestCase
+  def test_st_foreach_check_unpack
+    assert_nil Bug.unp_st_foreach_check(:check), "goto unpacked_continue"
+    assert_nil Bug.unp_st_foreach_check(:delete1), "goto unpacked"
+    assert_nil Bug.unp_st_foreach_check(:delete2), "goto deleted"
+  end
+
+  def test_st_foreach_unpack
+    assert_nil Bug.unp_st_foreach(:unpacked), "goto unpacked"
+    assert_nil Bug.unp_st_foreach(:unpack_delete), "if (!ptr) return 0"
+  end
+end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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