[Groonga-commit] groonga/groonga [master] Added sub_search() to pat.c

Zurück zum Archiv-Index

null+****@clear***** null+****@clear*****
2010年 8月 16日 (月) 19:21:00 JST


Daijiro MORI	2010-08-16 10:21:00 +0000 (Mon, 16 Aug 2010)

  New Revision: c6b5f058564ded9ca05b0fd158449613d49b5be1

  Log:
    Added sub_search() to pat.c

  Modified files:
    groonga.h
    lib/pat.c

  Modified: groonga.h (+1 -0)
===================================================================
--- groonga.h    2010-08-16 01:02:07 +0000 (9417b29)
+++ groonga.h    2010-08-16 10:21:00 +0000 (5d586ca)
@@ -665,6 +665,7 @@ typedef grn_obj grn_table_cursor;
 #define GRN_CURSOR_BY_ID               (0x01<<3)
 #define GRN_CURSOR_PREFIX              (0x01<<4)
 #define GRN_CURSOR_SIZE_BY_BIT         (0x01<<5)
+#define GRN_CURSOR_RK                  (0x01<<6)
 
 /**
  * grn_table_cursor_open:

  Modified: lib/pat.c (+77 -6)
===================================================================
--- lib/pat.c    2010-08-16 01:02:07 +0000 (ba3768d)
+++ lib/pat.c    2010-08-16 10:21:00 +0000 (afdeebd)
@@ -2006,6 +2006,9 @@ exit :
   return c;
 }
 
+static grn_rc set_cursor_rk(grn_ctx *ctx, grn_pat *pat, grn_pat_cursor *c,
+                            const void *key, uint32_t key_size, int flags);
+
 grn_pat_cursor *
 grn_pat_cursor_open(grn_ctx *ctx, grn_pat *pat,
                     const void *min, uint32_t min_size,
@@ -2041,7 +2044,11 @@ grn_pat_cursor_open(grn_ctx *ctx, grn_pat *pat,
       goto exit;
     } else {
       if (min && min_size) {
-        set_cursor_prefix(ctx, pat, c, min, min_size, flags);
+        if (flags & GRN_CURSOR_RK) {
+          set_cursor_rk(ctx, pat, c, min, min_size, flags);
+        } else {
+          set_cursor_prefix(ctx, pat, c, min, min_size, flags);
+        }
         goto exit;
       }
     }
@@ -2370,7 +2377,7 @@ typedef struct {
   uint8_t attr;
 } rk_tree_node;
 
-uint16_t rk_str_idx[] = {
+static uint16_t rk_str_idx[] = {
   0x0003, 0x0006, 0x0009, 0x000c, 0x0012, 0x0015, 0x0018, 0x001e, 0x0024, 0x002a,
   0x0030, 0x0036, 0x003c, 0x0042, 0x0048, 0x004e, 0x0054, 0x005a, 0x0060, 0x0066,
   0x006c, 0x0072, 0x0078, 0x007e, 0x0084, 0x008a, 0x0090, 0x0096, 0x009c, 0x00a2,
@@ -2390,7 +2397,7 @@ uint16_t rk_str_idx[] = {
   0x02e8, 0x02eb, 0x02ee, 0x02f1, 0x02f4, 0x02f7, 0x02fa, 0x02fd, 0x0300, 0x0303,
   0x0309, 0x030c, 0x0312, 0x0318, 0x031e, 0x0324, 0x0327, 0x032a, 0x032d
 };
-char rk_str[] = {
+static char rk_str[] = {
   0xe3, 0x82, 0xa1, 0xe3, 0x82, 0xa2, 0xe3, 0x82, 0xa3, 0xe3, 0x82, 0xa4, 0xe3,
   0x82, 0xa4, 0xe3, 0x82, 0xa7, 0xe3, 0x82, 0xa5, 0xe3, 0x82, 0xa6, 0xe3, 0x82,
   0xa6, 0xe3, 0x82, 0xa2, 0xe3, 0x82, 0xa6, 0xe3, 0x82, 0xa3, 0xe3, 0x82, 0xa6,
@@ -2455,7 +2462,7 @@ char rk_str[] = {
   0x83, 0xb4, 0xe3, 0x82, 0xa7, 0xe3, 0x83, 0xb4, 0xe3, 0x82, 0xa9, 0xe3, 0x83,
   0xb5, 0xe3, 0x83, 0xb6, 0xe3, 0x83, 0xbc
 };
-uint16_t rk_tree_idx[] = {
+static uint16_t rk_tree_idx[] = {
   0x001b, 0x0022, 0x0025, 0x0028, 0x002d, 0x0030, 0x0039, 0x003b, 0x003c, 0x003f,
   0x0046, 0x0047, 0x004f, 0x0050, 0x0053, 0x005a, 0x005d, 0x0064, 0x0067, 0x006f,
   0x0070, 0x0073, 0x007a, 0x007f, 0x0086, 0x0089, 0x00a6, 0x00ac, 0x00b3, 0x00b6,
@@ -2463,7 +2470,7 @@ uint16_t rk_tree_idx[] = {
   0x00ed, 0x00f3, 0x00f5, 0x00ff, 0x0101, 0x0103, 0x0104, 0x0105, 0x0108, 0x010d,
   0x0114, 0x0118, 0x011a, 0x0159, 0x0175, 0x0178, 0x018e, 0x01a2
 };
-rk_tree_node rk_tree[] = {
+static rk_tree_node rk_tree[] = {
   {0x2d, 0x00, 0xb2, 0x01}, {0x61, 0x00, 0x01, 0x01}, {0x62, 0x01, 0xff, 0x01},
   {0x63, 0x03, 0xff, 0x01}, {0x64, 0x06, 0xff, 0x01}, {0x65, 0x00, 0x24, 0x01},
   {0x66, 0x0a, 0xff, 0x01}, {0x67, 0x0c, 0xff, 0x01}, {0x68, 0x0f, 0xff, 0x01},
@@ -2648,7 +2655,7 @@ rk_emit(rk_tree_node *node, char **str)
   }\
 }
 
-int
+static uint32_t
 rk_conv(const char *str, uint32_t str_len, char *buf, uint32_t buf_size)
 {
   uint32_t l;
@@ -2674,3 +2681,67 @@ rk_conv(const char *str, uint32_t str_len, char *buf, uint32_t buf_size)
   }
   return oc - buf;
 }
+
+static pat_node *
+sub_search(grn_ctx *ctx, grn_pat *pat, grn_id id, int *c0, uint8_t *key, uint32_t key_len)
+{
+  uint32_t len = key_len * 16;
+  while (id) {
+    int ch;
+    pat_node *node;
+    PAT_AT(pat, id, node);
+    if (!node) { break; }
+    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(key, ch, len)];
+      }
+      *c0 = ch;
+    } else {
+      const uint8_t *k = pat_node_get_key(ctx, pat, node);
+      return (k && key_len <= PAT_LEN(node) && !memcmp(k, key, key_len)) ? node : NULL;
+    }
+  }
+  return NULL;
+}
+
+static grn_rc
+set_cursor_rk(grn_ctx *ctx, grn_pat *pat, grn_pat_cursor *c,
+                  const void *key, uint32_t key_len, int flags)
+{
+  int c0 = -1, ch;
+  uint32_t len, byte_len;
+  grn_id id;
+  pat_node *node;
+  uint8_t keybuf[MAX_FIXED_KEY_SIZE];
+  if (flags & GRN_CURSOR_SIZE_BY_BIT) {
+    return GRN_OPERATION_NOT_SUPPORTED;
+  }
+  byte_len = rk_conv(key, key_len, keybuf, MAX_FIXED_KEY_SIZE);
+  len = byte_len * 16;
+  PAT_AT(pat, 0, node);
+  id = node->lr[1];
+  if ((node = sub_search(ctx, pat, id, &c0, keybuf, byte_len))) {
+    ch = PAT_CHK(node);
+    if (c0 < ch) {
+      if (flags & GRN_CURSOR_DESCENDING) {
+        if ((ch > len - 1) || !(flags & GRN_CURSOR_GT)) {
+          push(c, node->lr[0], ch);
+        }
+        push(c, node->lr[1], ch);
+      } else {
+        push(c, node->lr[1], ch);
+        if ((ch > len - 1) || !(flags & GRN_CURSOR_GT)) {
+          push(c, node->lr[0], ch);
+        }
+      }
+    } else {
+      if (PAT_LEN(node) * 16 > len || !(flags & GRN_CURSOR_GT)) {
+        push(c, id, ch);
+      }
+    }
+  }
+  return ctx->rc;
+}




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