null+****@clear*****
null+****@clear*****
2010年 7月 28日 (水) 09:37:02 JST
Daijiro MORI 2010-07-28 00:37:02 +0000 (Wed, 28 Jul 2010)
New Revision: 85df52cfe641372564fc4be8e6f6f98501bddf80
Log:
Added GRN_CURSOR_SIZE_BY_BIT.
Modified files:
groonga.h
lib/pat.c
Modified: groonga.h (+1 -0)
===================================================================
--- groonga.h 2010-07-27 13:34:14 +0000 (fe72347)
+++ groonga.h 2010-07-28 00:37:02 +0000 (9ea6d9c)
@@ -663,6 +663,7 @@ typedef grn_obj grn_table_cursor;
#define GRN_CURSOR_BY_KEY (0x00<<3)
#define GRN_CURSOR_BY_ID (0x01<<3)
#define GRN_CURSOR_PREFIX (0x01<<4)
+#define GRN_CURSOR_SIZE_BY_BIT (0x01<<5)
/**
* grn_table_cursor_open:
Modified: lib/pat.c (+26 -4)
===================================================================
--- lib/pat.c 2010-07-27 13:34:14 +0000 (75fee65)
+++ lib/pat.c 2010-07-28 00:37:02 +0000 (c9e1d0d)
@@ -1675,17 +1675,37 @@ bitcmp(const void *s1, const void *s2, int offset, int length)
return (*a & mask) - (*b & mask);
}
+static int
+bitcmp2(const char *a, const char *b, uint32_t key_size)
+{
+ uint32_t o = key_size >> 3;
+ uint32_t m = key_size & 7;
+ int r = o ? memcmp(a, b, o) : 0;
+ if (!r && m) {
+ uint8_t mask = 0xff << (8 - m);
+ r = (a[o] & mask) - (b[o] & mask);
+ }
+ return r;
+}
+
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;
+ uint32_t len, byte_len;
grn_id id;
pat_node *node;
uint8_t keybuf[MAX_FIXED_KEY_SIZE];
- KEY_ENCODE(pat, keybuf, key, key_size);
+ if (flags & GRN_CURSOR_SIZE_BY_BIT) {
+ len = key_size * 2;
+ byte_len = key_size >> 3;
+ } else {
+ len = key_size * 16;
+ byte_len = key_size;
+ }
+ KEY_ENCODE(pat, keybuf, key, byte_len);
PAT_AT(pat, 0, node);
id = node->lr[1];
while (id) {
@@ -1702,8 +1722,10 @@ set_cursor_prefix(grn_ctx *ctx, grn_pat *pat, grn_pat_cursor *c,
continue;
}
if (!(k = pat_node_get_key(ctx, pat, node))) { break; }
- if (PAT_LEN(node) < key_size) { break; }
- if (!memcmp(k, key, key_size)) {
+ if (PAT_LEN(node) < byte_len) { break; }
+ if ((flags & GRN_CURSOR_SIZE_BY_BIT)
+ ? !bitcmp2(k, key, key_size)
+ : !memcmp(k, key, key_size)) {
if (flags & GRN_CURSOR_DESCENDING) {
if ((ch > len - 1) || !(flags & GRN_CURSOR_GT)) {
push(c, node->lr[0], ch);