[Groonga-commit] groonga/groonga at 29b7fa6 [master] Extract code for NOT as a function

Back to archive index

Kouhei Sutou null+****@clear*****
Wed Feb 15 13:17:23 JST 2017


Kouhei Sutou	2017-02-15 13:17:23 +0900 (Wed, 15 Feb 2017)

  New Revision: 29b7fa6ec0a888c1cc36206e2d784bb3f3716c2b
  https://github.com/groonga/groonga/commit/29b7fa6ec0a888c1cc36206e2d784bb3f3716c2b

  Message:
    Extract code for NOT as a function

  Modified files:
    lib/expr.c
    lib/mrb/scripts/scan_info_builder.rb

  Modified: lib/expr.c (+113 -93)
===================================================================
--- lib/expr.c    2017-02-15 12:32:57 +0900 (1248b01)
+++ lib/expr.c    2017-02-15 13:17:23 +0900 (b6114c3)
@@ -3739,27 +3739,33 @@ struct _grn_scan_info {
   GRN_FREE(si);\
 } while (0)
 
+#define SI_ALLOC_RAW(si, st) do {\
+  if (((si) = GRN_MALLOCN(scan_info, 1))) {\
+    GRN_INT32_INIT(&(si)->wv, GRN_OBJ_VECTOR);\
+    GRN_PTR_INIT(&(si)->index, GRN_OBJ_VECTOR, GRN_ID_NIL);\
+    (si)->logical_op = GRN_OP_OR;\
+    (si)->flags = SCAN_PUSH;\
+    (si)->nargs = 0;\
+    (si)->max_interval = DEFAULT_MAX_INTERVAL;\
+    (si)->similarity_threshold = DEFAULT_SIMILARITY_THRESHOLD;\
+    (si)->start = (st);\
+    (si)->query = NULL;\
+    GRN_PTR_INIT(&(si)->scorers, GRN_OBJ_VECTOR, GRN_ID_NIL);\
+    GRN_PTR_INIT(&(si)->scorer_args_exprs, GRN_OBJ_VECTOR, GRN_ID_NIL);\
+    GRN_UINT32_INIT(&(si)->scorer_args_expr_offsets, GRN_OBJ_VECTOR);\
+    (si)->position.specified = GRN_FALSE;\
+    (si)->position.start = 0;\
+  }\
+} while (0)
+
 #define SI_ALLOC(si, i, st) do {\
-  if (!((si) = GRN_MALLOCN(scan_info, 1))) {\
+  SI_ALLOC_RAW(si, st);\
+  if (!(si)) {\
     int j;\
     for (j = 0; j < i; j++) { SI_FREE(sis[j]); }\
     GRN_FREE(sis);\
     return NULL;\
   }\
-  GRN_INT32_INIT(&(si)->wv, GRN_OBJ_VECTOR);\
-  GRN_PTR_INIT(&(si)->index, GRN_OBJ_VECTOR, GRN_ID_NIL);\
-  (si)->logical_op = GRN_OP_OR;\
-  (si)->flags = SCAN_PUSH;\
-  (si)->nargs = 0;\
-  (si)->max_interval = DEFAULT_MAX_INTERVAL;\
-  (si)->similarity_threshold = DEFAULT_SIMILARITY_THRESHOLD;\
-  (si)->start = (st);\
-  (si)->query = NULL;\
-  GRN_PTR_INIT(&(si)->scorers, GRN_OBJ_VECTOR, GRN_ID_NIL);\
-  GRN_PTR_INIT(&(si)->scorer_args_exprs, GRN_OBJ_VECTOR, GRN_ID_NIL);\
-  GRN_UINT32_INIT(&(si)->scorer_args_expr_offsets, GRN_OBJ_VECTOR);\
-  (si)->position.specified = GRN_FALSE;\
-  (si)->position.start = 0;\
 } while (0)
 
 static scan_info **
@@ -4539,6 +4545,90 @@ scan_info_build_match(grn_ctx *ctx, scan_info *si)
   }
 }
 
+static grn_bool
+grn_scan_info_build_full_not(grn_ctx *ctx,
+                             scan_info **sis,
+                             int *i,
+                             grn_expr_code *code,
+                             grn_expr_code *code_end,
+                             grn_operator *next_code_op)
+{
+  scan_info *last_si;
+
+  if (*i == 0) {
+    return GRN_TRUE;
+  }
+
+  last_si = sis[*i - 1];
+  switch (last_si->op) {
+  case GRN_OP_LESS :
+    last_si->op = GRN_OP_GREATER_EQUAL;
+    last_si->end++;
+    break;
+  case GRN_OP_LESS_EQUAL :
+    last_si->op = GRN_OP_GREATER;
+    last_si->end++;
+    break;
+  case GRN_OP_GREATER :
+    last_si->op = GRN_OP_LESS_EQUAL;
+    last_si->end++;
+    break;
+  case GRN_OP_GREATER_EQUAL :
+    last_si->op = GRN_OP_LESS;
+    last_si->end++;
+    break;
+  case GRN_OP_NOT_EQUAL :
+    last_si->op = GRN_OP_EQUAL;
+    last_si->end++;
+    break;
+  default :
+    if (*i == 1) {
+      if (GRN_BULK_VSIZE(&(last_si->index)) > 0) {
+        scan_info *all_records_si = NULL;
+        SI_ALLOC_RAW(all_records_si, 0);
+        if (!all_records_si) {
+          return GRN_FALSE;
+        }
+        all_records_si->op = GRN_OP_CALL;
+        all_records_si->args[all_records_si->nargs++] =
+          grn_ctx_get(ctx, "all_records", -1);
+        last_si->logical_op = GRN_OP_AND_NOT;
+        last_si->flags &= ~SCAN_PUSH;
+        sis[*i] = sis[*i - 1];
+        sis[*i - 1] = all_records_si;
+        (*i)++;
+      } else {
+        if (last_si->op == GRN_OP_EQUAL) {
+          last_si->op = GRN_OP_NOT_EQUAL;
+          last_si->end++;
+        } else {
+          return GRN_FALSE;
+        }
+      }
+    } else {
+      grn_expr_code *next_code = code + 1;
+
+      if (next_code >= code_end) {
+        return GRN_FALSE;
+      }
+
+      switch (next_code->op) {
+      case GRN_OP_AND :
+        *next_code_op = GRN_OP_AND_NOT;
+        break;
+      case GRN_OP_AND_NOT :
+        *next_code_op = GRN_OP_AND;
+        break;
+      default :
+        return GRN_FALSE;
+        break;
+      }
+    }
+  }
+
+  return GRN_TRUE;
+}
+
 static scan_info **
 grn_scan_info_build_full(grn_ctx *ctx, grn_obj *expr, int *n,
                          grn_operator op, grn_bool record_exist)
@@ -4899,86 +4989,16 @@ grn_scan_info_build_full(grn_ctx *ctx, grn_obj *expr, int *n,
       stat = SCAN_COL1;
       break;
     case GRN_OP_NOT :
-      if (i == 0) {
-        return NULL;
-      }
       {
-        scan_info *last_si = sis[i - 1];
-        switch (last_si->op) {
-        case GRN_OP_LESS :
-          last_si->op = GRN_OP_GREATER_EQUAL;
-          last_si->end++;
-          break;
-        case GRN_OP_LESS_EQUAL :
-          last_si->op = GRN_OP_GREATER;
-          last_si->end++;
-          break;
-        case GRN_OP_GREATER :
-          last_si->op = GRN_OP_LESS_EQUAL;
-          last_si->end++;
-          break;
-        case GRN_OP_GREATER_EQUAL :
-          last_si->op = GRN_OP_LESS;
-          last_si->end++;
-          break;
-        case GRN_OP_NOT_EQUAL :
-          last_si->op = GRN_OP_EQUAL;
-          last_si->end++;
-          break;
-        default :
-          if (i == 1) {
-            if (GRN_BULK_VSIZE(&(last_si->index)) > 0) {
-              scan_info *all_records_si = NULL;
-              SI_ALLOC(all_records_si, 0, 0);
-              all_records_si->op = GRN_OP_CALL;
-              all_records_si->args[all_records_si->nargs++] =
-                grn_ctx_get(ctx, "all_records", -1);
-              last_si->logical_op = GRN_OP_AND_NOT;
-              last_si->flags &= ~SCAN_PUSH;
-              sis[i] = sis[i - 1];
-              sis[i - 1] = all_records_si;
-              i++;
-            } else {
-              if (last_si->op == GRN_OP_EQUAL) {
-                last_si->op = GRN_OP_NOT_EQUAL;
-                last_si->end++;
-              } else {
-                int j;
-                for (j = 0; j < i; j++) {
-                  SI_FREE(sis[j]);
-                }
-                GRN_FREE(sis);
-                return NULL;
-              }
-            }
-          } else {
-            grn_bool valid = GRN_TRUE;
-            grn_expr_code *next_code = c + 1;
-            if (next_code < ce) {
-              switch (next_code->op) {
-              case GRN_OP_AND :
-                next_code_op = GRN_OP_AND_NOT;
-                break;
-              case GRN_OP_AND_NOT :
-                next_code_op = GRN_OP_AND;
-                break;
-              default :
-                valid = GRN_FALSE;
-                break;
-              }
-            } else {
-              valid = GRN_FALSE;
-            }
-            if (!valid) {
-              int j;
-              for (j = 0; j < i; j++) {
-                SI_FREE(sis[j]);
-              }
-              GRN_FREE(sis);
-              return NULL;
-            }
+        grn_bool valid;
+        valid = grn_scan_info_build_full_not(ctx, sis, &i, c, ce, &next_code_op);
+        if (!valid) {
+          int j;
+          for (j = 0; j < i; j++) {
+            SI_FREE(sis[j]);
           }
-          break;
+          GRN_FREE(sis);
+          return NULL;
         }
       }
       break;

  Modified: lib/mrb/scripts/scan_info_builder.rb (+55 -45)
===================================================================
--- lib/mrb/scripts/scan_info_builder.rb    2017-02-15 12:32:57 +0900 (28dcbe2)
+++ lib/mrb/scripts/scan_info_builder.rb    2017-02-15 13:17:23 +0900 (27d0f5f)
@@ -148,51 +148,8 @@ module Groonga
           data.start_position = index.value
           status = Status::COL1
         when Operator::NOT
-          last_data = @data_list.last
-          return nil if last_data.nil?
-          case last_data.op
-          when Operator::LESS
-            last_data.op = Operator::GREATER_EQUAL
-            last_data.end += 1
-          when Operator::LESS_EQUAL
-            last_data.op = Operator::GREATER
-            last_data.end += 1
-          when Operator::GREATER
-            last_data.op = Operator::LESS_EQUAL
-            last_data.end += 1
-          when Operator::GREATER_EQUAL
-            last_data.op = Operator::LESS
-            last_data.end += 1
-          when Operator::NOT_EQUAL
-            last_data.op = Operator::EQUAL
-            last_data.end += 1
-          else
-            if @data_list.size == 1
-              if last_data.search_indexes.empty?
-                if last_data.op == Operator::EQUAL
-                  last_data.op = Operator::NOT_EQUAL
-                  last_data.end += 1
-                else
-                  return nil
-                end
-              else
-                last_data.logical_op = Operator::AND_NOT
-                last_data.flags &= ~ScanInfo::Flags::PUSH
-                @data_list.unshift(create_all_match_data)
-              end
-            else
-              next_code = codes[i + 1]
-              return nil if next_code.nil?
-              case next_code.op
-              when Operator::AND
-                next_code_op = Operator::AND_NOT
-              when Operator::AND_NOT
-                next_code_op = Operator::AND
-              else
-                return nil
-              end
-            end
-          end
+          success, next_code_op = build_not(code, codes, i)
+          return nil unless success
         end
       end
 
@@ -366,6 +323,59 @@ module Groonga
       end
     end
 
+    def build_not(code, codes, i)
+      last_data = @data_list.last
+      return [false, nil] if last_data.nil?
+
+      next_code_op = nil
+      case last_data.op
+      when Operator::LESS
+        last_data.op = Operator::GREATER_EQUAL
+        last_data.end += 1
+      when Operator::LESS_EQUAL
+        last_data.op = Operator::GREATER
+        last_data.end += 1
+      when Operator::GREATER
+        last_data.op = Operator::LESS_EQUAL
+        last_data.end += 1
+      when Operator::GREATER_EQUAL
+        last_data.op = Operator::LESS
+        last_data.end += 1
+      when Operator::NOT_EQUAL
+        last_data.op = Operator::EQUAL
+        last_data.end += 1
+      else
+        if @data_list.size == 1
+          if last_data.search_indexes.empty?
+            if last_data.op == Operator::EQUAL
+              last_data.op = Operator::NOT_EQUAL
+              last_data.end += 1
+            else
+              return [false, nil]
+            end
+          else
+            last_data.logical_op = Operator::AND_NOT
+            last_data.flags &= ~ScanInfo::Flags::PUSH
+            @data_list.unshift(create_all_match_data)
+          end
+        else
+          next_code = codes[i + 1]
+          return [false, nil] if next_code.nil?
+
+          case next_code.op
+          when Operator::AND
+            next_code_op = Operator::AND_NOT
+          when Operator::AND_NOT
+            next_code_op = Operator::AND
+          else
+            return [false, nil]
+          end
+        end
+      end
+
+      [true, next_code_op]
+    end
+
     def optimize
       optimized_data_list = []
       i = 0
-------------- next part --------------
HTML����������������������������...
Download 



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