[Groonga-commit] groonga/groonga at 6629adb [master] mrb: define Groonga::Table#sort in mruby

Back to archive index

Kouhei Sutou null+****@clear*****
Mon Jun 29 00:25:08 JST 2015


Kouhei Sutou	2015-06-29 00:25:08 +0900 (Mon, 29 Jun 2015)

  New Revision: 6629adb6c03fe1b83588d339828cc0c4952065f5
  https://github.com/groonga/groonga/commit/6629adb6c03fe1b83588d339828cc0c4952065f5

  Message:
    mrb: define Groonga::Table#sort in mruby

  Added files:
    lib/mrb/scripts/table.rb
  Modified files:
    lib/mrb/mrb_table.c
    lib/mrb/scripts/initialize/post.rb
    lib/mrb/scripts/sources.am

  Modified: lib/mrb/mrb_table.c (+14 -68)
===================================================================
--- lib/mrb/mrb_table.c    2015-06-29 00:24:10 +0900 (9dc4ee8)
+++ lib/mrb/mrb_table.c    2015-06-29 00:25:08 +0900 (7d245cf)
@@ -157,22 +157,21 @@ mrb_grn_table_select(mrb_state *mrb, mrb_value self)
   return grn_mrb_value_from_grn_obj(mrb, result);
 }
 
-/* TODO: Fix memory leak on error */
 static mrb_value
-mrb_grn_table_sort(mrb_state *mrb, mrb_value self)
+mrb_grn_table_sort_raw(mrb_state *mrb, mrb_value self)
 {
   grn_ctx *ctx = (grn_ctx *)mrb->ud;
   grn_obj *table;
-  grn_obj *result = NULL;
+  mrb_value mrb_keys;
   grn_table_sort_key *keys;
   int i, n_keys;
-  int offset = 0;
-  int limit = -1;
-  mrb_value mrb_keys;
-  mrb_value mrb_options = mrb_nil_value();
+  mrb_int offset;
+  mrb_int limit;
+  mrb_value mrb_result;
+  grn_obj *result;
 
   table = DATA_PTR(self);
-  mrb_get_args(mrb, "o|H", &mrb_keys, &mrb_options);
+  mrb_get_args(mrb, "oiio", &mrb_keys, &offset, &limit, &mrb_result);
 
   mrb_keys = mrb_convert_type(mrb, mrb_keys,
                               MRB_TT_ARRAY, "Array", "to_ary");
@@ -180,69 +179,16 @@ mrb_grn_table_sort(mrb_state *mrb, mrb_value self)
   n_keys = RARRAY_LEN(mrb_keys);
   keys = GRN_MALLOCN(grn_table_sort_key, n_keys);
   for (i = 0; i < n_keys; i++) {
-    mrb_value mrb_sort_options;
-    mrb_value mrb_sort_key;
-    mrb_value mrb_sort_order;
-
-    mrb_sort_options = RARRAY_PTR(mrb_keys)[i];
-    mrb_sort_key = grn_mrb_options_get_lit(mrb, mrb_sort_options, "key");
-    switch (mrb_type(mrb_sort_key)) {
-    case MRB_TT_STRING :
-      keys[i].key = grn_obj_column(ctx, table,
-                                   RSTRING_PTR(mrb_sort_key),
-                                   RSTRING_LEN(mrb_sort_key));
-      break;
-    case MRB_TT_SYMBOL :
-      {
-        const char *name;
-        mrb_int name_length;
-        name = mrb_sym2name_len(mrb, mrb_symbol(mrb_sort_key), &name_length);
-        keys[i].key = grn_obj_column(ctx, table, name, name_length);
-      }
-      break;
-    default :
-      /* TODO: free */
-      mrb_raisef(mrb, E_ARGUMENT_ERROR,
-                 "sort key must be string or symbol: %S",
-                 mrb_sort_key);
-      break;
-    }
-
-    keys[i].flags = 0;
-    mrb_sort_order = grn_mrb_options_get_lit(mrb, mrb_sort_options, "order");
-    if (mrb_nil_p(mrb_sort_order) ||
-        (mrb_symbol(mrb_sort_order) == mrb_intern_lit(mrb, "ascending"))) {
-      keys[i].flags |= GRN_TABLE_SORT_ASC;
-    } else {
-      keys[i].flags |= GRN_TABLE_SORT_DESC;
-    }
+    memcpy(&(keys[i]),
+           DATA_PTR(RARRAY_PTR(mrb_keys)[i]),
+           sizeof(grn_table_sort_key));
   }
-
-  if (!mrb_nil_p(mrb_options)) {
-    mrb_value mrb_offset;
-    mrb_value mrb_limit;
-
-    mrb_offset = grn_mrb_options_get_lit(mrb, mrb_options, "offset");
-    if (!mrb_nil_p(mrb_offset)) {
-      offset = mrb_fixnum(mrb_offset);
-    }
-
-    mrb_limit = grn_mrb_options_get_lit(mrb, mrb_options, "limit");
-    if (!mrb_nil_p(mrb_limit)) {
-      limit = mrb_fixnum(mrb_limit);
-    }
-  }
-
-  result = grn_table_create(ctx, NULL, 0, NULL, GRN_TABLE_NO_KEY,
-                            NULL, table);
+  result = DATA_PTR(mrb_result);
   grn_table_sort(ctx, table, offset, limit, result, keys, n_keys);
-  for (i = 0; i < n_keys; i++) {
-    grn_obj_unlink(ctx, keys[i].key);
-  }
   GRN_FREE(keys);
   grn_mrb_ctx_check(mrb);
 
-  return grn_mrb_value_from_grn_obj(mrb, result);
+  return mrb_result;
 }
 
 static mrb_value
@@ -343,8 +289,8 @@ grn_mrb_table_init(grn_ctx *ctx)
 
   mrb_define_method(mrb, klass, "select",
                     mrb_grn_table_select, MRB_ARGS_ARG(1, 1));
-  mrb_define_method(mrb, klass, "sort",
-                    mrb_grn_table_sort, MRB_ARGS_ARG(1, 1));
+  mrb_define_method(mrb, klass, "sort_raw",
+                    mrb_grn_table_sort_raw, MRB_ARGS_REQ(4));
 
   mrb_define_method(mrb, klass, "delete",
                     mrb_grn_table_delete, MRB_ARGS_REQ(1));

  Modified: lib/mrb/scripts/initialize/post.rb (+1 -0)
===================================================================
--- lib/mrb/scripts/initialize/post.rb    2015-06-29 00:24:10 +0900 (ea26a03)
+++ lib/mrb/scripts/initialize/post.rb    2015-06-29 00:25:08 +0900 (ccd4475)
@@ -6,6 +6,7 @@ require "writer"
 
 require "object"
 require "database"
+require "table"
 require "index_column"
 require "command"
 require "table_cursor"

  Modified: lib/mrb/scripts/sources.am (+1 -0)
===================================================================
--- lib/mrb/scripts/sources.am    2015-06-29 00:24:10 +0900 (5ddcba1)
+++ lib/mrb/scripts/sources.am    2015-06-29 00:25:08 +0900 (6fda018)
@@ -19,5 +19,6 @@ RUBY_SCRIPT_FILES =				\
 	scan_info_builder.rb			\
 	scan_info_data.rb			\
 	scan_info_search_index.rb		\
+	table.rb				\
 	table_cursor.rb				\
 	writer.rb

  Added: lib/mrb/scripts/table.rb (+77 -0) 100644
===================================================================
--- /dev/null
+++ lib/mrb/scripts/table.rb    2015-06-29 00:25:08 +0900 (0c81404)
@@ -0,0 +1,77 @@
+module Groonga
+  class Table
+    def sort(keys, options={})
+      offset = options[:offset] || 0
+      limit = options[:limit] || -1
+      ensure_sort_keys(keys) do |sort_keys|
+        sorted = Array.create("", self)
+        begin
+          sort_raw(sort_keys, offset, limit, sorted)
+        rescue Exception
+          sorted.close
+          raise
+        end
+        sorted
+      end
+    end
+
+    private
+    def ensure_sort_keys(keys)
+      if keys.is_a?(::Array) and keys.all? {|key| key.is_a?(TableSortKey)}
+        return yield(keys)
+      end
+
+      converted_keys = []
+
+      begin
+        keys = [keys] unless keys.is_a?(::Array)
+        sort_keys = keys.collect do |key|
+          ensure_sort_key(key, converted_keys)
+        end
+        yield(sort_keys)
+      ensure
+        converted_keys.each do |converted_key|
+          converted_key.close
+        end
+      end
+    end
+
+    def ensure_sort_key(key, converted_keys)
+      return key if key.is_a?(TableSortKey)
+
+      sort_key = TableSortKey.new
+      converted_keys << sort_key
+
+      key_name = nil
+      order = :ascending
+      offset = 0
+      if key.is_a?(::Hash)
+        key_name = key[:key]
+        order    = key[:order] || order
+        offset   = key[:offset] || offset
+      else
+        key_name = key
+      end
+
+      case key_name
+      when String
+        # Do nothing
+      when Symbol
+        key_name = key_name.to_s
+      else
+        message = "sort key name must be String or Symbol: " +
+                  "#{key_name.inspect}: #{key.inspect}"
+        raise ArgumentError, message
+      end
+
+      sort_key.key = find_column(key_name)
+      if order == :ascending
+        sort_key.flags = Groonga::TableSortFlags::ASCENDING
+      else
+        sort_key.flags = Groonga::TableSortFlags::DESCENDING
+      end
+      sort_key.offset = offset
+      sort_key
+    end
+  end
+end
-------------- next part --------------
HTML����������������������������...
Download 



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