[Groonga-commit] groonga/groonga [master] table: add range_gap argument to group command.

Back to archive index

null+****@clear***** null+****@clear*****
2012年 6月 25日 (月) 20:15:37 JST


Daijiro MORI	2012-06-25 20:15:37 +0900 (Mon, 25 Jun 2012)

  New Revision: 0fb9016df97933ea6115d164ed2abaac2f441a5d
  https://github.com/groonga/groonga/commit/0fb9016df97933ea6115d164ed2abaac2f441a5d

  Log:
    table: add range_gap argument to group command.

  Modified files:
    lib/db.c
    lib/db.h
    plugins/table/table.c

  Modified: lib/db.c (+100 -0)
===================================================================
--- lib/db.c    2012-06-25 17:01:27 +0900 (7a2a1ed)
+++ lib/db.c    2012-06-25 20:15:37 +0900 (15520da)
@@ -2944,6 +2944,106 @@ accelerated_table_group(grn_ctx *ctx, grn_obj *table, grn_obj *key, grn_obj *res
 }
 
 grn_rc
+grn_table_group_with_range_gap(grn_ctx *ctx, grn_obj *table,
+                               grn_table_sort_key *group_key,
+                               grn_obj *res, uint32_t range_gap)
+{
+  grn_obj *key = group_key->key;
+  if (key->header.type == GRN_ACCESSOR) {
+    grn_accessor *a = (grn_accessor *)key;
+    if (a->action == GRN_ACCESSOR_GET_KEY &&
+        a->next && a->next->action == GRN_ACCESSOR_GET_COLUMN_VALUE &&
+        a->next->obj && !a->next->next) {
+      grn_obj *range = grn_ctx_at(ctx, grn_obj_get_range(ctx, key));
+      int idp = GRN_OBJ_TABLEP(range);
+      grn_table_cursor *tc;
+      if ((tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL,
+                                      0, 0, -1, 0))) {
+        switch (a->next->obj->header.type) {
+        case GRN_COLUMN_FIX_SIZE :
+          {
+            grn_id id;
+            grn_ra *ra = (grn_ra *)a->next->obj;
+            unsigned int element_size = (ra)->header->element_size;
+            grn_ra_cache cache;
+            GRN_RA_CACHE_INIT(ra, &cache);
+            while ((id = grn_table_cursor_next_inline(ctx, tc))) {
+              void *v, *value;
+              grn_id *id_;
+              uint32_t key_size;
+              grn_rset_recinfo *ri = NULL;
+              if (DB_OBJ(table)->header.flags & GRN_OBJ_WITH_SUBREC) {
+                grn_table_cursor_get_value_inline(ctx, tc, (void **)&ri);
+              }
+              id_ = (grn_id *)_grn_table_key(ctx, table, id, &key_size);
+              v = grn_ra_ref_cache(ctx, ra, *id_, &cache);
+              if (idp && *((grn_id *)v) &&
+                  grn_table_at(ctx, range, *((grn_id *)v)) == GRN_ID_NIL) {
+                continue;
+              }
+              if ((!idp || *((grn_id *)v))) {
+                grn_id id;
+                if (element_size == sizeof(uint32_t)) {
+                  uint32_t quantized = (*(uint32_t *)v);
+                  quantized -= quantized % range_gap;
+                  id = grn_table_add_v_inline(ctx, res, &quantized,
+                                              element_size, &value, NULL);
+                } else {
+                  id = grn_table_add_v_inline(ctx, res, v,
+                                              element_size, &value, NULL);
+                }
+                if (id) {
+                  grn_table_add_subrec_inline(res, value,
+                                              ri ? ri->score : 0, NULL, 0);
+                }
+              }
+            }
+            GRN_RA_CACHE_FIN(ra, &cache);
+          }
+          break;
+        case GRN_COLUMN_VAR_SIZE :
+          if (idp) { /* todo : support other type */
+            grn_id id;
+            grn_ja *ja = (grn_ja *)a->next->obj;
+            while ((id = grn_table_cursor_next_inline(ctx, tc))) {
+              grn_io_win jw;
+              unsigned int len = 0;
+              void *value;
+              grn_id *v, *id_;
+              uint32_t key_size;
+              grn_rset_recinfo *ri = NULL;
+              if (DB_OBJ(table)->header.flags & GRN_OBJ_WITH_SUBREC) {
+                grn_table_cursor_get_value_inline(ctx, tc, (void **)&ri);
+              }
+              id_ = (grn_id *)_grn_table_key(ctx, table, id, &key_size);
+              if ((v = grn_ja_ref(ctx, ja, *id_, &jw, &len))) {
+                while (len) {
+                  if ((*v != GRN_ID_NIL) &&
+                      grn_table_add_v_inline(ctx, res, v, sizeof(grn_id), &value, NULL)) {
+                    grn_table_add_subrec_inline(res, value, ri ? ri->score : 0, NULL, 0);
+                  }
+                  v++;
+                  len -= sizeof(grn_id);
+                }
+                grn_ja_unref(ctx, &jw);
+              }
+            }
+          } else {
+            return 0;
+          }
+          break;
+        default :
+          return 0;
+        }
+        grn_table_cursor_close(ctx, tc);
+        return 1;
+      }
+    }
+  }
+  return 0;
+}
+
+grn_rc
 grn_table_group(grn_ctx *ctx, grn_obj *table,
                 grn_table_sort_key *keys, int n_keys,
                 grn_table_group_result *results, int n_results)

  Modified: lib/db.h (+4 -0)
===================================================================
--- lib/db.h    2012-06-25 17:01:27 +0900 (32a20d6)
+++ lib/db.h    2012-06-25 20:15:37 +0900 (6054433)
@@ -440,6 +440,10 @@ GRN_API void grn_load_(grn_ctx *ctx, grn_content_type input_type,
                        const char *each, unsigned int each_len,
                        uint32_t emit_level);
 
+GRN_API grn_rc grn_table_group_with_range_gap(grn_ctx *ctx, grn_obj *table,
+                                              grn_table_sort_key *group_key,
+                                              grn_obj *result_set, uint32_t range_gap);
+
 #ifdef __cplusplus
 }
 #endif

  Modified: plugins/table/table.c (+13 -6)
===================================================================
--- plugins/table/table.c    2012-06-25 17:01:27 +0900 (a99b81a)
+++ plugins/table/table.c    2012-06-25 20:15:37 +0900 (ea8701b)
@@ -200,11 +200,17 @@ command_group(grn_ctx *ctx, int nargs, grn_obj **args,
                                           gkeys[0].key, NULL);
       }
       if (set_) {
-        grn_table_group_result g = {
-          set_, 0, 0, 1,
-          GRN_TABLE_GROUP_CALC_COUNT, 0
-        };
-        grn_table_group(ctx, table_, gkeys, 1, &g, 1);
+        if (GRN_TEXT_LEN(VAR(3))) {
+          uint32_t gap = grn_atoui(GRN_TEXT_VALUE(VAR(3)),
+                                   GRN_BULK_CURR(VAR(3)), NULL);
+          grn_table_group_with_range_gap(ctx, table_, gkeys, set_, gap);
+        } else {
+          grn_table_group_result g = {
+            set_, 0, 0, 1,
+            GRN_TABLE_GROUP_CALC_COUNT, 0
+          };
+          grn_table_group(ctx, table_, gkeys, 1, &g, 1);
+        }
       }
       grn_table_sort_key_close(ctx, gkeys, ngkeys);
     }
@@ -545,7 +551,8 @@ GRN_PLUGIN_REGISTER(grn_ctx *ctx)
   DEF_VAR(vars[0], "table");
   DEF_VAR(vars[1], "key");
   DEF_VAR(vars[2], "result_set");
-  DEF_COMMAND("group", command_group, 3, vars);
+  DEF_VAR(vars[3], "range_gap");
+  DEF_COMMAND("group", command_group, 4, vars);
 
   DEF_VAR(vars[0], "table");
   DEF_VAR(vars[1], "keys");
-------------- next part --------------
HTML$B$NE:IU%U%!%$%k$rJ]4I$7$^$7$?(B...
Download 



Groonga-commit メーリングリストの案内
Back to archive index