[Groonga-commit] ranguba/rroonga at 9a7b309 [master] Support opening index cursor by term ID

Back to archive index

Kouhei Sutou null+****@clear*****
Tue Feb 7 19:54:49 JST 2017


Kouhei Sutou	2017-02-07 19:54:49 +0900 (Tue, 07 Feb 2017)

  New Revision: 9a7b309c7beaddfb41a369a5d9c90ab64134cfe9
  https://github.com/ranguba/rroonga/commit/9a7b309c7beaddfb41a369a5d9c90ab64134cfe9

  Message:
    Support opening index cursor by term ID

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

  Modified: ext/groonga/rb-grn-index-column.c (+47 -12)
===================================================================
--- ext/groonga/rb-grn-index-column.c    2017-02-07 17:52:47 +0900 (41e1d3b)
+++ ext/groonga/rb-grn-index-column.c    2017-02-07 19:54:49 +0900 (de9600f)
@@ -933,6 +933,12 @@ rb_grn_index_column_medium_p (VALUE self)
     return CBOOL2RVAL(flags & GRN_OBJ_INDEX_MEDIUM);
 }
 
+static VALUE
+call_close (VALUE object)
+{
+    return rb_funcall(object, rb_intern("close"), 0);
+}
+
 /*
  * Opens cursor to iterate posting in the index column.
  *
@@ -959,12 +965,12 @@ rb_grn_index_column_open_cursor (int argc, VALUE *argv, VALUE self)
     grn_obj          *column;
     grn_column_flags  column_flags;
     grn_obj          *range_object;
-    grn_table_cursor *table_cursor;
+    grn_table_cursor *table_cursor = NULL;
+    grn_id            term_id = GRN_ID_NIL;
     grn_id            rid_min = GRN_ID_NIL;
     grn_id            rid_max = GRN_ID_MAX;
     int               flags   = 0;
-    grn_obj          *index_cursor;
-    VALUE             rb_table_cursor;
+    VALUE             rb_table_cursor_or_term_id;
     VALUE             options;
     VALUE             rb_with_section, rb_with_weight, rb_with_position;
     VALUE             rb_table;
@@ -977,16 +983,20 @@ rb_grn_index_column_open_cursor (int argc, VALUE *argv, VALUE self)
                                     NULL, &range_object,
                                     NULL, NULL);
 
-    rb_scan_args(argc, argv, "11", &rb_table_cursor, &options);
+    rb_scan_args(argc, argv, "11", &rb_table_cursor_or_term_id, &options);
     rb_grn_scan_options(options,
                         "with_section", &rb_with_section,
                         "with_weight", &rb_with_weight,
                         "with_position", &rb_with_position,
                         NULL);
 
-    table_cursor = RVAL2GRNTABLECURSOR(rb_table_cursor, NULL);
+    if (CBOOL2RVAL(rb_obj_is_kind_of(rb_table_cursor_or_term_id, rb_cInteger))) {
+        term_id = NUM2UINT(rb_table_cursor_or_term_id);
+    } else {
+        table_cursor = RVAL2GRNTABLECURSOR(rb_table_cursor_or_term_id, NULL);
+    }
     rb_table     = GRNOBJECT2RVAL(Qnil, context, range_object, GRN_FALSE);
-    rb_lexicon   = rb_iv_get(rb_table_cursor, "@table");
+    rb_lexicon   = rb_funcall(self, rb_intern("table"), 0);
 
     column_flags = grn_column_get_flags(context, column);
 
@@ -1003,18 +1013,43 @@ rb_grn_index_column_open_cursor (int argc, VALUE *argv, VALUE self)
     }
 
     if (NIL_P(rb_with_position)) {
-        flags |= column_flags & GRN_OBJ_WITH_POSITION;
+        /* TODO: Remove this check. Require Groonga 7.0.1. */
+        if (table_cursor) {
+            flags |= column_flags & GRN_OBJ_WITH_POSITION;
+        }
     } else if (RVAL2CBOOL(rb_with_position)) {
         flags |= GRN_OBJ_WITH_POSITION;
     }
 
-    index_cursor = grn_index_cursor_open(context, table_cursor,
-                                         column, rid_min, rid_max, flags);
-
-    rb_cursor = GRNINDEXCURSOR2RVAL(context, index_cursor, rb_table, rb_lexicon);
+    if (table_cursor) {
+        grn_obj *index_cursor;
+        index_cursor = grn_index_cursor_open(context, table_cursor,
+                                             column, rid_min, rid_max, flags);
+        rb_cursor = GRNINDEXCURSOR2RVAL(context,
+                                        index_cursor,
+                                        rb_table,
+                                        rb_lexicon);
+    } else {
+        grn_ii *ii = (grn_ii *)column;
+        grn_ii_cursor *ii_cursor;
+        ii_cursor = grn_ii_cursor_open(context,
+                                       ii,
+                                       term_id,
+                                       rid_min,
+                                       rid_max,
+                                       /* TODO: Require Groonga 7.0.1. */
+                                       0, /* grn_ii_get_n_elements(context, ii), */
+                                       flags);
+        rb_cursor = rb_grn_inverted_index_cursor_to_ruby_object(context,
+                                                                ii_cursor,
+                                                                term_id,
+                                                                flags,
+                                                                rb_table,
+                                                                rb_lexicon);
+    }
 
     if (rb_block_given_p())
-        return rb_ensure(rb_yield, rb_cursor, rb_grn_object_close, rb_cursor);
+        return rb_ensure(rb_yield, rb_cursor, call_close, rb_cursor);
     else
         return rb_cursor;
 }

  Modified: ext/groonga/rb-grn-inverted-index-cursor.c (+62 -7)
===================================================================
--- ext/groonga/rb-grn-inverted-index-cursor.c    2017-02-07 17:52:47 +0900 (1dac53c)
+++ ext/groonga/rb-grn-inverted-index-cursor.c    2017-02-07 19:54:49 +0900 (e43ba30)
@@ -27,6 +27,7 @@ struct _RbGrnInvertedIndexCursor
     grn_ctx *context;
     grn_ii_cursor *cursor;
     grn_id term_id;
+    int flags;
 };
 
 static VALUE rb_cGrnInvertedIndexCursor;
@@ -36,7 +37,7 @@ rb_grn_inverted_index_cursor_free(void *data)
 {
     RbGrnInvertedIndexCursor *rb_grn_cursor = data;
 
-    if (rb_grn_cursor->context) {
+    if (rb_grn_cursor->context && rb_grn_cursor->cursor) {
         grn_ii_cursor_close(rb_grn_cursor->context,
                             rb_grn_cursor->cursor);
     }
@@ -58,6 +59,8 @@ static const rb_data_type_t rb_grn_inverted_index_cursor_type = {
 VALUE
 rb_grn_inverted_index_cursor_to_ruby_object (grn_ctx *context,
                                              grn_ii_cursor *cursor,
+                                             grn_id term_id,
+                                             int flags,
                                              VALUE rb_table,
                                              VALUE rb_lexicon)
 {
@@ -72,9 +75,18 @@ rb_grn_inverted_index_cursor_to_ruby_object (grn_ctx *context,
     rb_grn_cursor->self = rb_cursor;
     rb_grn_cursor->context = context;
     rb_grn_cursor->cursor = cursor;
+    rb_grn_cursor->term_id = term_id;
+    rb_grn_cursor->flags = flags;
     rb_iv_set(rb_cursor, "@table", rb_table);
     rb_iv_set(rb_cursor, "@lexicon", rb_lexicon);
 
+    /* TODO: Require Groonga 7.0.1.
+    if (rb_grn_cursor->cursor &&
+        (rb_grn_cursor->flags & GRN_OBJ_WITH_POSITION)) {
+        grn_ii_cursor_next(context, cursor);
+    }
+    */
+
     return rb_cursor;
 }
 
@@ -84,10 +96,24 @@ next_value (VALUE rb_posting,
             VALUE rb_table,
             VALUE rb_lexicon)
 {
-    grn_posting *posting;
-
-    posting = grn_ii_cursor_next(rb_grn_cursor->context,
-                                 rb_grn_cursor->cursor);
+    grn_ctx *context = rb_grn_cursor->context;
+    grn_ii_cursor *cursor = rb_grn_cursor->cursor;
+    grn_posting *posting = NULL;
+
+    /* TODO: Require Groonga 7.0.1. */
+    /*
+    if (rb_grn_cursor->flags & GRN_OBJ_WITH_POSITION) {
+        posting = grn_ii_cursor_next_pos(context, cursor);
+        while (!posting && grn_ii_cursor_next(context, cursor)) {
+            posting = grn_ii_cursor_next_pos(context, cursor);
+            break;
+        }
+    } else {
+    */
+        posting = grn_ii_cursor_next(context, cursor);
+    /*
+    }
+    */
     if (!posting) {
         return Qnil;
     }
@@ -123,6 +149,10 @@ rb_grn_inverted_index_cursor_next (VALUE self)
                  self);
     }
 
+    if (!rb_grn_cursor->cursor) {
+        return Qnil;
+    }
+
     rb_table = rb_iv_get(self, "@table");
     rb_lexicon = rb_iv_get(self, "@lexicon");
     rb_posting = next_value(Qnil, rb_grn_cursor, rb_table, rb_lexicon);
@@ -160,6 +190,10 @@ rb_grn_inverted_index_cursor_each (int argc, VALUE *argv, VALUE self)
                  self);
     }
 
+    if (!rb_grn_cursor->cursor) {
+        return Qnil;
+    }
+
     rb_table = rb_iv_get(self, "@table");
     rb_lexicon = rb_iv_get(self, "@lexicon");
     reuse_posting_object = RVAL2CBOOL(rb_reuse_posting_object);
@@ -196,8 +230,10 @@ rb_grn_inverted_index_cursor_close (VALUE self)
                  self);
     }
 
-    grn_ii_cursor_close(rb_grn_cursor->context,
-                        rb_grn_cursor->cursor);
+    if (rb_grn_cursor->cursor) {
+        grn_ii_cursor_close(rb_grn_cursor->context,
+                            rb_grn_cursor->cursor);
+    }
     rb_grn_cursor->context = NULL;
     rb_grn_cursor->cursor = NULL;
 
@@ -205,6 +241,23 @@ rb_grn_inverted_index_cursor_close (VALUE self)
 
 }
 
+static VALUE
+rb_grn_inverted_index_cursor_is_closed (VALUE self)
+{
+    RbGrnInvertedIndexCursor *rb_grn_cursor;
+
+    TypedData_Get_Struct(self,
+                         RbGrnInvertedIndexCursor,
+                         &rb_grn_inverted_index_cursor_type,
+                         rb_grn_cursor);
+    if (rb_grn_cursor->context) {
+        return Qfalse;
+    } else {
+        return Qtrue;
+    }
+
+}
+
 void
 rb_grn_init_inverted_index_cursor (VALUE mGrn)
 {
@@ -218,4 +271,6 @@ rb_grn_init_inverted_index_cursor (VALUE mGrn)
                      rb_grn_inverted_index_cursor_each, -1);
     rb_define_method(rb_cGrnInvertedIndexCursor, "close",
                      rb_grn_inverted_index_cursor_close, 0);
+    rb_define_method(rb_cGrnInvertedIndexCursor, "closed?",
+                     rb_grn_inverted_index_cursor_is_closed, 0);
 }

  Modified: ext/groonga/rb-grn.h (+2 -0)
===================================================================
--- ext/groonga/rb-grn.h    2017-02-07 17:52:47 +0900 (adcde73)
+++ ext/groonga/rb-grn.h    2017-02-07 19:54:49 +0900 (9be30b3)
@@ -829,6 +829,8 @@ VALUE          rb_grn_index_cursor_to_ruby_object   (grn_ctx *context,
 VALUE          rb_grn_inverted_index_cursor_to_ruby_object
                                                     (grn_ctx *context,
                                                      grn_ii_cursor *cursor,
+                                                     grn_id term_id,
+                                                     int flags,
                                                      VALUE rb_table,
                                                      VALUE rb_lexicon);
 

  Modified: ext/groonga/rb-groonga.c (+1 -0)
===================================================================
--- ext/groonga/rb-groonga.c    2017-02-07 17:52:47 +0900 (430c25d)
+++ ext/groonga/rb-groonga.c    2017-02-07 19:54:49 +0900 (1601c86)
@@ -229,6 +229,7 @@ Init_groonga (void)
     rb_grn_init_table(mGrn);
     rb_grn_init_table_cursor(mGrn);
     rb_grn_init_index_cursor(mGrn);
+    rb_grn_init_inverted_index_cursor(mGrn);
     rb_grn_init_posting(mGrn);
     rb_grn_init_type(mGrn);
     rb_grn_init_procedure(mGrn);

  Modified: test/test-index-cursor.rb (+55 -15)
===================================================================
--- test/test-index-cursor.rb    2017-02-07 17:52:47 +0900 (97e3229)
+++ test/test-index-cursor.rb    2017-02-07 19:54:49 +0900 (55e67b6)
@@ -36,7 +36,27 @@ class IndexCursorTest < Test::Unit::TestCase
         assert_predicate(index_cursor, :closed?)
       end
 
-      assert_equal(expected_postings, postings)
+      assert_equal(expected_postings(:with_position => true),
+                   postings)
+    end
+
+    def test_term_id
+      postings = []
+      @terms.open_cursor do |table_cursor|
+        table_cursor.each do |term|
+          index_cursor = nil
+          @content_index.open_cursor(term.id) do |cursor|
+            cursor.each do |posting|
+              postings << posting.to_hash
+            end
+            index_cursor = cursor
+          end
+          assert_predicate(index_cursor, :closed?)
+        end
+      end
+
+      assert_equal(expected_postings(:with_position => false),
+                   postings)
     end
   end
 
@@ -151,20 +171,40 @@ class IndexCursorTest < Test::Unit::TestCase
     @articles.add("3", :content => "hello")
   end
 
-  def expected_postings
-    parameters = [:record_id, :section_id, :term_id, :position,
-                  :term_frequency, :weight, :n_rest_postings]
-
-    expected = [
-                [1, 1, 1, 0, 1, 0, 0],
-                [2, 1, 1, 1, 1, 0, 0],
-                [2, 1, 2, 0, 1, 0, 0],
-                [3, 1, 2, 2, 1, 0, 0],
-                [3, 1, 3, 0, 1, 0, 0],
-                [3, 1, 4, 1, 1, 0, 0],
-                [3, 1, 5, 3, 1, 0, 0],
-                [3, 1, 6, 4, 1, 0, 0]
-               ]
+  def expected_postings(options={})
+    parameters = [
+      :record_id,
+      :section_id,
+      :term_id,
+      :position,
+      :term_frequency,
+      :weight,
+      :n_rest_postings,
+    ]
+
+    if options[:with_position]
+      expected = [
+        [1, 1, 1, 0, 1, 0, 0],
+        [2, 1, 1, 1, 1, 0, 0],
+        [2, 1, 2, 0, 1, 0, 0],
+        [3, 1, 2, 2, 1, 0, 0],
+        [3, 1, 3, 0, 1, 0, 0],
+        [3, 1, 4, 1, 1, 0, 0],
+        [3, 1, 5, 3, 1, 0, 0],
+        [3, 1, 6, 4, 1, 0, 0]
+      ]
+    else
+      expected = [
+        [1, 1, 1, 0, 1, 0, 1],
+        [2, 1, 1, 0, 1, 0, 1],
+        [2, 1, 2, 0, 1, 0, 1],
+        [3, 1, 2, 0, 1, 0, 1],
+        [3, 1, 3, 0, 1, 0, 0],
+        [3, 1, 4, 1, 1, 0, 0],
+        [3, 1, 5, 3, 1, 0, 0],
+        [3, 1, 6, 4, 1, 0, 0]
+      ]
+    end
 
     create_hashes(parameters, expected)
   end
-------------- next part --------------
HTML����������������������������...
Download 



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