[Groonga-commit] groonga/groonga at 1a629a0 [master] Extract common code

Back to archive index
Kouhei Sutou null+****@clear*****
Thu Dec 27 10:31:47 JST 2018


Kouhei Sutou	2018-12-27 10:31:47 +0900 (Thu, 27 Dec 2018)

  Revision: 1a629a0b71c795376fa59b86f9aef1ed264cb770
  https://github.com/groonga/groonga/commit/1a629a0b71c795376fa59b86f9aef1ed264cb770

  Message:
    Extract common code

  Added files:
    lib/grn_output_columns.h
  Modified files:
    lib/c_sources.am
    lib/output.c
    lib/output_columns.c

  Modified: lib/c_sources.am (+1 -0)
===================================================================
--- lib/c_sources.am    2018-12-26 15:31:40 +0900 (e3e91d2b1)
+++ lib/c_sources.am    2018-12-27 10:31:47 +0900 (637bb2ebd)
@@ -72,6 +72,7 @@ libgroonga_c_sources =				\
 	output.c				\
 	grn_output.h				\
 	output_columns.c			\
+	grn_output_columns.h			\
 	pat.c					\
 	grn_pat.h				\
 	plugin.c				\

  Added: lib/grn_output_columns.h (+34 -0) 100644
===================================================================
--- /dev/null
+++ lib/grn_output_columns.h    2018-12-27 10:31:47 +0900 (caa038905)
@@ -0,0 +1,34 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+  Copyright(C) 2018 Kouhei Sutou <kou****@clear*****>
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License version 2.1 as published by the Free Software Foundation.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#pragma once
+
+#include "grn.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+grn_rc
+grn_output_columns_get_offsets(grn_ctx *ctx,
+                               grn_obj *output_columns,
+                               grn_obj *offsets);
+
+#ifdef __cplusplus
+}
+#endif

  Modified: lib/output.c (+42 -108)
===================================================================
--- lib/output.c    2018-12-26 15:31:40 +0900 (90c5b076d)
+++ lib/output.c    2018-12-27 10:31:47 +0900 (97f4a0523)
@@ -24,6 +24,7 @@
 #include "grn_db.h"
 #include "grn_expr.h"
 #include "grn_output.h"
+#include "grn_output_columns.h"
 #include "grn_str.h"
 #include "grn_util.h"
 
@@ -1336,28 +1337,6 @@ grn_output_table_column_info(grn_ctx *ctx,
   }
 }
 
-static grn_inline int
-count_n_elements_in_expression(grn_ctx *ctx, grn_obj *expression)
-{
-  int n_elements = 0;
-  grn_bool is_first_comma = GRN_TRUE;
-  grn_expr *expr = (grn_expr *)expression;
-  grn_expr_code *code;
-  grn_expr_code *code_end = expr->codes + expr->codes_curr;
-
-  for (code = expr->codes; code < code_end; code++) {
-    if (code->op == GRN_OP_COMMA) {
-      n_elements++;
-      if (is_first_comma) {
-        n_elements++;
-        is_first_comma = GRN_FALSE;
-      }
-    }
-  }
-
-  return n_elements;
-}
-
 static grn_bool
 is_score_accessor(grn_ctx *ctx, grn_obj *obj)
 {
@@ -1498,58 +1477,33 @@ grn_output_table_columns_by_expression(grn_ctx *ctx, grn_obj *outbuf,
                                        grn_obj *table, grn_obj_format *format,
                                        grn_obj *buf)
 {
-  int n_elements;
-  int previous_comma_offset = -1;
-  grn_bool is_first_comma = GRN_TRUE;
-  grn_bool have_comma = GRN_FALSE;
   grn_expr *expr = (grn_expr *)format->expression;
-  grn_expr_code *code;
-  grn_expr_code *code_end = expr->codes + expr->codes_curr;
+  grn_obj offsets;
+  size_t i, n;
 
-  n_elements = count_n_elements_in_expression(ctx, format->expression);
+  GRN_UINT32_INIT(&offsets, GRN_OBJ_VECTOR);
+  grn_output_columns_get_offsets(ctx, format->expression, &offsets);
 
-  grn_output_table_columns_open(ctx, outbuf, output_type, n_elements);
+  n = GRN_BULK_VSIZE(&offsets) / sizeof(uint32_t) / 2;
 
-  for (code = expr->codes; code < code_end; code++) {
-    int code_start_offset;
+  grn_output_table_columns_open(ctx, outbuf, output_type, n);
 
-    if (code->op != GRN_OP_COMMA) {
-      continue;
-    }
-
-    have_comma = GRN_TRUE;
-    if (is_first_comma) {
-      unsigned int n_used_codes;
-      int code_end_offset;
+  for (i = 0; i < n; i++) {
+    uint32_t code_start_offset;
+    uint32_t code_end_offset;
 
-      n_used_codes = grn_expr_code_n_used_codes(ctx, expr->codes, code - 1);
-      code_end_offset = code - expr->codes - n_used_codes;
-
-      grn_output_table_column_by_expression(ctx, outbuf, output_type,
-                                            expr->codes,
-                                            expr->codes + code_end_offset,
-                                            buf);
-      code_start_offset = code_end_offset;
-      is_first_comma = GRN_FALSE;
-    } else {
-      code_start_offset = previous_comma_offset + 1;
-    }
+    code_start_offset = GRN_UINT32_VALUE_AT(&offsets, i * 2);
+    code_end_offset = GRN_UINT32_VALUE_AT(&offsets, i * 2 + 1);
 
     grn_output_table_column_by_expression(ctx, outbuf, output_type,
                                           expr->codes + code_start_offset,
-                                          code,
-                                          buf);
-    previous_comma_offset = code - expr->codes;
-  }
-
-  if (!have_comma && expr->codes_curr > 0) {
-    grn_output_table_column_by_expression(ctx, outbuf, output_type,
-                                          expr->codes,
-                                          code_end,
+                                          expr->codes + code_end_offset,
                                           buf);
   }
 
   grn_output_table_columns_close(ctx, outbuf, output_type);
+
+  GRN_OBJ_FIN(ctx, &offsets);
 }
 
 static grn_inline void
@@ -1627,9 +1581,16 @@ grn_output_table_record_by_expression(grn_ctx *ctx,
                                       grn_obj *outbuf,
                                       grn_content_type output_type,
                                       grn_obj *expression,
+                                      uint32_t code_start_offset,
+                                      uint32_t code_end_offset,
                                       grn_obj *record)
 {
   grn_expr *expr = (grn_expr *)expression;
+  grn_expr_code *codes = expr->codes;
+  uint32_t codes_curr = expr->codes_curr;
+
+  expr->codes += code_start_offset;
+  expr->codes_curr = code_end_offset - code_start_offset;
 
   if (expr->codes_curr == 1 && expr->codes[0].op == GRN_OP_GET_VALUE) {
     grn_obj *column = expr->codes[0].value;
@@ -1647,6 +1608,9 @@ grn_output_table_record_by_expression(grn_ctx *ctx,
       grn_output_cstr(ctx, outbuf, output_type, ctx->errbuf);
     }
   }
+
+  expr->codes = codes;
+  expr->codes_curr = codes_curr;
 }
 
 static grn_inline void
@@ -1655,69 +1619,39 @@ grn_output_table_records_by_expression(grn_ctx *ctx, grn_obj *outbuf,
                                        grn_table_cursor *tc,
                                        grn_obj_format *format)
 {
-  int n_elements = 0;
+  grn_obj offsets;
+  size_t n;
   grn_id id;
   grn_obj *record;
-  grn_expr *expr = (grn_expr *)format->expression;
-  grn_expr_code *code;
-  grn_expr_code *code_end = expr->codes + expr->codes_curr;
 
-  n_elements = count_n_elements_in_expression(ctx, format->expression);
+  GRN_UINT32_INIT(&offsets, GRN_OBJ_VECTOR);
+  grn_output_columns_get_offsets(ctx, format->expression, &offsets);
+  n = GRN_BULK_VSIZE(&offsets) / sizeof(uint32_t) / 2;
   record = grn_expr_get_var_by_offset(ctx, format->expression, 0);
   while ((id = grn_table_cursor_next(ctx, tc)) != GRN_ID_NIL) {
-    int previous_comma_offset = -1;
-    grn_bool is_first_comma = GRN_TRUE;
-    grn_bool have_comma = GRN_FALSE;
+    size_t i;
+
     GRN_RECORD_SET(ctx, record, id);
-    grn_output_table_record_open(ctx, outbuf, output_type, n_elements);
-    for (code = expr->codes; code < code_end; code++) {
-      if (code->op == GRN_OP_COMMA) {
-        int code_start_offset = previous_comma_offset + 1;
-        int code_end_offset;
-        int original_codes_curr = expr->codes_curr;
-
-        have_comma = GRN_TRUE;
-        if (is_first_comma) {
-          int second_code_offset;
-          unsigned int second_code_n_used_codes;
-          second_code_offset = code - expr->codes - 1;
-          second_code_n_used_codes =
-            grn_expr_code_n_used_codes(ctx,
-                                       expr->codes,
-                                       expr->codes + second_code_offset);
-          expr->codes_curr = second_code_offset - second_code_n_used_codes + 1;
-          grn_output_table_record_by_expression(ctx,
-                                                outbuf,
-                                                output_type,
-                                                format->expression,
-                                                record);
-          code_start_offset = expr->codes_curr;
-          is_first_comma = GRN_FALSE;
-        }
-        code_end_offset = code - expr->codes - code_start_offset;
-        expr->codes += code_start_offset;
-        expr->codes_curr = code_end_offset;
-        grn_output_table_record_by_expression(ctx,
-                                              outbuf,
-                                              output_type,
-                                              format->expression,
-                                              record);
-        expr->codes -= code_start_offset;
-        expr->codes_curr = original_codes_curr;
-        previous_comma_offset = code - expr->codes;
-      }
-    }
+    grn_output_table_record_open(ctx, outbuf, output_type, n);
+    for (i = 0; i < n; i++) {
+      uint32_t code_start_offset;
+      uint32_t code_end_offset;
 
-    if (!have_comma && expr->codes_curr > 0) {
+      code_start_offset = GRN_UINT32_VALUE_AT(&offsets, i * 2);
+      code_end_offset = GRN_UINT32_VALUE_AT(&offsets, i * 2 + 1);
       grn_output_table_record_by_expression(ctx,
                                             outbuf,
                                             output_type,
                                             format->expression,
+                                            code_start_offset,
+                                            code_end_offset,
                                             record);
     }
 
     grn_output_table_record_close(ctx, outbuf, output_type);
   }
+
+  GRN_OBJ_FIN(ctx, &offsets);
 }
 
 static grn_inline void

  Modified: lib/output_columns.c (+70 -40)
===================================================================
--- lib/output_columns.c    2018-12-26 15:31:40 +0900 (7ea6546a5)
+++ lib/output_columns.c    2018-12-27 10:31:47 +0900 (2422aa983)
@@ -18,6 +18,7 @@
 */
 
 #include "grn_expr.h"
+#include "grn_output_columns.h"
 
 grn_obj *
 grn_output_columns_parse(grn_ctx *ctx,
@@ -45,6 +46,56 @@ grn_output_columns_parse(grn_ctx *ctx,
   GRN_API_RETURN(output_columns);
 }
 
+grn_rc
+grn_output_columns_get_offsets(grn_ctx *ctx,
+                               grn_obj *output_columns,
+                               grn_obj *offsets)
+{
+  int previous_comma_offset = -1;
+  grn_bool is_first_comma = GRN_TRUE;
+  grn_bool have_comma = GRN_FALSE;
+  grn_expr *expr = (grn_expr *)output_columns;
+  grn_expr_code *code;
+  grn_expr_code *code_end = expr->codes + expr->codes_curr;
+
+  GRN_API_ENTER;
+
+  for (code = expr->codes; code < code_end; code++) {
+    int code_start_offset;
+
+    if (code->op != GRN_OP_COMMA) {
+      continue;
+    }
+
+    have_comma = GRN_TRUE;
+    if (is_first_comma) {
+      unsigned int n_used_codes;
+      int code_end_offset;
+
+      n_used_codes = grn_expr_code_n_used_codes(ctx, expr->codes, code - 1);
+      code_end_offset = code - expr->codes - n_used_codes;
+      GRN_UINT32_PUT(ctx, offsets, 0);
+      GRN_UINT32_PUT(ctx, offsets, code_end_offset);
+      code_start_offset = code_end_offset;
+      is_first_comma = GRN_FALSE;
+    } else {
+      code_start_offset = previous_comma_offset + 1;
+    }
+
+    GRN_UINT32_PUT(ctx, offsets, code_start_offset);
+    GRN_UINT32_PUT(ctx, offsets, code - expr->codes);
+
+    previous_comma_offset = code - expr->codes;
+  }
+
+  if (!have_comma && expr->codes_curr > 0) {
+    GRN_UINT32_PUT(ctx, offsets, 0);
+    GRN_UINT32_PUT(ctx, offsets, expr->codes_curr);
+  }
+
+  GRN_API_RETURN(ctx->rc);
+}
+
 static void
 grn_output_columns_apply_one(grn_ctx *ctx,
                              grn_obj *output_columns,
@@ -62,7 +113,7 @@ grn_output_columns_apply_one(grn_ctx *ctx,
   size_t n_ids;
 
   expr->codes += code_start_offset;
-  expr->codes_curr = code_end_offset;
+  expr->codes_curr = code_end_offset - code_start_offset;
   grn_expr_executor_init(ctx, &executor, output_columns);
   n_ids = GRN_BULK_VSIZE(ids) / sizeof(grn_id);
   for (i = 0; i < n_ids; i += 2) {
@@ -94,6 +145,7 @@ grn_output_columns_apply(grn_ctx *ctx,
   grn_obj source_key_buffer;
   grn_obj target_key_buffer;
   grn_obj ids;
+  grn_obj offsets;
 
   GRN_API_ENTER;
 
@@ -135,7 +187,8 @@ grn_output_columns_apply(grn_ctx *ctx,
     }
   }
 
-  GRN_RECORD_INIT(&ids, 0, GRN_ID_NIL);
+  GRN_RECORD_INIT(&ids, GRN_OBJ_VECTOR, GRN_ID_NIL);
+  GRN_UINT32_INIT(&offsets, GRN_OBJ_VECTOR);
 
   if (use_keys) {
     GRN_TABLE_EACH_BEGIN(ctx, source_table, cursor, source_id) {
@@ -189,52 +242,28 @@ grn_output_columns_apply(grn_ctx *ctx,
   }
 
   {
-    int previous_comma_offset = -1;
-    grn_bool is_first_comma = GRN_TRUE;
-    grn_bool have_comma = GRN_FALSE;
-    grn_expr *expr = (grn_expr *)output_columns;
-    grn_expr_code *code;
-    grn_expr_code *code_end = expr->codes + expr->codes_curr;
-    size_t i = 0;
-
-    for (code = expr->codes; code < code_end; code++) {
-      int code_start_offset;
-
-      if (code->op != GRN_OP_COMMA) {
-        continue;
-      }
+    size_t i, n;
 
-      have_comma = GRN_TRUE;
-      if (is_first_comma) {
-        unsigned int n_used_codes;
-        int code_end_offset;
-
-        n_used_codes = grn_expr_code_n_used_codes(ctx, expr->codes, code - 1);
-        code_end_offset = code - expr->codes - n_used_codes;
-
-        grn_output_columns_apply_one(ctx,
-                                     output_columns,
-                                     &ids,
-                                     variable,
-                                     0,
-                                     code_end_offset,
-                                     GRN_PTR_VALUE_AT(columns, i));
-        i++;
-        code_start_offset = code_end_offset;
-        is_first_comma = GRN_FALSE;
-      } else {
-        code_start_offset = previous_comma_offset + 1;
-      }
+    grn_output_columns_get_offsets(ctx, output_columns, &offsets);
+    if (ctx->rc != GRN_SUCCESS) {
+      GRN_OBJ_FIN(ctx, &offsets);
+      goto exit;
+    }
+
+    n = GRN_BULK_VSIZE(&offsets) / sizeof(uint32_t) / 2;
+    for (i = 0; i < n; i++) {
+      uint32_t code_start_offset;
+      uint32_t code_end_offset;
 
+      code_start_offset = GRN_UINT32_VALUE_AT(&offsets, i * 2);
+      code_end_offset = GRN_UINT32_VALUE_AT(&offsets, i * 2 + 1);
       grn_output_columns_apply_one(ctx,
                                    output_columns,
                                    &ids,
                                    variable,
                                    code_start_offset,
-                                   code - expr->codes - 1,
+                                   code_end_offset,
                                    GRN_PTR_VALUE_AT(columns, i));
-      i++;
-      previous_comma_offset = code - expr->codes;
     }
   }
 
@@ -245,6 +274,7 @@ exit :
       GRN_OBJ_FIN(ctx, &target_key_buffer);
     }
     GRN_OBJ_FIN(ctx, &ids);
+    GRN_OBJ_FIN(ctx, &offsets);
   }
 
   GRN_API_RETURN(ctx->rc);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.osdn.me/mailman/archives/groonga-commit/attachments/20181227/10ead4a2/attachment-0001.html>


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