[Groonga-commit] groonga/groonga at b289c1a [master] grn_ts: implement logical operators

Back to archive index

susumu.yata null+****@clear*****
Tue Sep 8 14:58:29 JST 2015


susumu.yata	2015-09-08 14:58:29 +0900 (Tue, 08 Sep 2015)

  New Revision: b289c1a10fe44c3eb1c27dd1ce8a3ceb3ff11e0b
  https://github.com/groonga/groonga/commit/b289c1a10fe44c3eb1c27dd1ce8a3ceb3ff11e0b

  Message:
    grn_ts: implement logical operators
    
    GitHub: #385

  Modified files:
    lib/ts.c

  Modified: lib/ts.c (+212 -37)
===================================================================
--- lib/ts.c    2015-09-08 16:43:36 +0900 (ea2ab2c)
+++ lib/ts.c    2015-09-08 14:58:29 +0900 (afd7dd3)
@@ -409,24 +409,6 @@ grn_ts_data_kind_to_type(grn_ts_data_kind kind) {
  * Operators.
  */
 
-/* Logical Not operator (!X). */
-inline static grn_bool
-grn_ts_op_logical_not(grn_bool arg) {
-  return !arg;
-}
-
-/* Logical And operator (X && Y). */
-inline static grn_bool
-grn_ts_op_logical_and(grn_bool arg1, grn_bool arg2) {
-  return arg1 & arg2;
-}
-
-/* Logical Or operator (X || Y). */
-inline static grn_bool
-grn_ts_op_logical_or(grn_bool arg1, grn_bool arg2) {
-  return arg1 | arg2;
-}
-
 /* grn_ts_op_get_n_args() returns the number of arguments. */
 static size_t
 grn_ts_op_get_n_args(grn_ts_op_type op_type) {
@@ -666,6 +648,8 @@ typedef struct {
   grn_ts_op_type op_type;
   grn_ts_expr_node **args;
   size_t n_args;
+  void *buf;
+  size_t buf_size; /* Size in bytes. */
   // TODO
 } grn_ts_expr_op_node;
 
@@ -715,7 +699,10 @@ grn_ts_expr_node_fin(grn_ctx *ctx, grn_ts_expr_node *node) {
     }
     case GRN_TS_EXPR_OP_NODE: {
       grn_ts_expr_op_node *op_node = (grn_ts_expr_op_node *)node;
-      // TODO: Unlink objects and free memory.
+      // TODO: Free memory.
+      if (op_node->buf) {
+        GRN_FREE(op_node->buf);
+      }
       if (op_node->args) {
         GRN_FREE(op_node->args);
       }
@@ -1038,11 +1025,13 @@ static grn_rc
 grn_ts_expr_op_node_open(grn_ctx *ctx, grn_ts_op_type op_type,
                          grn_ts_expr_node **args, size_t n_args,
                          grn_ts_expr_node **node) {
-  grn_rc rc = GRN_SUCCESS;
+  size_t i;
   grn_ts_data_kind data_kind = GRN_TS_VOID;
   grn_ts_data_type data_type = GRN_DB_VOID;
   grn_ts_expr_node **args_clone = NULL;
   grn_ts_expr_op_node *new_node;
+
+  /* Check arguments. */
   switch (op_type) {
     case GRN_TS_OP_LOGICAL_AND:
     case GRN_TS_OP_LOGICAL_OR: {
@@ -1063,15 +1052,20 @@ grn_ts_expr_op_node_open(grn_ctx *ctx, grn_ts_op_type op_type,
       return GRN_INVALID_ARGUMENT;
     }
   }
-  if (rc == GRN_SUCCESS) {
-    args_clone = GRN_MALLOCN(grn_ts_expr_node *, n_args);
-    if (!args_clone) {
-      return GRN_NO_MEMORY_AVAILABLE;
-    }
-  } else {
-    return rc;
+  if ((data_kind == GRN_TS_VOID) || (data_type == GRN_DB_VOID)) {
+    return GRN_UNKNOWN_ERROR;
+  }
+
+  /* Create a copy of args. */
+  args_clone = GRN_MALLOCN(grn_ts_expr_node *, n_args);
+  if (!args_clone) {
+    return GRN_NO_MEMORY_AVAILABLE;
+  }
+  for (i = 0; i < n_args; i++) {
+    args_clone[i] = args[i];
   }
 
+  /* Create an operator node. */
   new_node = GRN_MALLOCN(grn_ts_expr_op_node, 1);
   if (!new_node) {
     if (args_clone) {
@@ -1085,7 +1079,9 @@ grn_ts_expr_op_node_open(grn_ctx *ctx, grn_ts_op_type op_type,
   new_node->op_type = op_type;
   new_node->args = args_clone;
   new_node->n_args = n_args;
-  return rc;
+  new_node->buf = NULL;
+  new_node->buf_size = 0;
+  return GRN_SUCCESS;
 }
 
 /* grn_ts_expr_id_node_evaluate() outputs IDs. */
@@ -1688,13 +1684,122 @@ grn_ts_expr_column_node_evaluate(grn_ctx *ctx, grn_ts_expr_column_node *node,
   }
 }
 
-/* grn_ts_expr_op_node_evaluate() outputs results of an operator. */
+/* Forward declaration for operator nodes. */
+static grn_rc
+grn_ts_expr_node_evaluate(grn_ctx *ctx, grn_ts_expr_node *node,
+                          const grn_ts_record *in, size_t n_in, void *out);
+
+/*
+ * grn_ts_expr_op_node_reserve_buf() allocates memory to the 1st internal
+ * buffer.
+ */
+static grn_rc
+grn_ts_expr_op_node_reserve_buf(grn_ctx *ctx, grn_ts_expr_op_node *node,
+                                size_t new_size) {
+  void *new_buf;
+  if (new_size <= node->buf_size) {
+    return GRN_SUCCESS;
+  }
+  new_buf = GRN_REALLOC(node->buf, new_size);
+  if (!new_buf) {
+    return GRN_NO_MEMORY_AVAILABLE;
+  }
+  node->buf = new_buf;
+  node->buf_size = new_size;
+  return GRN_SUCCESS;
+}
+
+/* grn_ts_op_logical_not_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_logical_not_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+                               const grn_ts_record *in, size_t n_in,
+                               void *out) {
+  size_t i;
+  grn_ts_bool *out_ptr = (grn_ts_bool *)out;
+  grn_rc rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);
+  if (rc != GRN_SUCCESS) {
+    return rc;
+  }
+  for (i = 0; i < n_in; i++) {
+    out_ptr[i] = !out_ptr[i];
+  }
+  return GRN_SUCCESS;
+}
+
+/* grn_ts_op_logical_and_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_logical_and_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+                               const grn_ts_record *in, size_t n_in,
+                               void *out) {
+  size_t i;
+  grn_ts_bool *out_ptr = (grn_ts_bool *)out;
+  grn_ts_bool *buf_ptr;
+  grn_rc rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);
+  if (rc != GRN_SUCCESS) {
+    return rc;
+  }
+  rc = grn_ts_expr_op_node_reserve_buf(ctx, node, sizeof(grn_ts_bool) * n_in);
+  if (rc != GRN_SUCCESS) {
+    return rc;
+  }
+  buf_ptr = (grn_ts_bool *)node->buf;
+  rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, node->buf);
+  if (rc != GRN_SUCCESS) {
+    return rc;
+  }
+  for (i = 0; i < n_in; i++) {
+    out_ptr[i] &= buf_ptr[i];
+  }
+  return GRN_SUCCESS;
+}
+
+/* grn_ts_op_logical_or_evaluate() evaluates an operator. */
+static grn_rc
+grn_ts_op_logical_or_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
+                               const grn_ts_record *in, size_t n_in,
+                               void *out) {
+  size_t i;
+  grn_ts_bool *out_ptr = (grn_ts_bool *)out;
+  grn_ts_bool *buf_ptr;
+  grn_rc rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, out);
+  if (rc != GRN_SUCCESS) {
+    return rc;
+  }
+  rc = grn_ts_expr_op_node_reserve_buf(ctx, node, sizeof(grn_ts_bool) * n_in);
+  if (rc != GRN_SUCCESS) {
+    return rc;
+  }
+  buf_ptr = (grn_ts_bool *)node->buf;
+  rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, node->buf);
+  if (rc != GRN_SUCCESS) {
+    return rc;
+  }
+  for (i = 0; i < n_in; i++) {
+    out_ptr[i] |= buf_ptr[i];
+  }
+  return GRN_SUCCESS;
+}
+
+/* grn_ts_expr_op_node_evaluate() evaluates an operator. */
 static grn_rc
 grn_ts_expr_op_node_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
                              const grn_ts_record *in, size_t n_in,
                              void *out) {
-  // TODO
-  return GRN_SUCCESS;
+  switch (node->op_type) {
+    case GRN_TS_OP_LOGICAL_NOT: {
+      return grn_ts_op_logical_not_evaluate(ctx, node, in, n_in, out);
+    }
+    case GRN_TS_OP_LOGICAL_AND: {
+      return grn_ts_op_logical_and_evaluate(ctx, node, in, n_in, out);
+    }
+    case GRN_TS_OP_LOGICAL_OR: {
+      return grn_ts_op_logical_or_evaluate(ctx, node, in, n_in, out);
+    }
+    // TODO
+    default: {
+      return GRN_OPERATION_NOT_SUPPORTED;
+    }
+  }
 }
 
 #define GRN_TS_EXPR_NODE_EVALUATE_CASE_BLOCK(TYPE, type)\
@@ -1707,8 +1812,7 @@ grn_ts_expr_op_node_evaluate(grn_ctx *ctx, grn_ts_expr_op_node *node,
 /* grn_ts_expr_node_evaluate() evaluates a subexpression. */
 static grn_rc
 grn_ts_expr_node_evaluate(grn_ctx *ctx, grn_ts_expr_node *node,
-                          const grn_ts_record *in, size_t n_in,
-                          void *out) {
+                          const grn_ts_record *in, size_t n_in, void *out) {
   switch (node->type) {
     GRN_TS_EXPR_NODE_EVALUATE_CASE_BLOCK(ID, id)
     GRN_TS_EXPR_NODE_EVALUATE_CASE_BLOCK(SCORE, score)
@@ -1803,13 +1907,80 @@ grn_ts_expr_column_node_filter(grn_ctx *ctx, grn_ts_expr_column_node *node,
   return GRN_SUCCESS;
 }
 
+/* Forward declaration for operator nodes. */
+static grn_rc
+grn_ts_expr_node_filter(grn_ctx *ctx, grn_ts_expr_node *node,
+                        grn_ts_record *in, size_t n_in,
+                        grn_ts_record *out, size_t *n_out);
+
+/* grn_ts_op_logical_not_filter() filters records. */
+static grn_rc
+grn_ts_op_logical_not_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+                             grn_ts_record *in, size_t n_in,
+                             grn_ts_record *out, size_t *n_out) {
+  size_t i, count;
+  grn_rc rc;
+  grn_ts_bool *buf_ptr;
+  rc = grn_ts_expr_op_node_reserve_buf(ctx, node, sizeof(grn_ts_bool) * n_in);
+  if (rc != GRN_SUCCESS) {
+    return rc;
+  }
+  buf_ptr = (grn_ts_bool *)node->buf;
+  rc = grn_ts_expr_node_evaluate(ctx, node->args[0], in, n_in, node->buf);
+  if (rc != GRN_SUCCESS) {
+    return rc;
+  }
+  for (i = 0, count = 0; i < n_in; i++) {
+    if (!buf_ptr[i]) {
+      out[count++] = in[i];
+    }
+  }
+  *n_out = count;
+  return GRN_SUCCESS;
+}
+
+/* grn_ts_op_logical_and_filter() filters records. */
+static grn_rc
+grn_ts_op_logical_and_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+                             grn_ts_record *in, size_t n_in,
+                             grn_ts_record *out, size_t *n_out) {
+  grn_rc rc = grn_ts_expr_node_filter(ctx, node->args[0], in, n_in,
+                                      out, n_out);
+  if (rc != GRN_SUCCESS) {
+    return rc;
+  }
+  return grn_ts_expr_node_filter(ctx, node->args[1], out, *n_out, out, n_out);
+}
+
+/* grn_ts_op_logical_or_filter() filters records. */
+static grn_rc
+grn_ts_op_logical_or_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
+                            grn_ts_record *in, size_t n_in,
+                            grn_ts_record *out, size_t *n_out) {
+  // TODO
+  return GRN_FUNCTION_NOT_IMPLEMENTED;
+}
+
 /* grn_ts_expr_op_node_filter() filters records. */
 static grn_rc
 grn_ts_expr_op_node_filter(grn_ctx *ctx, grn_ts_expr_op_node *node,
                            grn_ts_record *in, size_t n_in,
                            grn_ts_record *out, size_t *n_out) {
-  // TODO
-  return GRN_SUCCESS;
+  switch (node->op_type) {
+    case GRN_TS_OP_LOGICAL_NOT: {
+      return grn_ts_op_logical_not_filter(ctx, node, in, n_in, out, n_out);
+    }
+    case GRN_TS_OP_LOGICAL_AND: {
+      return grn_ts_op_logical_and_filter(ctx, node, in, n_in, out, n_out);
+    }
+    case GRN_TS_OP_LOGICAL_OR: {
+      return grn_ts_op_logical_or_filter(ctx, node, in, n_in, out, n_out);
+    }
+    // TODO
+    default: {
+      return GRN_OPERATION_NOT_SUPPORTED;
+    }
+  }
 }
 
 #define GRN_TS_EXPR_NODE_FILTER_CASE_BLOCK(TYPE, type)\
@@ -1918,8 +2089,12 @@ grn_ts_expr_column_node_adjust(grn_ctx *ctx, grn_ts_expr_column_node *node,
 static grn_rc
 grn_ts_expr_op_node_adjust(grn_ctx *ctx, grn_ts_expr_op_node *node,
                            grn_ts_record *io, size_t n_io) {
-  // TODO
-  return GRN_SUCCESS;
+  switch (node->op_type) {
+    // TODO
+    default: {
+      return GRN_OPERATION_NOT_SUPPORTED;
+    }
+  }
 }
 
 #define GRN_TS_EXPR_NODE_ADJUST_CASE_BLOCK(TYPE, type)\
-------------- next part --------------
HTML����������������������������...
Download 



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