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����������������������������... 下載