[Groonga-commit] groonga/groonga [master] Added GRN_CURSOR_SIZE_BY_BIT.

Zurück zum Archiv-Index

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);




Groonga-commit メーリングリストの案内
Zurück zum Archiv-Index