Kouhei Sutou
null+****@clear*****
Fri Sep 23 18:38:23 JST 2016
Kouhei Sutou 2016-09-23 18:38:23 +0900 (Fri, 23 Sep 2016) New Revision: 56bfac9a7f8d64a8af28ef6d2e0bc79abbc9632b https://github.com/groonga/groonga/commit/56bfac9a7f8d64a8af28ef6d2e0bc79abbc9632b Message: schema: close newly opened tables and columns when the max # of thread is 1 Modified files: lib/proc/proc_schema.c Modified: lib/proc/proc_schema.c (+258 -99) =================================================================== --- lib/proc/proc_schema.c 2016-09-23 18:35:41 +0900 (129a067) +++ lib/proc/proc_schema.c 2016-09-23 18:38:23 +0900 (f13fe25) @@ -22,6 +22,10 @@ #include <groonga/plugin.h> +typedef struct { + grn_bool is_close_opened_object_mode; +} grn_schema_data; + static void command_schema_output_name(grn_ctx *ctx, grn_obj *obj) { @@ -176,21 +180,26 @@ command_schema_output_plugins(grn_ctx *ctx) static void command_schema_output_types(grn_ctx *ctx) { - grn_obj types; - unsigned int i, n; - - GRN_PTR_INIT(&types, GRN_OBJ_VECTOR, GRN_DB_OBJECT); + unsigned int n_types; - grn_ctx_get_all_types(ctx, &types); + n_types = 0; + GRN_DB_EACH_BEGIN_BY_KEY(ctx, cursor, id) { + if (grn_id_is_builtin_type(ctx, id)) { + n_types++; + } + } GRN_DB_EACH_END(ctx, cursor); grn_ctx_output_cstr(ctx, "types"); - n = GRN_BULK_VSIZE(&types) / sizeof(grn_obj *); - grn_ctx_output_map_open(ctx, "types", n); - for (i = 0; i < n; i++) { + grn_ctx_output_map_open(ctx, "types", n_types); + GRN_DB_EACH_BEGIN_BY_KEY(ctx, cursor, id) { grn_obj *type; - type = GRN_PTR_VALUE_AT(&types, i); + if (!grn_id_is_builtin_type(ctx, id)) { + continue; + } + + type = grn_ctx_at(ctx, id); command_schema_output_name(ctx, type); @@ -209,30 +218,59 @@ command_schema_output_types(grn_ctx *ctx) grn_ctx_output_bool(ctx, !(type->header.flags & GRN_OBJ_KEY_VAR_SIZE)); grn_ctx_output_map_close(ctx); - } + } GRN_DB_EACH_END(ctx, cursor); grn_ctx_output_map_close(ctx); - - GRN_OBJ_FIN(ctx, &types); } static void -command_schema_output_tokenizers(grn_ctx *ctx) +command_schema_output_tokenizers(grn_ctx *ctx, grn_schema_data *data) { - grn_obj tokenizers; + grn_obj tokenizer_ids; unsigned int i, n; - GRN_PTR_INIT(&tokenizers, GRN_OBJ_VECTOR, GRN_DB_OBJECT); + GRN_RECORD_INIT(&tokenizer_ids, GRN_OBJ_VECTOR, GRN_ID_NIL); + GRN_DB_EACH_BEGIN_BY_KEY(ctx, cursor, id) { + void *name; + int name_size; + grn_obj *object; - grn_ctx_get_all_tokenizers(ctx, &tokenizers); + name_size = grn_table_cursor_get_key(ctx, cursor, &name); + if (grn_obj_name_is_column(ctx, name, name_size)) { + continue; + } + + if (data->is_close_opened_object_mode) { + grn_ctx_push_temporary_open_space(ctx); + } + + object = grn_ctx_at(ctx, id); + if (object) { + if (grn_obj_is_tokenizer_proc(ctx, object)) { + GRN_RECORD_PUT(ctx, &tokenizer_ids, id); + } + } else { + /* XXX: this clause is executed when MeCab tokenizer is enabled in + database but the groonga isn't supported MeCab. + We should return error mesage about it and error exit status + but it's too difficult for this architecture. :< */ + GRN_PLUGIN_CLEAR_ERROR(ctx); + } + + if (data->is_close_opened_object_mode) { + grn_ctx_pop_temporary_open_space(ctx); + } + } GRN_DB_EACH_END(ctx, cursor); grn_ctx_output_cstr(ctx, "tokenizers"); - n = GRN_BULK_VSIZE(&tokenizers) / sizeof(grn_obj *); + n = GRN_BULK_VSIZE(&tokenizer_ids) / sizeof(grn_id); grn_ctx_output_map_open(ctx, "tokenizers", n); for (i = 0; i < n; i++) { + grn_id tokenizer_id; grn_obj *tokenizer; - tokenizer = GRN_PTR_VALUE_AT(&tokenizers, i); + tokenizer_id = GRN_RECORD_VALUE_AT(&tokenizer_ids, i); + tokenizer = grn_ctx_at(ctx, tokenizer_id); command_schema_output_name(ctx, tokenizer); @@ -245,27 +283,58 @@ command_schema_output_tokenizers(grn_ctx *ctx) } grn_ctx_output_map_close(ctx); - GRN_OBJ_FIN(ctx, &tokenizers); + GRN_OBJ_FIN(ctx, &tokenizer_ids); } static void -command_schema_output_normalizers(grn_ctx *ctx) +command_schema_output_normalizers(grn_ctx *ctx, grn_schema_data *data) { - grn_obj normalizers; + grn_obj normalizer_ids; unsigned int i, n; - GRN_PTR_INIT(&normalizers, GRN_OBJ_VECTOR, GRN_DB_OBJECT); + GRN_RECORD_INIT(&normalizer_ids, GRN_OBJ_VECTOR, GRN_ID_NIL); + GRN_DB_EACH_BEGIN_BY_KEY(ctx, cursor, id) { + void *name; + int name_size; + grn_obj *object; + + name_size = grn_table_cursor_get_key(ctx, cursor, &name); + if (grn_obj_name_is_column(ctx, name, name_size)) { + continue; + } + + if (data->is_close_opened_object_mode) { + grn_ctx_push_temporary_open_space(ctx); + } + + object = grn_ctx_at(ctx, id); + if (object) { + if (grn_obj_is_normalizer_proc(ctx, object)) { + GRN_RECORD_PUT(ctx, &normalizer_ids, id); + } + } else { + /* XXX: this clause is executed when MeCab normalizer is enabled in + database but the groonga isn't supported MeCab. + We should return error mesage about it and error exit status + but it's too difficult for this architecture. :< */ + GRN_PLUGIN_CLEAR_ERROR(ctx); + } - grn_ctx_get_all_normalizers(ctx, &normalizers); + if (data->is_close_opened_object_mode) { + grn_ctx_pop_temporary_open_space(ctx); + } + } GRN_DB_EACH_END(ctx, cursor); grn_ctx_output_cstr(ctx, "normalizers"); - n = GRN_BULK_VSIZE(&normalizers) / sizeof(grn_obj *); + n = GRN_BULK_VSIZE(&normalizer_ids) / sizeof(grn_id); grn_ctx_output_map_open(ctx, "normalizers", n); for (i = 0; i < n; i++) { + grn_id normalizer_id; grn_obj *normalizer; - normalizer = GRN_PTR_VALUE_AT(&normalizers, i); + normalizer_id = GRN_RECORD_VALUE_AT(&normalizer_ids, i); + normalizer = grn_ctx_at(ctx, normalizer_id); command_schema_output_name(ctx, normalizer); @@ -278,27 +347,58 @@ command_schema_output_normalizers(grn_ctx *ctx) } grn_ctx_output_map_close(ctx); - GRN_OBJ_FIN(ctx, &normalizers); + GRN_OBJ_FIN(ctx, &normalizer_ids); } static void -command_schema_output_token_filters(grn_ctx *ctx) +command_schema_output_token_filters(grn_ctx *ctx, grn_schema_data *data) { - grn_obj token_filters; - int i, n; + grn_obj token_filter_ids; + unsigned int i, n; - GRN_PTR_INIT(&token_filters, GRN_OBJ_VECTOR, GRN_DB_OBJECT); + GRN_RECORD_INIT(&token_filter_ids, GRN_OBJ_VECTOR, GRN_ID_NIL); + GRN_DB_EACH_BEGIN_BY_KEY(ctx, cursor, id) { + void *name; + int name_size; + grn_obj *object; + + name_size = grn_table_cursor_get_key(ctx, cursor, &name); + if (grn_obj_name_is_column(ctx, name, name_size)) { + continue; + } - grn_ctx_get_all_token_filters(ctx, &token_filters); + if (data->is_close_opened_object_mode) { + grn_ctx_push_temporary_open_space(ctx); + } + + object = grn_ctx_at(ctx, id); + if (object) { + if (grn_obj_is_token_filter_proc(ctx, object)) { + GRN_RECORD_PUT(ctx, &token_filter_ids, id); + } + } else { + /* XXX: this clause is executed when MeCab normalizer is enabled in + database but the groonga isn't supported MeCab. + We should return error mesage about it and error exit status + but it's too difficult for this architecture. :< */ + GRN_PLUGIN_CLEAR_ERROR(ctx); + } + + if (data->is_close_opened_object_mode) { + grn_ctx_pop_temporary_open_space(ctx); + } + } GRN_DB_EACH_END(ctx, cursor); grn_ctx_output_cstr(ctx, "token_filters"); - n = GRN_BULK_VSIZE(&token_filters) / sizeof(grn_obj *); + n = GRN_BULK_VSIZE(&token_filter_ids) / sizeof(grn_id); grn_ctx_output_map_open(ctx, "token_filters", n); for (i = 0; i < n; i++) { + grn_id token_filter_id; grn_obj *token_filter; - token_filter = GRN_PTR_VALUE_AT(&token_filters, i); + token_filter_id = GRN_RECORD_VALUE_AT(&token_filter_ids, i); + token_filter = grn_ctx_at(ctx, token_filter_id); command_schema_output_name(ctx, token_filter); @@ -311,7 +411,7 @@ command_schema_output_token_filters(grn_ctx *ctx) } grn_ctx_output_map_close(ctx); - GRN_OBJ_FIN(ctx, &token_filters); + GRN_OBJ_FIN(ctx, &token_filter_ids); } static const char * @@ -675,24 +775,22 @@ command_schema_column_output_sources(grn_ctx *ctx, grn_obj *column) } static void -command_schema_column_output_indexes(grn_ctx *ctx, grn_obj *column) +command_schema_output_indexes(grn_ctx *ctx, grn_obj *object) { uint32_t i; grn_index_datum *index_data = NULL; uint32_t n_index_data = 0; - if (column) { - n_index_data = grn_column_get_all_index_data(ctx, column, NULL, 0); - if (n_index_data > 0) { - index_data = GRN_PLUGIN_MALLOC(ctx, - sizeof(grn_index_datum) * n_index_data); - if (!index_data) { - GRN_PLUGIN_ERROR(ctx, GRN_NO_MEMORY_AVAILABLE, - "[schema] failed to allocate memory for indexes"); - return; - } - grn_column_get_all_index_data(ctx, column, index_data, n_index_data); + n_index_data = grn_column_get_all_index_data(ctx, object, NULL, 0); + if (n_index_data > 0) { + index_data = GRN_PLUGIN_MALLOC(ctx, + sizeof(grn_index_datum) * n_index_data); + if (!index_data) { + GRN_PLUGIN_ERROR(ctx, GRN_NO_MEMORY_AVAILABLE, + "[schema] failed to allocate memory for indexes"); + return; } + grn_column_get_all_index_data(ctx, object, index_data, n_index_data); } grn_ctx_output_array_open(ctx, "indexes", n_index_data); @@ -725,9 +823,9 @@ command_schema_column_output_indexes(grn_ctx *ctx, grn_obj *column) static void command_schema_column_command_collect_arguments(grn_ctx *ctx, - grn_obj *table, - grn_obj *column, - grn_obj *arguments) + grn_obj *table, + grn_obj *column, + grn_obj *arguments) { #define ADD(name_, value_) \ grn_vector_add_element(ctx, arguments, \ @@ -823,7 +921,9 @@ command_schema_column_command_collect_arguments(grn_ctx *ctx, } static void -command_schema_column_output_command(grn_ctx *ctx, grn_obj *table, grn_obj *column) +command_schema_column_output_command(grn_ctx *ctx, + grn_obj *table, + grn_obj *column) { grn_obj arguments; @@ -877,7 +977,7 @@ command_schema_column_output(grn_ctx *ctx, grn_obj *table, grn_obj *column) command_schema_column_output_sources(ctx, column); grn_ctx_output_cstr(ctx, "indexes"); - command_schema_column_output_indexes(ctx, column); + command_schema_output_indexes(ctx, column); grn_ctx_output_cstr(ctx, "command"); command_schema_column_output_command(ctx, table, column); @@ -886,7 +986,9 @@ command_schema_column_output(grn_ctx *ctx, grn_obj *table, grn_obj *column) } static void -command_schema_table_output_columns(grn_ctx *ctx, grn_obj *table) +command_schema_table_output_columns(grn_ctx *ctx, + grn_obj *table, + grn_schema_data *data) { grn_hash *columns; @@ -904,8 +1006,17 @@ command_schema_table_output_columns(grn_ctx *ctx, grn_obj *table) grn_id *key; GRN_HASH_EACH(ctx, columns, id, &key, NULL, NULL, { grn_obj *column; + + if (data->is_close_opened_object_mode) { + grn_ctx_push_temporary_open_space(ctx); + } + column = grn_ctx_at(ctx, *key); command_schema_column_output(ctx, table, column); + + if (data->is_close_opened_object_mode) { + grn_ctx_pop_temporary_open_space(ctx); + } }); } grn_ctx_output_map_close(ctx); @@ -913,84 +1024,132 @@ command_schema_table_output_columns(grn_ctx *ctx, grn_obj *table) } static void -command_schema_output_tables(grn_ctx *ctx) +command_schema_output_table(grn_ctx *ctx, + grn_schema_data *data, + grn_obj *table) { - grn_obj tables; - unsigned int i, n; + command_schema_output_name(ctx, table); - GRN_PTR_INIT(&tables, GRN_OBJ_VECTOR, GRN_DB_OBJECT); + grn_ctx_output_map_open(ctx, "table", 10); - grn_ctx_get_all_tables(ctx, &tables); + grn_ctx_output_cstr(ctx, "name"); + command_schema_output_name(ctx, table); - grn_ctx_output_cstr(ctx, "tables"); + grn_ctx_output_cstr(ctx, "type"); + grn_ctx_output_cstr(ctx, command_schema_table_type_name(ctx, table)); - n = GRN_BULK_VSIZE(&tables) / sizeof(grn_obj *); - grn_ctx_output_map_open(ctx, "tables", n); - for (i = 0; i < n; i++) { - grn_obj *table; + grn_ctx_output_cstr(ctx, "key_type"); + command_schema_table_output_key_type(ctx, table); - table = GRN_PTR_VALUE_AT(&tables, i); + grn_ctx_output_cstr(ctx, "value_type"); + command_schema_table_output_value_type(ctx, table); - command_schema_output_name(ctx, table); + grn_ctx_output_cstr(ctx, "tokenizer"); + command_schema_table_output_tokenizer(ctx, table); - grn_ctx_output_map_open(ctx, "table", 10); + grn_ctx_output_cstr(ctx, "normalizer"); + command_schema_table_output_normalizer(ctx, table); - grn_ctx_output_cstr(ctx, "name"); - command_schema_output_name(ctx, table); + grn_ctx_output_cstr(ctx, "token_filters"); + command_schema_table_output_token_filters(ctx, table); - grn_ctx_output_cstr(ctx, "type"); - grn_ctx_output_cstr(ctx, command_schema_table_type_name(ctx, table)); + grn_ctx_output_cstr(ctx, "indexes"); + command_schema_output_indexes(ctx, table); + + grn_ctx_output_cstr(ctx, "command"); + command_schema_table_output_command(ctx, table); + + grn_ctx_output_cstr(ctx, "columns"); + command_schema_table_output_columns(ctx, table, data); + + grn_ctx_output_map_close(ctx); +} - grn_ctx_output_cstr(ctx, "key_type"); - command_schema_table_output_key_type(ctx, table); +static void +command_schema_output_tables(grn_ctx *ctx, grn_schema_data *data) +{ + grn_obj table_ids; + unsigned int i, n; - grn_ctx_output_cstr(ctx, "value_type"); - command_schema_table_output_value_type(ctx, table); + GRN_RECORD_INIT(&table_ids, GRN_OBJ_VECTOR, GRN_ID_NIL); + GRN_DB_EACH_BEGIN_BY_KEY(ctx, cursor, id) { + void *name; + int name_size; + grn_obj *object; - grn_ctx_output_cstr(ctx, "tokenizer"); - command_schema_table_output_tokenizer(ctx, table); + if (grn_id_is_builtin(ctx, id)) { + continue; + } + + name_size = grn_table_cursor_get_key(ctx, cursor, &name); + if (grn_obj_name_is_column(ctx, name, name_size)) { + continue; + } - grn_ctx_output_cstr(ctx, "normalizer"); - command_schema_table_output_normalizer(ctx, table); + if (data->is_close_opened_object_mode) { + grn_ctx_push_temporary_open_space(ctx); + } - grn_ctx_output_cstr(ctx, "token_filters"); - command_schema_table_output_token_filters(ctx, table); + object = grn_ctx_at(ctx, id); + if (!object) { + /* XXX: this clause is executed when MeCab tokenizer is enabled in + database but the groonga isn't supported MeCab. + We should return error mesage about it and error exit status + but it's too difficult for this architecture. :< */ + GRN_PLUGIN_CLEAR_ERROR(ctx); + goto next_loop; + } - grn_ctx_output_cstr(ctx, "indexes"); - if (table->header.type == GRN_TABLE_NO_KEY) { - command_schema_column_output_indexes(ctx, NULL); - } else { - grn_obj *key_column; - key_column = grn_obj_column(ctx, table, - GRN_COLUMN_NAME_KEY, - GRN_COLUMN_NAME_KEY_LEN); - command_schema_column_output_indexes(ctx, key_column); - grn_obj_unlink(ctx, key_column); + if (grn_obj_is_table(ctx, object)) { + GRN_RECORD_PUT(ctx, &table_ids, id); } - grn_ctx_output_cstr(ctx, "command"); - command_schema_table_output_command(ctx, table); + next_loop : + if (data->is_close_opened_object_mode) { + grn_ctx_pop_temporary_open_space(ctx); + } + } GRN_TABLE_EACH_END(ctx, cursor); - grn_ctx_output_cstr(ctx, "columns"); - command_schema_table_output_columns(ctx, table); + n = GRN_BULK_VSIZE(&table_ids) / sizeof(grn_id); - grn_ctx_output_map_close(ctx); + grn_ctx_output_cstr(ctx, "tables"); + grn_ctx_output_map_open(ctx, "tables", n); + for (i = 0; i < n; i++) { + grn_id table_id; + grn_obj *table; + + if (data->is_close_opened_object_mode) { + grn_ctx_push_temporary_open_space(ctx); + } + + table_id = GRN_RECORD_VALUE_AT(&table_ids, i); + table = grn_ctx_at(ctx, table_id); + + command_schema_output_table(ctx, data, table); + + if (data->is_close_opened_object_mode) { + grn_ctx_pop_temporary_open_space(ctx); + } } grn_ctx_output_map_close(ctx); - GRN_OBJ_FIN(ctx, &tables); + GRN_OBJ_FIN(ctx, &table_ids); } static grn_obj * command_schema(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) { + grn_schema_data data; + + data.is_close_opened_object_mode = (grn_thread_get_limit() == 1); + grn_ctx_output_map_open(ctx, "schema", 6); command_schema_output_plugins(ctx); command_schema_output_types(ctx); - command_schema_output_tokenizers(ctx); - command_schema_output_normalizers(ctx); - command_schema_output_token_filters(ctx); - command_schema_output_tables(ctx); + command_schema_output_tokenizers(ctx, &data); + command_schema_output_normalizers(ctx, &data); + command_schema_output_token_filters(ctx, &data); + command_schema_output_tables(ctx, &data); grn_ctx_output_map_close(ctx); return NULL; -------------- next part -------------- HTML����������������������������...Download