[Groonga-commit] ranguba/rroonga at 501e0b1 [master] Add :reuse_posting_object option to IndexCursor#each

Back to archive index

Kouhei Sutou null+****@clear*****
Sat Nov 8 22:17:42 JST 2014


Kouhei Sutou	2014-11-08 22:17:42 +0900 (Sat, 08 Nov 2014)

  New Revision: 501e0b1ac320d5abbdd2ed45bd75a73574fa3f4f
  https://github.com/ranguba/rroonga/commit/501e0b1ac320d5abbdd2ed45bd75a73574fa3f4f

  Message:
    Add :reuse_posting_object option to IndexCursor#each
    
    It is for performance. If posting object is reused, memory allocation
    and the number of GCs will be reduced.
    
    But reusing posting object isn't straightforward. So the option is
    disabled by default.

  Modified files:
    ext/groonga/rb-grn-index-cursor.c
    ext/groonga/rb-grn-posting.c
    ext/groonga/rb-grn.h
    test/test-index-cursor.rb

  Modified: ext/groonga/rb-grn-index-cursor.c (+32 -8)
===================================================================
--- ext/groonga/rb-grn-index-cursor.c    2014-11-07 01:36:23 +0900 (50f14a8)
+++ ext/groonga/rb-grn-index-cursor.c    2014-11-08 22:17:42 +0900 (58e89c5)
@@ -57,7 +57,8 @@ rb_grn_index_cursor_deconstruct (RbGrnIndexCursor *rb_grn_index_cursor,
 }
 
 static VALUE
-next_value (grn_ctx *context, grn_obj *cursor, VALUE rb_table, VALUE rb_lexicon)
+next_value (VALUE rb_posting,
+            grn_ctx *context, grn_obj *cursor, VALUE rb_table, VALUE rb_lexicon)
 {
     grn_posting *posting;
     grn_id term_id;
@@ -67,7 +68,12 @@ next_value (grn_ctx *context, grn_obj *cursor, VALUE rb_table, VALUE rb_lexicon)
         return Qnil;
     }
 
-    return rb_grn_posting_new(posting, term_id, rb_table, rb_lexicon);
+    if (NIL_P(rb_posting)) {
+        return rb_grn_posting_new(posting, term_id, rb_table, rb_lexicon);
+    } else {
+        rb_grn_posting_update(rb_posting, posting, term_id);
+        return rb_posting;
+    }
 }
 
 static VALUE
@@ -84,7 +90,7 @@ rb_grn_index_cursor_next (VALUE self)
         VALUE rb_lexicon;
         rb_table = rb_iv_get(self, "@table");
         rb_lexicon = rb_iv_get(self, "@lexicon");
-        rb_posting = next_value(context, cursor, rb_table, rb_lexicon);
+        rb_posting = next_value(Qnil, context, cursor, rb_table, rb_lexicon);
     }
 
     return rb_posting;
@@ -92,14 +98,24 @@ rb_grn_index_cursor_next (VALUE self)
 }
 
 static VALUE
-rb_grn_index_cursor_each (VALUE self)
+rb_grn_index_cursor_each (int argc, VALUE *argv, VALUE self)
 {
     grn_obj *cursor;
     grn_ctx *context;
+    grn_bool reuse_posting_object;
+    VALUE rb_options;
+    VALUE rb_reuse_posting_object;
     VALUE rb_table;
     VALUE rb_lexicon;
+    VALUE rb_posting = Qnil;
+
+    RETURN_ENUMERATOR(self, argc, argv);
+
+    rb_scan_args(argc, argv, "01", &rb_options);
 
-    RETURN_ENUMERATOR(self, 0, NULL);
+    rb_grn_scan_options(rb_options,
+                        "reuse_posting_object", &rb_reuse_posting_object,
+                        NULL);
 
     rb_grn_index_cursor_deconstruct(SELF(self), &cursor, &context,
                                     NULL, NULL, NULL, NULL);
@@ -114,9 +130,17 @@ rb_grn_index_cursor_each (VALUE self)
 
     rb_table = rb_iv_get(self, "@table");
     rb_lexicon = rb_iv_get(self, "@lexicon");
+    reuse_posting_object = RVAL2CBOOL(rb_reuse_posting_object);
+
+    if (reuse_posting_object) {
+        rb_posting = rb_grn_posting_new(NULL, GRN_ID_NIL, rb_table, rb_lexicon);
+    }
     while (GRN_TRUE) {
-        VALUE rb_posting;
-        rb_posting = next_value(context, cursor, rb_table, rb_lexicon);
+        if (!reuse_posting_object) {
+            rb_posting = Qnil;
+        }
+        rb_posting = next_value(rb_posting,
+                                context, cursor, rb_table, rb_lexicon);
         if (NIL_P(rb_posting)) {
             break;
         }
@@ -135,5 +159,5 @@ rb_grn_init_index_cursor (VALUE mGrn)
     rb_include_module(rb_cGrnIndexCursor, rb_mEnumerable);
 
     rb_define_method(rb_cGrnIndexCursor, "next", rb_grn_index_cursor_next, 0);
-    rb_define_method(rb_cGrnIndexCursor, "each", rb_grn_index_cursor_each, 0);
+    rb_define_method(rb_cGrnIndexCursor, "each", rb_grn_index_cursor_each, -1);
 }

  Modified: ext/groonga/rb-grn-posting.c (+26 -6)
===================================================================
--- ext/groonga/rb-grn-posting.c    2014-11-07 01:36:23 +0900 (d88a094)
+++ ext/groonga/rb-grn-posting.c    2014-11-08 22:17:42 +0900 (c94b4d5)
@@ -32,13 +32,15 @@ rb_grn_posting_new (grn_posting *posting, grn_id term_id,
 #define SET_PARAMETER(key, value) \
     rb_hash_aset(parameters, RB_GRN_INTERN(key), INT2NUM((value)))
 
-    SET_PARAMETER("record_id", posting->rid);
-    SET_PARAMETER("section_id", posting->sid);
+    if (posting) {
+        SET_PARAMETER("record_id", posting->rid);
+        SET_PARAMETER("section_id", posting->sid);
+        SET_PARAMETER("position", posting->pos);
+        SET_PARAMETER("term_frequency", posting->tf);
+        SET_PARAMETER("weight", posting->weight);
+        SET_PARAMETER("n_rest_postings", posting->rest);
+    }
     SET_PARAMETER("term_id", term_id);
-    SET_PARAMETER("position", posting->pos);
-    SET_PARAMETER("term_frequency", posting->tf);
-    SET_PARAMETER("weight", posting->weight);
-    SET_PARAMETER("n_rest_postings", posting->rest);
 
 #undef SET_PARAMETER
 
@@ -50,6 +52,24 @@ rb_grn_posting_new (grn_posting *posting, grn_id term_id,
 }
 
 void
+rb_grn_posting_update (VALUE self, grn_posting *posting, grn_id term_id)
+{
+#define SET_PARAMETER(key, value) \
+    rb_funcall(self, rb_intern(key "="), 1, INT2NUM(value));
+
+    SET_PARAMETER("record_id",       posting->rid);
+    SET_PARAMETER("section_id",      posting->sid);
+    SET_PARAMETER("position",        posting->pos);
+    SET_PARAMETER("term_frequency",  posting->tf);
+    SET_PARAMETER("weight",          posting->weight);
+    SET_PARAMETER("n_rest_postings", posting->rest);
+
+    SET_PARAMETER("term_id",         term_id);
+
+#undef SET_PARAMETER
+}
+
+void
 rb_grn_init_posting (VALUE mGrn)
 {
     rb_cGrnPosting = rb_const_get(mGrn, rb_intern("Posting"));

  Modified: ext/groonga/rb-grn.h (+3 -0)
===================================================================
--- ext/groonga/rb-grn.h    2014-11-07 01:36:23 +0900 (57fc256)
+++ ext/groonga/rb-grn.h    2014-11-08 22:17:42 +0900 (4227588)
@@ -568,6 +568,9 @@ VALUE          rb_grn_posting_new                   (grn_posting *posting,
                                                      grn_id term_id,
                                                      VALUE rb_table,
                                                      VALUE rb_lexicon);
+void           rb_grn_posting_update                (VALUE rb_posting,
+                                                     grn_posting *posting,
+                                                     grn_id term_id);
 
 VALUE          rb_grn_tokyo_geo_point_new           (int   latitude,
                                                      int   longitude);

  Modified: test/test-index-cursor.rb (+21 -1)
===================================================================
--- test/test-index-cursor.rb    2014-11-07 01:36:23 +0900 (1a39e5f)
+++ test/test-index-cursor.rb    2014-11-08 22:17:42 +0900 (c0ea294)
@@ -1,4 +1,4 @@
-# Copyright (C) 2012  Kouhei Sutou <kou �� clear-code.com>
+# Copyright (C) 2012-2014  Kouhei Sutou <kou �� clear-code.com>
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -66,6 +66,26 @@ class IndexCursorTest < Test::Unit::TestCase
     assert_true(opened)
   end
 
+  def test_each_reuse_posting_object
+    opened = false
+    @terms.open_cursor do |table_cursor|
+      @content_index.open_cursor(table_cursor) do |cursor|
+        posting_object_ids = []
+        postings = []
+        cursor.each(:reuse_posting_object => true) do |posting|
+          posting_object_ids << posting.object_id
+          postings << posting.to_hash
+        end
+        assert_equal([posting_object_ids.first] * posting_object_ids.size,
+                     posting_object_ids)
+        assert_equal(expected_postings, postings)
+        opened = true
+      end
+    end
+
+    assert_true(opened)
+  end
+
   def test_record
     record = nil
     @terms.open_cursor do |table_cursor|
-------------- next part --------------
HTML����������������������������...
下載 



More information about the Groonga-commit mailing list
Back to archive index