null+****@clear*****
null+****@clear*****
2010年 6月 29日 (火) 13:27:15 JST
Daijiro MORI 2010-06-29 04:27:15 +0000 (Tue, 29 Jun 2010) New Revision: bda13c4db013e3d5b324dcc15e8557e5c909c4a3 Log: Added set_cursor_prefix(). Modified files: lib/pat.c Modified: lib/pat.c (+42 -0) =================================================================== --- lib/pat.c 2010-06-28 10:29:45 +0000 (379630d) +++ lib/pat.c 2010-06-29 04:27:15 +0000 (2242b79) @@ -1598,6 +1598,45 @@ bitcmp(const void *s1, const void *s2, int offset, int length) } inline static grn_rc +set_cursor_prefix(grn_ctx *ctx, grn_pat *pat, grn_pat_cursor *c, + const void *key, uint32_t key_size, int flags) +{ + int c0 = -1, ch; + const uint8_t *k; + uint32_t len = key_size * 16; + grn_id id; + pat_node *node; + uint8_t keybuf[MAX_FIXED_KEY_SIZE]; + KEY_ENCODE(pat, keybuf, key, key_size); + PAT_AT(pat, 0, node); + id = node->lr[1]; + while (id) { + PAT_AT(pat, id, node); + if (!node) { return GRN_FILE_CORRUPT; } + ch = PAT_CHK(node); + if (c0 < ch && ch < len - 1) { + if (ch & 1) { + id = (ch + 1 < len) ? node->lr[1] : node->lr[0]; + } else { + id = node->lr[nth_bit((uint8_t *)key, ch, len)]; + } + c0 = ch; + continue; + } + if (!(k = pat_node_get_key(ctx, pat, node))) { break; } + if (PAT_LEN(node) < key_size) { break; } + if (!memcmp(k, key, key_size)) { + push(c, node->lr[1], ch); + if ((ch > len - 1) || !(flags & GRN_CURSOR_GT)) { + push(c, node->lr[0], ch); + } + } + break; + } + return GRN_SUCCESS; +} + +inline static grn_rc set_cursor_ascend(grn_ctx *ctx, grn_pat *pat, grn_pat_cursor *c, const void *key, uint32_t key_size, int flags) { @@ -1607,6 +1646,9 @@ set_cursor_ascend(grn_ctx *ctx, grn_pat *pat, grn_pat_cursor *c, int r, check = -1, ch, c2; uint32_t len = key_size * 16; uint8_t keybuf[MAX_FIXED_KEY_SIZE]; + if (flags & GRN_CURSOR_PREFIX) { + return set_cursor_prefix(ctx, pat, c, key, key_size, flags); + } KEY_ENCODE(pat, keybuf, key, key_size); PAT_AT(pat, 0, node); for (id = node->lr[1]; id;) {