[Groonga-commit] ranguba/rroonga at 00b03e7 [master] Add Groonga::ColumnCache

Back to archive index

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 



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