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>