Kouhei Sutou
null+****@clear*****
Mon Jan 16 17:05:16 JST 2017
Kouhei Sutou 2017-01-16 17:05:16 +0900 (Mon, 16 Jan 2017) New Revision: 7dd19103de5df2f8c0af7ac47b9149d421a0aa5d https://github.com/groonga/groonga/commit/7dd19103de5df2f8c0af7ac47b9149d421a0aa5d Message: ii: use decremental PREFIX instead of ASCENDING|GT GitHub: #617 It improves the buffer_new's worst case. Modified files: lib/ii.c Modified: lib/ii.c (+77 -22) =================================================================== --- lib/ii.c 2017-01-16 15:53:39 +0900 (fce61c6) +++ lib/ii.c 2017-01-16 17:05:16 +0900 (27d952d) @@ -4016,15 +4016,88 @@ buffer_new_find_segment(grn_ctx *ctx, array_unref(ii, tid); } +inline static void +buffer_new_lexicon_pat(grn_ctx *ctx, + grn_ii *ii, + int size, + grn_id id, + grn_hash *h, + buffer **b, + uint32_t *lseg, + uint32_t *pseg) +{ + grn_pat_cursor *cursor; + char key[GRN_TABLE_MAX_KEY_SIZE]; + int key_size; + + key_size = grn_table_get_key(ctx, ii->lexicon, id, key, + GRN_TABLE_MAX_KEY_SIZE); + if (ii->lexicon->header.flags & GRN_OBJ_KEY_VAR_SIZE) { + int target_key_size = key_size; + + while (*lseg == NOT_ASSIGNED && target_key_size > 0) { + grn_id tid; + + cursor = grn_pat_cursor_open(ctx, + (grn_pat *)(ii->lexicon), + key, target_key_size, + NULL, 0, 0, -1, + GRN_CURSOR_PREFIX); + target_key_size--; + if (!cursor) { + break; + } + + while (ctx->rc == GRN_SUCCESS && + *lseg == NOT_ASSIGNED && + (tid = grn_pat_cursor_next(ctx, cursor))) { + buffer_new_find_segment(ctx, ii, size, tid, h, b, lseg, pseg); + } + grn_pat_cursor_close(ctx, cursor); + } + } else { + cursor = grn_pat_cursor_open(ctx, + (grn_pat *)(ii->lexicon), + NULL, 0, key, key_size, 0, -1, + GRN_CURSOR_PREFIX); + if (cursor) { + grn_id tid; + while (ctx->rc == GRN_SUCCESS && + *lseg == NOT_ASSIGNED && + (tid = grn_pat_cursor_next(ctx, cursor))) { + buffer_new_find_segment(ctx, ii, size, tid, h, b, lseg, pseg); + } + grn_pat_cursor_close(ctx, cursor); + } + } +} + +inline static void +buffer_new_lexicon_other(grn_ctx *ctx, + grn_ii *ii, + int size, + grn_id id, + grn_hash *h, + buffer **b, + uint32_t *lseg, + uint32_t *pseg) +{ + GRN_TABLE_EACH_BEGIN(ctx, ii->lexicon, cursor, tid) { + if (ctx->rc != GRN_SUCCESS || *lseg != NOT_ASSIGNED) { + break; + } + buffer_new_find_segment(ctx, ii, size, tid, h, b, lseg, pseg); + } GRN_TABLE_EACH_END(ctx, cursor); +} + + inline static uint32_t buffer_new(grn_ctx *ctx, grn_ii *ii, int size, uint32_t *pos, buffer_term **bt, buffer_rec **br, buffer **bp, grn_id id, grn_hash *h) { buffer *b = NULL; - grn_id tid; uint16_t offset; uint32_t lseg = NOT_ASSIGNED, pseg = NOT_ASSIGNED; - grn_table_cursor *tc = NULL; if (S_SEGMENT - sizeof(buffer_header) < size + sizeof(buffer_term)) { DEFINE_NAME(ii); MERR("[ii][buffer][new] requested size is too large: " @@ -4036,27 +4109,9 @@ buffer_new(grn_ctx *ctx, grn_ii *ii, int size, uint32_t *pos, return NOT_ASSIGNED; } if (ii->lexicon->header.type == GRN_TABLE_PAT_KEY) { - char key[GRN_TABLE_MAX_KEY_SIZE]; - int key_size = grn_table_get_key(ctx, ii->lexicon, id, key, - GRN_TABLE_MAX_KEY_SIZE); - if (ii->lexicon->header.flags & GRN_OBJ_KEY_VAR_SIZE) { - tc = grn_table_cursor_open(ctx, ii->lexicon, key, key_size, NULL, 0, 0, -1, - GRN_CURSOR_ASCENDING|GRN_CURSOR_GT); - } else { - tc = grn_table_cursor_open(ctx, ii->lexicon, NULL, 0, key, key_size, 0, -1, - GRN_CURSOR_PREFIX); - } + buffer_new_lexicon_pat(ctx, ii, size, id, h, &b, &lseg, &pseg); } else { - tc = grn_table_cursor_open(ctx, ii->lexicon, NULL, 0, NULL, 0, 0, -1, - GRN_CURSOR_ASCENDING); - } - if (tc) { - while (ctx->rc == GRN_SUCCESS && - lseg == NOT_ASSIGNED && - (tid = grn_table_cursor_next(ctx, tc))) { - buffer_new_find_segment(ctx, ii, size, tid, h, &b, &lseg, &pseg); - } - grn_table_cursor_close(ctx, tc); + buffer_new_lexicon_other(ctx, ii, size, id, h, &b, &lseg, &pseg); } if (lseg == NOT_ASSIGNED) { if (buffer_segment_new(ctx, ii, &lseg) || -------------- next part -------------- HTML����������������������������...Download