[Groonga-commit] groonga/groonga at 8375d68 [master] mrb: add Table#sort but not perfect :<

Back to archive index

Kouhei Sutou null+****@clear*****
Tue Feb 10 00:03:18 JST 2015


Kouhei Sutou	2015-02-10 00:03:18 +0900 (Tue, 10 Feb 2015)

  New Revision: 8375d68ff5ff8f3babec9fea4d723775887376b5
  https://github.com/groonga/groonga/commit/8375d68ff5ff8f3babec9fea4d723775887376b5

  Message:
    mrb: add Table#sort but not perfect :<
    
    TODO:
    
      * Refine it.

  Modified files:
    lib/mrb/mrb_table.c

  Modified: lib/mrb/mrb_table.c (+97 -0)
===================================================================
--- lib/mrb/mrb_table.c    2015-02-10 00:02:58 +0900 (049065e)
+++ lib/mrb/mrb_table.c    2015-02-10 00:03:18 +0900 (2b86fdb)
@@ -23,6 +23,8 @@
 #include <mruby/class.h>
 #include <mruby/data.h>
 #include <mruby/hash.h>
+#include <mruby/array.h>
+#include <mruby/string.h>
 
 #include "mrb_ctx.h"
 #include "mrb_table.h"
@@ -103,6 +105,99 @@ 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)
+{
+  grn_ctx *ctx = (grn_ctx *)mrb->ud;
+  grn_obj *table;
+  grn_obj *result = NULL;
+  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();
+
+  table = DATA_PTR(self);
+  mrb_get_args(mrb, "o|H", &mrb_keys, &mrb_options);
+
+  mrb_keys = mrb_convert_type(mrb, mrb_keys,
+                              MRB_TT_ARRAY, "Array", "to_ary");
+
+  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 = mrb_hash_get(mrb, mrb_sort_options,
+                                mrb_symbol_value(mrb_intern_lit(mrb, "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 =
+      mrb_hash_get(mrb, mrb_sort_options,
+                   mrb_symbol_value(mrb_intern_lit(mrb, "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;
+    }
+  }
+
+  if (!mrb_nil_p(mrb_options)) {
+    mrb_value mrb_offset;
+    mrb_value mrb_limit;
+
+    mrb_offset = mrb_hash_get(mrb, mrb_options,
+                              mrb_symbol_value(mrb_intern_lit(mrb, "offset")));
+    if (!mrb_nil_p(mrb_offset)) {
+      offset = mrb_fixnum(mrb_offset);
+    }
+
+    mrb_limit = mrb_hash_get(mrb, mrb_options,
+                             mrb_symbol_value(mrb_intern_lit(mrb, "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);
+  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);
+}
+
 void
 grn_mrb_table_init(grn_ctx *ctx)
 {
@@ -125,5 +220,7 @@ 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));
 }
 #endif
-------------- next part --------------
HTML����������������������������...
Download 



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