[Groonga-commit] groonga/groonga [support-selector] Support custom selector definition

Zurück zum Archiv-Index

null+****@clear***** null+****@clear*****
Fri Aug 10 17:24:12 JST 2012


Kouhei Sutou	2012-08-10 17:24:12 +0900 (Fri, 10 Aug 2012)

  New Revision: 1f8dd657392cc164cc71a40cffefa7bd7bd22953
  https://github.com/groonga/groonga/commit/1f8dd657392cc164cc71a40cffefa7bd7bd22953

  Log:
    Support custom selector definition
    
    Selector is a function that collects matched records into resultset
    table. Selector works fast because it can use index.
    
    geo_in_circle() and geo_in_rectangle() are existing selectors. They
    are defined by the mechanism intruduced in the change.

  Modified files:
    lib/db.h
    lib/expr.c
    lib/geo.c
    lib/geo.h
    lib/proc.c

  Modified: lib/db.h (+9 -0)
===================================================================
--- lib/db.h    2012-08-10 17:33:16 +0900 (b973242)
+++ lib/db.h    2012-08-10 17:24:12 +0900 (9c20d32)
@@ -153,6 +153,10 @@ typedef struct {
    (GRN_TABLE_HASH_KEY <= ((grn_db_obj *)obj)->header.type) &&\
    (((grn_db_obj *)obj)->header.type <= GRN_DB))
 
+typedef grn_rc grn_selector_func(grn_ctx *ctx, grn_obj *index,
+                                 int nargs, grn_obj **args,
+                                 grn_obj *res, grn_operator op);
+
 typedef struct _grn_proc_ctx grn_proc_ctx;
 
 struct _grn_proc_ctx {
@@ -177,6 +181,8 @@ struct _grn_proc {
   grn_proc_type type;
   grn_proc_func *funcs[3];
 
+  grn_selector_func *selector;
+
   grn_id module;
   //  uint32_t nargs;
   //  uint32_t nresults;
@@ -196,6 +202,9 @@ GRN_API grn_obj *grn_proc_get_var_by_offset(grn_ctx *ctx, grn_user_data *user_da
 GRN_API grn_obj *grn_proc_alloc(grn_ctx *ctx, grn_user_data *user_data,
                                 grn_id domain, grn_obj_flags flags);
 
+grn_rc grn_proc_set_selector(grn_ctx *ctx, grn_obj *proc,
+                             grn_selector_func selector);
+
 grn_obj *grn_expr_get_or_add_var(grn_ctx *ctx, grn_obj *expr,
                                  const char *name, unsigned int name_size);
 

  Modified: lib/expr.c (+25 -14)
===================================================================
--- lib/expr.c    2012-08-10 17:33:16 +0900 (2fda6e7)
+++ lib/expr.c    2012-08-10 17:24:12 +0900 (5b7f48b)
@@ -32,6 +32,12 @@ function_proc_p(grn_obj *obj)
           ((grn_proc *)obj)->type == GRN_PROC_FUNCTION);
 }
 
+static inline int
+selector_proc_p(grn_obj *obj)
+{
+  return (function_proc_p(obj) && ((grn_proc *)obj)->selector);
+}
+
 grn_obj *
 grn_expr_alloc(grn_ctx *ctx, grn_obj *expr, grn_id domain, grn_obj_flags flags)
 {
@@ -141,6 +147,17 @@ grn_proc_alloc(grn_ctx *ctx, grn_user_data *user_data, grn_id domain, grn_obj_fl
   return pctx->caller ? grn_expr_alloc(ctx, (grn_obj *)pctx->caller, domain, flags) : NULL;
 }
 
+grn_rc
+grn_proc_set_selector(grn_ctx *ctx, grn_obj *proc, grn_selector_func selector)
+{
+  grn_proc *proc_ = (grn_proc *)proc;
+  if (!function_proc_p(proc)) {
+    return GRN_INVALID_ARGUMENT;
+  }
+  proc_->selector = selector;
+  return GRN_SUCCESS;
+}
+
 /* grn_expr */
 
 static const char *opstrs[] = {
@@ -4247,20 +4264,14 @@ grn_table_select(grn_ctx *ctx, grn_obj *table, grn_obj *expr,
               break;
             case GRN_OP_CALL :
               if (si->flags & SCAN_ACCESSOR) {
-              } else {
-                char buf[GRN_TABLE_MAX_KEY_SIZE];
-                int len = grn_obj_name(ctx, si->args[0], buf,
-                                       GRN_TABLE_MAX_KEY_SIZE);
-                /* geo_in_circle and geo_in_rectangle only */
-                if (len == 13 && !memcmp(buf, "geo_in_circle", 13)) {
-                  /* TODO: error check */
-                  grn_selector_geo_in_circle(ctx, index, si->args, si->nargs,
-                                             res, si->logical_op);
-                  done++;
-                } else if (len == 16 && !memcmp(buf, "geo_in_rectangle", 16)) {
-                  /* TODO: error check */
-                  grn_selector_geo_in_rectangle(ctx, index, si->args, si->nargs,
-                                                res, si->logical_op);
+              } else if (selector_proc_p(si->args[0])) {
+                grn_rc rc;
+                grn_proc *proc = si->args[0];
+                rc = proc->selector(ctx, index, si->nargs, si->args,
+                                    res, si->logical_op);
+                if (rc) {
+                  /* TODO: report error */
+                } else {
                   done++;
                 }
               }

  Modified: lib/geo.c (+3 -2)
===================================================================
--- lib/geo.c    2012-08-10 17:33:16 +0900 (e474696)
+++ lib/geo.c    2012-08-10 17:24:12 +0900 (4cd8258)
@@ -673,7 +673,8 @@ typedef double (*grn_geo_distance_raw_func)(grn_ctx *ctx,
                                             grn_geo_point *point2);
 
 grn_rc
-grn_selector_geo_in_circle(grn_ctx *ctx, grn_obj *obj, grn_obj **args, int nargs,
+grn_selector_geo_in_circle(grn_ctx *ctx, grn_obj *obj,
+                           int nargs, grn_obj **args,
                            grn_obj *res, grn_operator op)
 {
   grn_geo_approximate_type type = GRN_GEO_APPROXIMATE_RECTANGLE;
@@ -884,7 +885,7 @@ exit :
 
 grn_rc
 grn_selector_geo_in_rectangle(grn_ctx *ctx, grn_obj *obj,
-                              grn_obj **args, int nargs,
+                              int nargs, grn_obj **args,
                               grn_obj *res, grn_operator op)
 {
   if (nargs == 4) {

  Modified: lib/geo.h (+6 -4)
===================================================================
--- lib/geo.h    2012-08-10 17:33:16 +0900 (5a0ef36)
+++ lib/geo.h    2012-08-10 17:24:12 +0900 (8fd2e7d)
@@ -133,10 +133,12 @@ grn_rc grn_geo_select_in_circle(grn_ctx *ctx,
                                 grn_obj *res,
                                 grn_operator op);
 
-grn_rc grn_selector_geo_in_circle(grn_ctx *ctx, grn_obj *obj, grn_obj **args,
-                                  int nargs, grn_obj *res, grn_operator op);
-grn_rc grn_selector_geo_in_rectangle(grn_ctx *ctx, grn_obj *obj, grn_obj **args,
-                                     int nargs, grn_obj *res, grn_operator op);
+grn_rc grn_selector_geo_in_circle(grn_ctx *ctx, grn_obj *obj,
+                                  int nargs, grn_obj **args,
+                                  grn_obj *res, grn_operator op);
+grn_rc grn_selector_geo_in_rectangle(grn_ctx *ctx, grn_obj *obj,
+                                     int nargs, grn_obj **args,
+                                     grn_obj *res, grn_operator op);
 
 GRN_API grn_bool grn_geo_in_circle(grn_ctx *ctx, grn_obj *point, grn_obj *center,
                            grn_obj *radius_or_point,

  Modified: lib/proc.c (+11 -4)
===================================================================
--- lib/proc.c    2012-08-10 17:33:16 +0900 (5e855a4)
+++ lib/proc.c    2012-08-10 17:24:12 +0900 (714e4ad)
@@ -2968,11 +2968,18 @@ grn_db_init_builtin_query(grn_ctx *ctx)
 
   grn_proc_create(ctx, "now", 3, GRN_PROC_FUNCTION, func_now, NULL, NULL, 0, vars);
 
-  grn_proc_create(ctx, "geo_in_circle", 13, GRN_PROC_FUNCTION,
-                  func_geo_in_circle, NULL, NULL, 0, NULL);
+  {
+    grn_obj *selector_proc;
+
+    selector_proc = grn_proc_create(ctx, "geo_in_circle", 13, GRN_PROC_FUNCTION,
+                                    func_geo_in_circle, NULL, NULL, 0, NULL);
+    grn_proc_set_selector(ctx, selector_proc, grn_selector_geo_in_circle);
 
-  grn_proc_create(ctx, "geo_in_rectangle", 16, GRN_PROC_FUNCTION,
-                  func_geo_in_rectangle, NULL, NULL, 0, NULL);
+    selector_proc = grn_proc_create(ctx, "geo_in_rectangle", 16,
+                                    GRN_PROC_FUNCTION,
+                                    func_geo_in_rectangle, NULL, NULL, 0, NULL);
+    grn_proc_set_selector(ctx, selector_proc, grn_selector_geo_in_rectangle);
+  }
 
   grn_proc_create(ctx, "geo_distance", 12, GRN_PROC_FUNCTION,
                   func_geo_distance, NULL, NULL, 0, NULL);
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Zurück zum Archiv-Index