[Groonga-commit] groonga/groonga at 738c1a1 [master] grn_ts: implement grn_ts_begin/end_subexpr()

Back to archive index

susumu.yata null+****@clear*****
Thu Sep 24 18:01:55 JST 2015


susumu.yata	2015-09-24 18:01:55 +0900 (Thu, 24 Sep 2015)

  New Revision: 738c1a13343af18632481a0973f5077fb78add10
  https://github.com/groonga/groonga/commit/738c1a13343af18632481a0973f5077fb78add10

  Message:
    grn_ts: implement grn_ts_begin/end_subexpr()
    
    GitHub: #408

  Modified files:
    lib/grn_ts.h
    lib/ts.c

  Modified: lib/grn_ts.h (+21 -12)
===================================================================
--- lib/grn_ts.h    2015-09-24 14:28:19 +0900 (5f83144)
+++ lib/grn_ts.h    2015-09-24 18:01:55 +0900 (9c77e5b)
@@ -179,18 +179,27 @@ typedef struct {
 } grn_ts_expr_node;
 
 typedef struct {
-  grn_obj *table;             /* Associated table. */
-  grn_obj *curr_table;        /* Current table. */
-  grn_ts_expr_type type;      /* Expression type. */
-  grn_ts_data_kind data_kind; /* Abstract data type. */
-  grn_ts_data_type data_type; /* Detailed data type. */
-  grn_ts_expr_node *root;     /* Root node. */
-  grn_ts_expr_node **nodes;   /* Buffer for a node stack. */
-  size_t n_nodes;             /* Number of nodes. */
-  size_t max_n_nodes;         /* Max. number (capacity) of nodes. */
-  grn_ts_expr_node **stack;   /* Node stack. */
-  size_t stack_depth;         /* Node stack's current depth. */
-  size_t stack_size;          /* Node stack's size (capacity). */
+  grn_obj *src_table;  /* The source table of a bridge (no ref. count). */
+  grn_obj *dest_table; /* The destination table of a bridge. */
+  size_t stack_depth;  /* The stack depth (position) of a bridge. */
+} grn_ts_expr_bridge;
+
+typedef struct {
+  grn_obj *table;              /* Associated table. */
+  grn_obj *curr_table;         /* Current table (no ref. count). */
+  grn_ts_expr_type type;       /* Expression type. */
+  grn_ts_data_kind data_kind;  /* Abstract data type. */
+  grn_ts_data_type data_type;  /* Detailed data type. */
+  grn_ts_expr_node *root;      /* Root node. */
+  grn_ts_expr_node **nodes;    /* Buffer for a node stack. */
+  size_t n_nodes;              /* Number of nodes. */
+  size_t max_n_nodes;          /* Max. number (capacity) of nodes. */
+  grn_ts_expr_node **stack;    /* Node stack. */
+  size_t stack_depth;          /* Node stack's current depth. */
+  size_t stack_size;           /* Node stack's size (capacity). */
+  grn_ts_expr_bridge *bridges; /* Bridges to subexpressions. */
+  size_t n_bridges;            /* Number of bridges (subexpression depth). */
+  size_t max_n_bridges;        /* Max. number (capacity) of bridges. */
 } grn_ts_expr;
 
 /* grn_ts_expr_open() creates an empty expression. */

  Modified: lib/ts.c (+113 -24)
===================================================================
--- lib/ts.c    2015-09-24 14:28:19 +0900 (dd7b5e7)
+++ lib/ts.c    2015-09-24 18:01:55 +0900 (f9f8c36)
@@ -3819,6 +3819,8 @@ grn_ts_expr_bridge_node_open(grn_ctx *ctx, grn_ts_expr_node *src,
     return GRN_NO_MEMORY_AVAILABLE;
   }
   grn_ts_expr_bridge_node_init(ctx, new_node);
+  new_node->data_kind = dest->data_kind;
+  new_node->data_type = dest->data_type;
   new_node->src = src;
   new_node->dest = dest;
   *node = (grn_ts_expr_node *)new_node;
@@ -4834,6 +4836,10 @@ grn_ts_expr_parser_apply(grn_ctx *ctx, grn_ts_expr_parser *parser,
     /* Check the number of arguments. */
     if (stack[depth - 2]->type == GRN_TS_EXPR_BRIDGE_TOKEN) {
       n_args = 2;
+      rc = grn_ts_expr_end_subexpr(ctx, parser->expr);
+      if (rc != GRN_SUCCESS) {
+        break;
+      }
     } else if (stack[depth - 2]->type == GRN_TS_EXPR_OP_TOKEN) {
       grn_ts_expr_op_token *op_token;
       grn_ts_op_precedence precedence;
@@ -5075,6 +5081,27 @@ grn_ts_expr_parser_parse(grn_ctx *ctx, grn_ts_expr_parser *parser,
 }
 
 /*-------------------------------------------------------------
+ * grn_ts_expr_bridge.
+ */
+
+/* grn_ts_expr_bridge_init() initializes a bridge. */
+static void
+grn_ts_expr_bridge_init(grn_ctx *ctx, grn_ts_expr_bridge *bridge) {
+  memset(bridge, 0, sizeof(*bridge));
+  bridge->src_table = NULL;
+  bridge->dest_table = NULL;
+}
+
+/* grn_ts_expr_bridge_fin() finalizes a bridge. */
+static void
+grn_ts_expr_bridge_fin(grn_ctx *ctx, grn_ts_expr_bridge *bridge) {
+  if (bridge->dest_table) {
+    grn_obj_unlink(ctx, bridge->dest_table);
+  }
+  /* Note: bridge->src_count does not increment a reference count. */
+}
+
+/*-------------------------------------------------------------
  * grn_ts_expr.
  */
 
@@ -5087,16 +5114,23 @@ grn_ts_expr_init(grn_ctx *ctx, grn_ts_expr *expr) {
   expr->root = NULL;
   expr->nodes = NULL;
   expr->stack = NULL;
+  expr->bridges = NULL;
 }
 
 /* grn_ts_expr_fin() finalizes an expression. */
 static void
 grn_ts_expr_fin(grn_ctx *ctx, grn_ts_expr *expr) {
+  size_t i;
+  if (expr->bridges) {
+    for (i = 0; i < expr->n_bridges; i++) {
+      grn_ts_expr_bridge_fin(ctx, &expr->bridges[i]);
+    }
+    GRN_FREE(expr->bridges);
+  }
   if (expr->stack) {
     GRN_FREE(expr->stack);
   }
   if (expr->nodes) {
-    size_t i;
     for (i = 0; i < expr->n_nodes; i++) {
       if (expr->nodes[i]) {
         grn_ts_expr_node_close(ctx, expr->nodes[i]);
@@ -5104,9 +5138,7 @@ grn_ts_expr_fin(grn_ctx *ctx, grn_ts_expr *expr) {
     }
     GRN_FREE(expr->nodes);
   }
-  if (expr->curr_table) {
-    grn_obj_unlink(ctx, expr->curr_table);
-  }
+  /* Note: expr->curr_table does not increment a reference count. */
   if (expr->table) {
     grn_obj_unlink(ctx, expr->table);
   }
@@ -5123,20 +5155,14 @@ grn_ts_expr_open(grn_ctx *ctx, grn_obj *table, grn_ts_expr **expr) {
   if (!new_expr) {
     return GRN_NO_MEMORY_AVAILABLE;
   }
-  grn_ts_expr_init(ctx, new_expr);
   rc = grn_ts_obj_increment_ref_count(ctx, table);
-  if (rc == GRN_SUCCESS) {
-    new_expr->table = table;
-    rc = grn_ts_obj_increment_ref_count(ctx, table);
-    if (rc == GRN_SUCCESS) {
-      new_expr->curr_table = table;
-    }
-  }
   if (rc != GRN_SUCCESS) {
-    grn_ts_expr_fin(ctx, new_expr);
     GRN_FREE(new_expr);
     return rc;
   }
+  grn_ts_expr_init(ctx, new_expr);
+  new_expr->table = table;
+  new_expr->curr_table = table;
   *expr = new_expr;
   return GRN_SUCCESS;
 }
@@ -5851,33 +5877,95 @@ grn_ts_expr_push_wgs84_geo_point_vector(grn_ctx *ctx, grn_ts_expr *expr,
 }
 #undef GRN_TS_EXPR_PUSH_CONST
 
+/* grn_ts_expr_reserve_bridges() extends a bridge buffer for a new bridge. */
+static grn_rc
+grn_ts_expr_reserve_bridges(grn_ctx *ctx, grn_ts_expr *expr) {
+  size_t n_bytes, new_max_n_bridges;
+  grn_ts_expr_bridge *new_bridges;
+  if (expr->n_bridges < expr->max_n_bridges) {
+    return GRN_SUCCESS;
+  }
+  new_max_n_bridges = expr->n_bridges * 2;
+  if (!new_max_n_bridges) {
+    new_max_n_bridges = 1;
+  }
+  n_bytes = sizeof(grn_ts_expr_bridge) * new_max_n_bridges;
+  new_bridges = (grn_ts_expr_bridge *)GRN_REALLOC(expr->bridges, n_bytes);
+  if (!new_bridges) {
+    return GRN_NO_MEMORY_AVAILABLE;
+  }
+  expr->bridges = new_bridges;
+  expr->max_n_bridges = new_max_n_bridges;
+  return GRN_SUCCESS;
+}
+
 grn_rc
 grn_ts_expr_begin_subexpr(grn_ctx *ctx, grn_ts_expr *expr) {
-  if (!ctx || !expr || (expr->type != GRN_TS_EXPR_INCOMPLETE)) {
+  grn_rc rc;
+  grn_obj *obj;
+  grn_ts_expr_node *node;
+  grn_ts_expr_bridge *bridge;
+  if (!ctx || !expr || (expr->type != GRN_TS_EXPR_INCOMPLETE) ||
+      !expr->stack_depth) {
+    return GRN_INVALID_ARGUMENT;
+  }
+
+  /* Check whehter or not the latest node refers to a table. */
+  node = expr->stack[expr->stack_depth - 1];
+  if ((node->data_kind & ~GRN_TS_VECTOR_FLAG) != GRN_TS_REF) {
+    return GRN_INVALID_ARGUMENT;
+  }
+  obj = grn_ctx_at(ctx, node->data_type);
+  if (!obj) {
+    return GRN_INVALID_ARGUMENT;
+  }
+  if (!grn_ts_obj_is_table(ctx, obj)) {
+    grn_obj_unlink(ctx, obj);
     return GRN_INVALID_ARGUMENT;
   }
-  // TODO
-  return GRN_FUNCTION_NOT_IMPLEMENTED;
+
+  /* Creates a bridge to a subexpression. */
+  rc = grn_ts_expr_reserve_bridges(ctx, expr);
+  if (rc != GRN_SUCCESS) {
+    grn_obj_unlink(ctx, obj);
+    return rc;
+  }
+  bridge = &expr->bridges[expr->n_bridges++];
+  grn_ts_expr_bridge_init(ctx, bridge);
+  bridge->src_table = expr->curr_table;
+  bridge->dest_table = obj;
+  bridge->stack_depth = expr->stack_depth;
+  expr->curr_table = bridge->dest_table;
+  return GRN_SUCCESS;
 }
 
 grn_rc
 grn_ts_expr_end_subexpr(grn_ctx *ctx, grn_ts_expr *expr) {
   grn_rc rc;
   grn_ts_expr_node **args, *node;
-  if (!ctx || !expr || (expr->type != GRN_TS_EXPR_INCOMPLETE)) {
+  grn_ts_expr_bridge *bridge;
+  if (!ctx || !expr || (expr->type != GRN_TS_EXPR_INCOMPLETE) ||
+      (expr->stack_depth < 2) || !expr->n_bridges) {
     return GRN_INVALID_ARGUMENT;
   }
-  if (expr->stack_depth < 2) {
+  /* Check whehter or not the subexpression is complete.*/
+  bridge = &expr->bridges[expr->n_bridges - 1];
+  if (expr->stack_depth != (bridge->stack_depth + 1)) {
     return GRN_INVALID_ARGUMENT;
   }
-  // TODO: End a subexpression.
+  /* Creates a bridge node. */
   args = &expr->stack[expr->stack_depth - 2];
   rc = grn_ts_expr_open_bridge_node(ctx, expr, args[0], args[1], &node);
-  if (rc == GRN_SUCCESS) {
-    expr->stack_depth -= 2;
-    expr->stack[expr->stack_depth++] = node;
+  if (rc != GRN_SUCCESS) {
+    return rc;
   }
-  return rc;
+  /* Note: grn_ts_expr_reserve_stack() is not required. */
+  expr->stack_depth -= 2;
+  expr->stack[expr->stack_depth++] = node;
+  expr->curr_table = bridge->src_table;
+  grn_ts_expr_bridge_fin(ctx, bridge);
+  expr->n_bridges--;
+  return GRN_SUCCESS;
 }
 
 grn_rc
@@ -5918,7 +6006,8 @@ grn_ts_expr_complete(grn_ctx *ctx, grn_ts_expr *expr) {
       break;
     }
     case GRN_TS_EXPR_COLUMN_NODE:
-    case GRN_TS_EXPR_OP_NODE: {
+    case GRN_TS_EXPR_OP_NODE:
+    case GRN_TS_EXPR_BRIDGE_NODE: {
       expr->type = GRN_TS_EXPR_VARIABLE;
       break;
     }
-------------- next part --------------
HTML����������������������������...
Download 



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