[Groonga-commit] groonga/groonga [master] add a test for patricia trie cursor with GRN_CURSOR_SIZE_BY_BIT.

アーカイブの一覧に戻る

null+****@clear***** null+****@clear*****
2010年 8月 2日 (月) 15:20:03 JST


Kouhei Sutou	2010-08-02 06:20:03 +0000 (Mon, 02 Aug 2010)

  New Revision: bf7a82d44fcb9e7df10f1b4e18370b0a06015aae

  Log:
    add a test for patricia trie cursor with GRN_CURSOR_SIZE_BY_BIT.

  Modified files:
    test/unit/core/test-table-patricia-trie-cursor.c

  Modified: test/unit/core/test-table-patricia-trie-cursor.c (+319 -30)
===================================================================
--- test/unit/core/test-table-patricia-trie-cursor.c    2010-07-30 08:16:33 +0000 (dc99e44)
+++ test/unit/core/test-table-patricia-trie-cursor.c    2010-08-02 06:20:03 +0000 (fe27d26)
@@ -41,6 +41,8 @@
 
 void data_prefix_short_text(void);
 void test_prefix_short_text(gpointer data);
+void data_prefix_geo_point(void);
+void test_prefix_geo_point(gpointer data);
 void data_near_uint32(void);
 void test_near_uint32(gpointer data);
 void data_near_geo_point(void);
@@ -161,45 +163,20 @@ create_uint32_table(void)
 }
 
 static void
-create_geo_point_table(void)
+create_geo_point_table(const gchar *data)
 {
   const char *table_name = "GeoPointPat";
 
   assert_send_commands(
-    cut_take_printf("table_create %s TABLE_PAT_KEY UInt32", table_name));
+    cut_take_printf("table_create %s TABLE_PAT_KEY WGS84GeoPoint", table_name));
   assert_send_commands(
     cut_take_printf("load --table %s\n"
                     "[\n"
                     " [\"_key\"],\n"
-                    " [\"%s\"],"
-                    " [\"%s\"],"
-                    " [\"%s\"],"
-                    " [\"%s\"],"
-                    " [\"%s\"],"
-                    " [\"%s\"],"
-                    " [\"%s\"],"
-                    " [\"%s\"],"
-                    " [\"%s\"]"
+                    "%s"
                     "]",
                     table_name,
-                    TAKEN_POINT(1, 2, 3,
-                                4, 5, 6),
-                    TAKEN_POINT(1, 2, 3,
-                                7, 8, 9),
-                    TAKEN_POINT(7, 8, 9,
-                                4, 5, 6),
-                    TAKEN_POINT(89, 59, 59,
-                                179, 59, 59),
-                    TAKEN_POINT(89, 59, 59,
-                                179, -59, -59),
-                    TAKEN_POINT(88, 58, 58,
-                                178, 58, 58),
-                    TAKEN_POINT(-89, -59, -59,
-                                -179, -59, -59),
-                    TAKEN_POINT(-89, -59, -59,
-                                179, 59, 59),
-                    TAKEN_POINT(-88, -58, -58,
-                                -178, -58, -58)));
+                    data));
 
   table = grn_ctx_get(context, table_name, strlen(table_name));
 }
@@ -309,6 +286,291 @@ test_prefix_short_text(gpointer data)
   gcut_assert_equal_list_string(expected_keys, actual_keys);
 }
 
+static void
+grn_gton(uint8_t *keybuf, const void *key, uint32_t size)
+{
+  int la = ((grn_geo_point *)key)->latitude;
+  int lo = ((grn_geo_point *)key)->longitude;
+  uint8_t *p = keybuf;
+  int i = 32;
+  while (i) {
+    i -= 4;
+    *p++ = ((((la >> i) & 8) << 4) + (((lo >> i) & 8) << 3) +
+            (((la >> i) & 4) << 3) + (((lo >> i) & 4) << 2) +
+            (((la >> i) & 2) << 2) + (((lo >> i) & 2) << 1) +
+            (((la >> i) & 1) << 1) + (((lo >> i) & 1) << 0));
+  }
+}
+
+static void
+grn_ntog(uint8_t *keybuf, uint8_t *key, uint32_t size)
+{
+  int la = 0, lo = 0;
+  uint8_t v, *p = key;
+  int i = 32;
+  while (size--) {
+    i -= 4;
+    v = *p++;
+    la += (((v & 128) >> 4) + ((v &  32) >> 3) +
+           ((v &   8) >> 2) + ((v &   2) >> 1)) << i;
+    lo += (((v &  64) >> 3) + ((v &  16) >> 2) +
+           ((v &   4) >> 1) + ((v &   1) >> 0)) << i;
+  }
+  ((grn_geo_point *)keybuf)->latitude = la;
+  ((grn_geo_point *)keybuf)->longitude = lo;
+}
+
+static const gchar *
+geo_byte_parse(const gchar *geo_byte_string)
+{
+    gint i = 0;
+    uint8_t geo_byte[sizeof(grn_geo_point)];
+    grn_geo_point geo_point;
+
+    while (geo_byte_string[0]) {
+      switch (geo_byte_string[0]) {
+      case '0':
+        geo_byte[i / 8] &= ~(1 << (7 - (i % 8)));
+        i++;
+        break;
+      case '1':
+        geo_byte[i / 8] |= 1 << (7 - (i % 8));
+        i++;
+        break;
+      default:
+        break;
+      }
+      geo_byte_string++;
+    }
+    grn_ntog((uint8_t *)(&geo_point), geo_byte, sizeof(grn_geo_point));
+    return cut_take_printf("%dx%d",
+                           geo_point.latitude,
+                           geo_point.longitude);
+}
+
+static GList *
+geo_byte_list_new_va_list(const gchar *value, va_list args)
+{
+  GList *list = NULL;
+
+  while (value) {
+    list = g_list_prepend(list, g_strdup(geo_byte_parse(value)));
+    value = va_arg(args, const gchar *);
+  }
+
+  return g_list_reverse(list);
+}
+
+static GList *
+geo_byte_list_new(const gchar *value, ...)
+{
+  GList *list = NULL;
+  va_list args;
+
+  va_start(args, value);
+  list = geo_byte_list_new_va_list(value, args);
+  va_end(args);
+
+  return list;
+}
+
+static const gchar *
+geo_byte_load_data(const gchar *value, ...)
+{
+  GString *data;
+  GList *list, *node;
+  va_list args;
+
+  va_start(args, value);
+  list = geo_byte_list_new_va_list(value, args);
+  va_end(args);
+
+  data = g_string_new(NULL);
+  for (node = list; node; node = g_list_next(node)) {
+    const gchar *point = node->data;
+    g_string_append_printf(data, "[\"%s\"]", point);
+    if (g_list_next(node)) {
+      g_string_append_printf(data, ",\n");
+    }
+  }
+  gcut_list_string_free(list);
+
+  return cut_take_string(g_string_free(data, FALSE));
+}
+
+void
+data_prefix_geo_point(void)
+{
+#define ADD_DATA(label, expected, min, min_size, offset, limit, flags)  \
+  gcut_add_datum(label,                                                 \
+                 "expected", G_TYPE_POINTER,                            \
+                 expected, gcut_list_string_free,                       \
+                 "min", G_TYPE_STRING, min,                             \
+                 "min-size", G_TYPE_UINT, min_size,                     \
+                 "offset", G_TYPE_INT, offset,                          \
+                 "limit", G_TYPE_INT, limit,                            \
+                 "flags", G_TYPE_INT, flags,                            \
+                 NULL)
+
+  ADD_DATA(
+    "bit - ascending",
+    gcut_list_string_new(
+      "00000000 00111111 01010000 00000000 01111101 00010000 00011101 00001111",
+      "00000000 00111111 01010000 00000001 00011110 01010001 01101001 00110000",
+      "00000000 00111111 01010000 00001101 01011101 01011011 01011001 01010011",
+      "00000000 00111111 01010000 00001111 00101011 00011111 00110011 00001001",
+      "00000000 00111111 01010000 00010010 00110001 00001000 00001010 00110011",
+      "00000000 00111111 01010000 00010010 00110001 00110111 01111000 01110000",
+      "00000000 00111111 01010000 00011000 01110000 00001011 00101110 01001010",
+      "00000000 00111111 01010000 00100000 00010111 01000111 00110100 00101010",
+      "00000000 00111111 01010000 00100010 00100111 01000011 00000010 01101001",
+      "00000000 00111111 01010000 00100010 00111011 01000000 00111000 01100100",
+      "00000000 00111111 01010000 00100011 00000001 00000111 01011100 01110011",
+      "00000000 00111111 01010000 00100011 00001010 00000000 00001101 00111010",
+      "00000000 00111111 01010000 00100011 01100100 01011000 00000111 01110010",
+      "00000000 00111111 01010000 00101101 00101000 00111111 01010110 00010110",
+      "00000000 00111111 01010000 00101101 01111100 01101100 00111000 01111001",
+      "00000000 00111111 01010000 00101110 01010011 00101001 00101001 00100011",
+      "00000000 00111111 01010000 00101110 01110010 00111001 00011011 01101010",
+      "00000000 00111111 01010000 00101111 00011000 01000110 00100101 01011110",
+      "00000000 00111111 01010000 00101111 01001010 01101000 01000100 01100011",
+      "00000000 00111111 01010000 00110000 01001010 01011100 01101010 00010001",
+      "00000000 00111111 01010000 00111000 01100100 01101011 01111100 01111011",
+      "00000000 00111111 01010000 00111001 00111101 00001001 00001011 01010011",
+      "00000000 00111111 01010000 00111010 01011111 00000010 00101001 01010000",
+      NULL),
+    "00000000 00111111 01010000 00000000 00000000 00000000 00000000 00000000",
+    26,
+    0, -1,
+    GRN_CURSOR_SIZE_BY_BIT);
+  ADD_DATA(
+    "bit - descending",
+    gcut_list_string_new(
+      "00000000 00111111 01010000 00111010 01011111 00000010 00101001 01010000",
+      "00000000 00111111 01010000 00111001 00111101 00001001 00001011 01010011",
+      "00000000 00111111 01010000 00111000 01100100 01101011 01111100 01111011",
+      "00000000 00111111 01010000 00110000 01001010 01011100 01101010 00010001",
+      "00000000 00111111 01010000 00101111 01001010 01101000 01000100 01100011",
+      "00000000 00111111 01010000 00101111 00011000 01000110 00100101 01011110",
+      "00000000 00111111 01010000 00101110 01110010 00111001 00011011 01101010",
+      "00000000 00111111 01010000 00101110 01010011 00101001 00101001 00100011",
+      "00000000 00111111 01010000 00101101 01111100 01101100 00111000 01111001",
+      "00000000 00111111 01010000 00101101 00101000 00111111 01010110 00010110",
+      "00000000 00111111 01010000 00100011 01100100 01011000 00000111 01110010",
+      "00000000 00111111 01010000 00100011 00001010 00000000 00001101 00111010",
+      "00000000 00111111 01010000 00100011 00000001 00000111 01011100 01110011",
+      "00000000 00111111 01010000 00100010 00111011 01000000 00111000 01100100",
+      "00000000 00111111 01010000 00100010 00100111 01000011 00000010 01101001",
+      "00000000 00111111 01010000 00100000 00010111 01000111 00110100 00101010",
+      "00000000 00111111 01010000 00011000 01110000 00001011 00101110 01001010",
+      "00000000 00111111 01010000 00010010 00110001 00110111 01111000 01110000",
+      "00000000 00111111 01010000 00010010 00110001 00001000 00001010 00110011",
+      "00000000 00111111 01010000 00001111 00101011 00011111 00110011 00001001",
+      "00000000 00111111 01010000 00001101 01011101 01011011 01011001 01010011",
+      "00000000 00111111 01010000 00000001 00011110 01010001 01101001 00110000",
+      "00000000 00111111 01010000 00000000 01111101 00010000 00011101 00001111",
+      NULL),
+    "00000000 00111111 01010000 00000000 00000000 00000000 00000000 00000000",
+    26,
+    0, -1,
+    GRN_CURSOR_SIZE_BY_BIT | GRN_CURSOR_DESCENDING);
+
+#undef ADD_DATA
+}
+
+void
+test_prefix_geo_point(gpointer data)
+{
+  grn_id id;
+  grn_obj min, min_string;
+  int offset, limit, flags;
+  unsigned min_size;
+  const GList *expected_keys;
+  GList *actual_keys = NULL;
+
+  create_geo_point_table(
+    geo_byte_load_data(
+      "00000000 00111111 01010000 00110000 01001010 01011100 01101010 00010001",
+      "00000000 00111111 01010000 00001101 01011101 01011011 01011001 01010011",
+      "00000000 00111111 01010000 00000001 00011110 01010001 01101001 00110000",
+      "00000000 00111111 01010000 00011000 01110000 00001011 00101110 01001010",
+      "00000000 00111111 01010000 00010010 00110001 00110111 01111000 01110000",
+      "00000000 00111111 01010000 00010010 00110001 00001000 00001010 00110011",
+      "00000000 00111111 01010000 00101110 01110010 00111001 00011011 01101010",
+      "00000000 00111111 01010000 00101101 00101000 00111111 01010110 00010110",
+      "00000000 00111111 01010000 00101111 01001010 01101000 01000100 01100011",
+      "00000000 00111111 01010000 00101111 00011000 01000110 00100101 01011110",
+      "00000000 00111111 01000101 01011001 01010110 00000111 00110100 01111111",
+      "00000000 00111111 01000101 01010010 01100101 01100110 00010111 01111110",
+      "00000000 00111111 01000101 01111111 01011011 01111101 00001001 01100001",
+      "00000000 00111111 01010000 00100011 00001010 00000000 00001101 00111010",
+      "00000000 00111111 01010000 00101110 01010011 00101001 00101001 00100011",
+      "00000000 00111111 01010000 00111010 01011111 00000010 00101001 01010000",
+      "00000000 00111111 01010000 00111001 00111101 00001001 00001011 01010011",
+      "00000000 00111111 01000101 01011100 00001100 01000001 01011010 00010011",
+      "00000000 00111111 01010000 00100011 00000001 00000111 01011100 01110011",
+      "00000000 00111111 01010000 00100011 01100100 01011000 00000111 01110010",
+      "00000000 00111111 01010000 00111000 01100100 01101011 01111100 01111011",
+      "00000000 00111111 01010000 00001111 00101011 00011111 00110011 00001001",
+      "00000000 00111111 01000101 01111011 01001011 01101011 00001001 00000001",
+      "00000000 00111111 01000101 01011010 00110100 00000010 01111010 00000000",
+      "00000000 00111111 01000101 01011011 00011010 00010111 00011000 00100000",
+      "00000000 00111111 01010000 00100000 00010111 01000111 00110100 00101010",
+      "00000000 00111111 01010000 00000000 01111101 00010000 00011101 00001111",
+      "00000000 00111111 01000101 01000100 01010010 00100100 01100011 00111011",
+      "00000000 00111111 01000101 01010001 00011100 01010110 00100110 00000110",
+      "00000000 00111111 01010000 00101101 01111100 01101100 00111000 01111001",
+      "00000000 00111111 01000101 01001101 00111110 00000101 00101010 01000101",
+      "00000000 00111111 01000101 01000100 01111100 01101011 01101111 00010101",
+      "00000000 00111111 01000101 01110111 01010100 01110100 01111000 01111000",
+      "00000000 00111111 01010000 00100010 00111011 01000000 00111000 01100100",
+      "00000000 00111111 01010000 00100010 00100111 01000011 00000010 01101001",
+      "00000000 00111111 01000101 01011100 00110110 00100010 00111000 01100001",
+      NULL));
+
+  GRN_TEXT_INIT(&min_string, 0);
+  GRN_TEXT_PUTS(context, &min_string,
+                geo_byte_parse(gcut_data_get_string(data, "min")));
+  GRN_WGS84_GEO_POINT_INIT(&min, 0);
+  grn_obj_cast(context, &min_string, &min, FALSE);
+  grn_obj_unlink(context, &min_string);
+
+  min_size = gcut_data_get_uint(data, "min-size");
+  offset = gcut_data_get_int(data, "offset");
+  limit = gcut_data_get_int(data, "limit");
+  flags = gcut_data_get_int(data, "flags");
+  cursor = grn_table_cursor_open(context, table,
+                                 GRN_BULK_HEAD(&min), min_size,
+                                 NULL, 0,
+                                 offset, limit,
+                                 flags | GRN_CURSOR_PREFIX);
+  grn_obj_unlink(context, &min);
+  grn_test_assert_context(context);
+  while ((id = grn_table_cursor_next(context, cursor))) {
+    grn_geo_point *key;
+    int i, j, key_size;
+    uint8_t encoded_key[sizeof(grn_geo_point)];
+    GString *geo_byte;
+
+    key_size = grn_table_cursor_get_key(context, cursor, (void **)&key);
+    grn_gton(encoded_key, key, key_size);
+    geo_byte = g_string_new(NULL);
+    for (i = 0; i < sizeof(grn_geo_point); i++) {
+      if (i != 0) {
+        g_string_append(geo_byte, " ");
+      }
+      for (j = 0; j < 8; j++) {
+        g_string_append_printf(geo_byte, "%d", (encoded_key[i] >> (7 - j)) & 1);
+      }
+    }
+    actual_keys = g_list_append(actual_keys, g_string_free(geo_byte, FALSE));
+  }
+  gcut_take_list(actual_keys, g_free);
+
+  expected_keys = gcut_data_get_pointer(data, "expected");
+  gcut_assert_equal_list_string(expected_keys, actual_keys);
+}
+
 static GList *
 uint_list_new(gint n, guint value, ...)
 {
@@ -468,7 +730,34 @@ test_near_geo_point(gpointer data)
   const GList *expected_keys;
   GList *actual_keys = NULL;
 
-  create_geo_point_table();
+  create_geo_point_table(
+    cut_take_printf(" [\"%s\"],"
+                    " [\"%s\"],"
+                    " [\"%s\"],"
+                    " [\"%s\"],"
+                    " [\"%s\"],"
+                    " [\"%s\"],"
+                    " [\"%s\"],"
+                    " [\"%s\"],"
+                    " [\"%s\"]",
+                    TAKEN_POINT(1, 2, 3,
+                                4, 5, 6),
+                    TAKEN_POINT(1, 2, 3,
+                                7, 8, 9),
+                    TAKEN_POINT(7, 8, 9,
+                                4, 5, 6),
+                    TAKEN_POINT(89, 59, 59,
+                                179, 59, 59),
+                    TAKEN_POINT(89, 59, 59,
+                                179, -59, -59),
+                    TAKEN_POINT(88, 58, 58,
+                                178, 58, 58),
+                    TAKEN_POINT(-89, -59, -59,
+                                -179, -59, -59),
+                    TAKEN_POINT(-89, -59, -59,
+                                179, 59, 59),
+                    TAKEN_POINT(-88, -58, -58,
+                                -178, -58, -58)));
 
   min_size = gcut_data_get_int(data, "min-size");
   GRN_TEXT_INIT(&max_string, 0);




Groonga-commit メーリングリストの案内
アーカイブの一覧に戻る