Kouhei Sutou
null+****@clear*****
Sun Jan 28 23:21:51 JST 2018
Kouhei Sutou 2018-01-28 23:21:51 +0900 (Sun, 28 Jan 2018) New Revision: 00b03e7e3ccea1ae28a1550e04210c27dca7498b https://github.com/ranguba/rroonga/commit/00b03e7e3ccea1ae28a1550e04210c27dca7498b Message: Add Groonga::ColumnCache Added files: ext/groonga/rb-grn-column-cache.c test/test-column-cache.rb Modified files: ext/groonga/rb-grn.h ext/groonga/rb-groonga.c Added: ext/groonga/rb-grn-column-cache.c (+171 -0) 100644 =================================================================== --- /dev/null +++ ext/groonga/rb-grn-column-cache.c 2018-01-28 23:21:51 +0900 (5b52dfb3) @@ -0,0 +1,171 @@ +/* -*- coding: utf-8; mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim: set sts=4 sw=4 ts=8 noet: */ +/* + Copyright (C) 2018 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 + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "rb-grn.h" + +/* + * Document-class: Groonga::ColumnCache + * + * This is a class for accelerating column value read. + * + * {Groonga::FixSizeColumn} is only supported for now. + * + * @since 7.1.1 + */ + +VALUE rb_cGrnColumnCache; + +static void +rb_grn_column_cache_mark(void *data) +{ + RbGrnColumnCache *column_cache = data; + + rb_gc_mark(column_cache->rb_column); +} + +static void +rb_grn_column_cache_free(void *data) +{ + RbGrnColumnCache *rb_column_cache = data; + + if (!rb_column_cache->column_cache) + return; + + GRN_OBJ_FIN(rb_column_cache->context, + &(rb_column_cache->buffer)); + grn_column_cache_close(rb_column_cache->context, + rb_column_cache->column_cache); +} + +static rb_data_type_t data_type = { + "Groonga::ColumnCache", + { + rb_grn_column_cache_mark, + rb_grn_column_cache_free, + NULL, + }, + NULL, + NULL, + RUBY_TYPED_FREE_IMMEDIATELY +}; + +static VALUE +rb_grn_column_cache_allocate (VALUE klass) +{ + return TypedData_Wrap_Struct(klass, &data_type, NULL); +} + +/* + * @overload initialize(column) + * @param column [Groonga::Column] The column to be cached. + * + * @return [Groonga::ColumnCache] Create a new column cache. + */ +static VALUE +rb_grn_column_cache_initialize (VALUE self, VALUE rb_column) +{ + RbGrnColumnCache *rb_grn_column_cache; + grn_ctx *context; + grn_obj *column; + grn_id range_id; + + rb_grn_column_cache = ALLOC(RbGrnColumnCache); + rb_grn_column_cache->self = self; + rb_grn_column_cache->context = NULL; + rb_grn_column_cache->rb_column = rb_column; + rb_grn_column_cache->column_cache = NULL; + DATA_PTR(self) = rb_grn_column_cache; + + column = RVAL2GRNCOLUMN(rb_column, &(rb_grn_column_cache->context)); + context = rb_grn_column_cache->context; + rb_grn_column_cache->column_cache = grn_column_cache_open(context, column); + if (!rb_grn_column_cache->column_cache) { + rb_raise(rb_eArgError, + "failed to create column cache: %s%s%" PRIsVALUE, + context->rc == GRN_SUCCESS ? "" : context->errbuf, + context->rc == GRN_SUCCESS ? "" : ": ", + rb_column); + } + + range_id = grn_obj_get_range(context, column); + GRN_VALUE_FIX_SIZE_INIT(&(rb_grn_column_cache->buffer), + GRN_OBJ_DO_SHALLOW_COPY, + range_id); + rb_grn_column_cache->range = grn_ctx_at(context, range_id); + rb_grn_column_cache->table = grn_ctx_at(context, column->header.domain); + + return Qnil; +} + +/* + * @overload [](id) + * @param id [Integer, Groonga::Record] The record ID for the + * column value. + * + * @return [Object] The value for the record ID. + */ +static VALUE +rb_grn_column_cache_array_reference (VALUE self, VALUE rb_id) +{ + RbGrnColumnCache *rb_grn_column_cache; + grn_id id; + void *value; + size_t value_size = 0; + + TypedData_Get_Struct(self, + RbGrnColumnCache, + &data_type, + rb_grn_column_cache); + + id = rb_grn_id_from_ruby_object(rb_id, + rb_grn_column_cache->context, + rb_grn_column_cache->table, + self); + value = grn_column_cache_ref(rb_grn_column_cache->context, + rb_grn_column_cache->column_cache, + id, + &value_size); + rb_grn_context_check(rb_grn_column_cache->context, self); + GRN_TEXT_SET_REF(&(rb_grn_column_cache->buffer), + value, + value_size); + + return GRNBULK2RVAL(rb_grn_column_cache->context, + &(rb_grn_column_cache->buffer), + rb_grn_column_cache->range, + self); +} + +void +rb_grn_init_column_cache (VALUE mGrn) +{ + rb_cGrnColumnCache = + rb_define_class_under(mGrn, "ColumnCache", rb_cData); + + rb_define_alloc_func(rb_cGrnColumnCache, rb_grn_column_cache_allocate); + + rb_define_method(rb_cGrnColumnCache, + "initialize", + rb_grn_column_cache_initialize, + 1); + rb_define_method(rb_cGrnColumnCache, + "[]", + rb_grn_column_cache_array_reference, + 1); +} Modified: ext/groonga/rb-grn.h (+15 -1) =================================================================== --- ext/groonga/rb-grn.h 2018-01-25 17:24:56 +0900 (14e3d967) +++ ext/groonga/rb-grn.h 2018-01-28 23:21:51 +0900 (c71a74e0) @@ -1,6 +1,6 @@ /* -*- coding: utf-8; mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* - Copyright (C) 2009-2017 Kouhei Sutou <kou �� clear-code.com> + Copyright (C) 2009-2018 Kouhei Sutou <kou �� clear-code.com> Copyright (C) 2015-2017 Masafumi Yokoyama <yokoyama �� clear-code.com> This library is free software; you can redistribute it and/or @@ -248,6 +248,18 @@ struct _RbGrnPlugin grn_id id; }; +typedef struct _RbGrnColumnCache RbGrnColumnCache; +struct _RbGrnColumnCache +{ + VALUE self; + grn_ctx *context; + VALUE rb_column; + grn_column_cache *column_cache; + grn_obj buffer; + grn_obj *range; + grn_obj *table; +}; + RB_GRN_VAR grn_bool rb_grn_exited; RB_GRN_VAR VALUE rb_eGrnError; @@ -306,6 +318,7 @@ RB_GRN_VAR VALUE rb_cGrnIndex; RB_GRN_VAR VALUE rb_mGrnRequestCanceler; RB_GRN_VAR VALUE rb_mGrnRequestTimer; RB_GRN_VAR VALUE rb_cGrnRequestTimerID; +RB_GRN_VAR VALUE rb_cGrnColumnCache; void rb_grn_init_utils (VALUE mGrn); void rb_grn_init_exception (VALUE mGrn); @@ -369,6 +382,7 @@ void rb_grn_init_request_timer_id (VALUE mGrn); void rb_grn_init_id (VALUE mGrn); void rb_grn_init_name (VALUE mGrn); void rb_grn_init_default_cache (VALUE mGrn); +void rb_grn_init_column_cache (VALUE mGrn); VALUE rb_grn_rc_to_exception (grn_rc rc); void rb_grn_rc_check (grn_rc rc, Modified: ext/groonga/rb-groonga.c (+2 -1) =================================================================== --- ext/groonga/rb-groonga.c 2018-01-25 17:24:56 +0900 (211e67fc) +++ ext/groonga/rb-groonga.c 2018-01-28 23:21:51 +0900 (68a2052d) @@ -1,6 +1,6 @@ /* -*- coding: utf-8; mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* - Copyright (C) 2009-2016 Kouhei Sutou <kou �� clear-code.com> + Copyright (C) 2009-2018 Kouhei Sutou <kou �� clear-code.com> Copyright (C) 2016 Masafumi Yokoyama <yokoyama �� clear-code.com> This library is free software; you can redistribute it and/or @@ -257,4 +257,5 @@ Init_groonga (void) rb_grn_init_id(mGrn); rb_grn_init_name(mGrn); rb_grn_init_default_cache(mGrn); + rb_grn_init_column_cache(mGrn); } Added: test/test-column-cache.rb (+45 -0) 100644 =================================================================== --- /dev/null +++ test/test-column-cache.rb 2018-01-28 23:21:51 +0900 (1a5df65c) @@ -0,0 +1,45 @@ +# Copyright (C) 2018 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 +# License version 2.1 as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +class ColumnCacheTest < Test::Unit::TestCase + include GroongaTestUtils + + def setup + setup_database + + setup_users_table + end + + def setup_users_table + Groonga::Schema.define do |schema| + schema.create_table("Users", :type => :hash) do |table| + table.integer32("age") + end + end + + @users = context["Users"] + @users.add("alice", :age => 9) + @users.add("bob", :age => 19) + @users.add("chris", :age => 29) + + @age =****@users*****("age") + end + + def test_array_reference + column_cache = Groonga::ColumnCache.new(@age) + assert_equal(@users.collect(&:age), + @users.collect {|user| column_cache[user]}) + end +end -------------- next part -------------- HTML����������������������������... URL: https://lists.osdn.me/mailman/archives/groonga-commit/attachments/20180128/f4a7edbe/attachment-0001.htm