null+****@clear*****
null+****@clear*****
2011年 11月 17日 (木) 13:57:02 JST
Susumu Yata 2011-11-17 04:57:02 +0000 (Thu, 17 Nov 2011) New Revision: 7c39417112896c81ef64eb371911cf52be40cc6f Log: added a test that compares grn_pat and grn_dat. Added files: test/unit/core/dat/test-dat-pat.cpp Modified files: test/unit/core/dat/Makefile.am test/unit/core/dat/test-trie.cpp Modified: test/unit/core/dat/Makefile.am (+2 -0) =================================================================== --- test/unit/core/dat/Makefile.am 2011-11-17 03:59:43 +0000 (eb12a5c) +++ test/unit/core/dat/Makefile.am 2011-11-17 04:57:02 +0000 (71bf899) @@ -11,6 +11,7 @@ noinst_LTLIBRARIES = \ test-id-cursor.la \ test-dat.la \ test-dat-cursor.la \ + test-dat-pat.la \ test-key-cursor.la \ test-key.la \ test-node.la \ @@ -51,6 +52,7 @@ test_check_la_SOURCES = test-check.cpp test_cursor_factory_la_SOURCES = test-cursor-factory.cpp test_dat_la_SOURCES = test-dat.cpp test_dat_cursor_la_SOURCES = test-dat-cursor.cpp +test_dat_pat_la_SOURCES = test-dat-pat.cpp test_entry_la_SOURCES = test-entry.cpp test_file_la_SOURCES = test-file.cpp test_header_la_SOURCES = test-header.cpp Added: test/unit/core/dat/test-dat-pat.cpp (+390 -0) 100644 =================================================================== --- /dev/null +++ test/unit/core/dat/test-dat-pat.cpp 2011-11-17 04:57:02 +0000 (9e6300e) @@ -0,0 +1,390 @@ +/* -*- c-basic-offset: 2; coding: utf-8 -*- */ +/* + Copyright (C) 2011 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#define __STDC_LIMIT_MACROS + +#include <gcutter.h> +#include <glib/gstdio.h> +#include <cppcutter.h> + +#include <grn-assertions.h> + +#include <algorithm> +#include <cstdio> +#include <cstdlib> +#include <ctime> +#include <set> +#include <string> +#include <vector> + +namespace +{ + void create_key(std::string *key, std::size_t min_length, std::size_t max_length) + { + key->resize(min_length + (std::rand() % (max_length - min_length + 1))); + for (std::size_t i = 0; i < key->size(); ++i) { + (*key)[i] = '0' + (std::rand() % 10); + } + } + + void create_keys(std::vector<std::string> *keys, std::size_t num_keys, + std::size_t min_length, std::size_t max_length) + { + std::string key; + std::set<std::string> keyset; + while (keyset.size() < num_keys) { + create_key(&key, min_length, max_length); + keyset.insert(key); + } + std::vector<std::string>(keyset.begin(), keyset.end()).swap(*keys); + std::random_shuffle(keys->begin(), keys->end()); + } +} + +namespace test_dat_pat +{ + const gchar *base_dir = NULL; + grn_ctx ctx; + + void cut_setup(void) + { + std::srand(static_cast<unsigned int>(std::time(NULL))); + + base_dir = grn_test_get_tmp_dir(); + cut_remove_path(base_dir, NULL); + g_mkdir_with_parents(base_dir, 0755); + + grn_ctx_init(&ctx, 0); + } + + void cut_teardown(void) + { + grn_ctx_fin(&ctx); + + if (base_dir) { + cut_remove_path(base_dir, NULL); + } + } + + grn_pat *create_pat(const char *filename, const std::vector<std::string> &keys) + { + char pat_path[PATH_MAX]; + std::sprintf(pat_path, "%s/%s.pat", base_dir, filename); + grn_pat * const pat = grn_pat_create(&ctx, NULL, 1024, 0, GRN_OBJ_KEY_VAR_SIZE); + cut_assert_not_null(pat); + + for (std::size_t i = 0; i < keys.size(); ++i) { + grn_pat_add(&ctx, pat, keys[i].c_str(), keys[i].length(), NULL, NULL); + } + return pat; + } + + grn_dat *create_dat(const char *filename, const std::vector<std::string> &keys) + { + char dat_path[PATH_MAX]; + std::sprintf(dat_path, "%s/%s.dat", base_dir, filename); + grn_dat * const dat = grn_dat_create(&ctx, NULL, 1024, 0, GRN_OBJ_KEY_VAR_SIZE); + cut_assert_not_null(dat); + + for (std::size_t i = 0; i < keys.size(); ++i) { + grn_dat_add(&ctx, dat, keys[i].c_str(), keys[i].length(), NULL, NULL); + } + return dat; + } + + void test_get(void) + { + const char * const filename = "test_get"; + + std::vector<std::string> keys; + create_keys(&keys, 1000, 3, 5); + grn_pat * const pat = create_pat(filename, keys); + grn_dat * const dat = create_dat(filename, keys); + + std::string key; + for (int i = 0; i < 1000; ++i) { + create_key(&key, 3, 5); + + const grn_id pat_id = grn_pat_get(&ctx, pat, key.c_str(), key.length(), NULL); + const grn_id dat_id = grn_dat_get(&ctx, dat, key.c_str(), key.length(), NULL); + cppcut_assert_equal(pat_id, dat_id); + if (pat_id != GRN_ID_NIL) { + char pat_key[1024]; + int pat_length = grn_pat_get_key(&ctx, pat, pat_id, pat_key, sizeof(pat_key)); + char dat_key[1024]; + int dat_length = grn_dat_get_key(&ctx, dat, dat_id, dat_key, sizeof(dat_key)); + cut_assert_equal_memory(pat_key, pat_length, dat_key, dat_length); + } + } + + cppcut_assert_equal(GRN_SUCCESS, grn_pat_close(&ctx, pat)); + cppcut_assert_equal(GRN_SUCCESS, grn_dat_close(&ctx, dat)); + } + + void test_add(void) + { + const char * const filename = "test_add"; + + std::vector<std::string> keys; + create_keys(&keys, 1000, 3, 5); + grn_pat * const pat = create_pat(filename, keys); + grn_dat * const dat = create_dat(filename, keys); + + std::string key; + for (int i = 0; i < 1000; ++i) { + create_key(&key, 3, 5); + int pat_added = -1; + const grn_id pat_id = grn_pat_add(&ctx, pat, key.c_str(), + key.length(), NULL, &pat_added); + int dat_added = -2; + const grn_id dat_id = grn_dat_add(&ctx, dat, key.c_str(), + key.length(), NULL, &dat_added); + cppcut_assert_equal(pat_id, dat_id); + cppcut_assert_equal(pat_added, dat_added); + } + + cppcut_assert_equal(GRN_SUCCESS, grn_pat_close(&ctx, pat)); + cppcut_assert_equal(GRN_SUCCESS, grn_dat_close(&ctx, dat)); + } + + void test_id_cursor(void) + { + const char * const filename = "test_id_cursor"; + + std::vector<std::string> keys; + create_keys(&keys, 1000, 3, 5); + grn_pat * const pat = create_pat(filename, keys); + grn_dat * const dat = create_dat(filename, keys); + + std::string key; + for (int i = 0; i < 1000; ++i) { + grn_id min_id = static_cast<grn_id>(std::rand() % (keys.size() + 1)); + grn_id max_id = static_cast<grn_id>(std::rand() % (keys.size() + 1)); + if (!min_id) { + min_id = GRN_ID_NIL; + } + if (!max_id) { + max_id = GRN_ID_NIL; + } + if ((min_id != GRN_ID_NIL) && (max_id != GRN_ID_NIL) && + (min_id > max_id)) { + std::swap(min_id, max_id); + } + + const char * const min_key = + (min_id != GRN_ID_NIL) ? keys[min_id - 1].c_str() : NULL; + const int min_length = min_key ? static_cast<int>(keys[min_id - 1].length()) : 0; + const char * const max_key = + (max_id != GRN_ID_NIL) ? keys[max_id - 1].c_str() : NULL; + const int max_length = max_key ? static_cast<int>(keys[max_id - 1].length()) : 0; + + const int temp = std::rand(); + const int offset = temp & 0x0F; + const int limit = ((temp & 0xF0) == 0xF0) ? -1 : ((temp & 0xF0) >> 4); + const int flags = GRN_CURSOR_BY_ID | + (((temp & 0x100) == 0x100) ? GRN_CURSOR_LT : GRN_CURSOR_LE) | + (((temp & 0x200) == 0x200) ? GRN_CURSOR_GT : GRN_CURSOR_GE) | + (((temp & 0x400) == 0x400) ? + GRN_CURSOR_DESCENDING : GRN_CURSOR_ASCENDING); + + grn_pat_cursor * const pat_cursor = + grn_pat_cursor_open(&ctx, pat, min_key, min_length, max_key, max_length, + offset, limit, flags); + cut_assert_not_null(pat_cursor); + + grn_dat_cursor * const dat_cursor = + grn_dat_cursor_open(&ctx, dat, min_key, min_length, max_key, max_length, + offset, limit, flags); + cut_assert_not_null(dat_cursor); + + grn_id pat_id; + grn_id dat_id; + do { + pat_id = grn_pat_cursor_next(&ctx, pat_cursor); + dat_id = grn_dat_cursor_next(&ctx, dat_cursor); + cppcut_assert_equal(pat_id, dat_id); + } while (pat_id != GRN_ID_NIL); + + grn_pat_cursor_close(&ctx, pat_cursor); + grn_dat_cursor_close(&ctx, dat_cursor); + } + + cppcut_assert_equal(GRN_SUCCESS, grn_pat_close(&ctx, pat)); + cppcut_assert_equal(GRN_SUCCESS, grn_dat_close(&ctx, dat)); + } + + void test_key_cursor(void) + { + const char * const filename = "test_key_cursor"; + + std::vector<std::string> keys; + create_keys(&keys, 1000, 3, 5); + grn_pat * const pat = create_pat(filename, keys); + grn_dat * const dat = create_dat(filename, keys); + + std::string min_str; + std::string max_str; + for (int i = 0; i < 1000; ++i) { + create_key(&min_str, 3, 5); + create_key(&max_str, 3, 5); + if (min_str > max_str) { + min_str.swap(max_str); + } + + const int temp = std::rand(); + const int offset = temp & 0x0F; + const int limit = ((temp & 0xF0) == 0xF0) ? -1 : ((temp & 0xF0) >> 4); + const int flags = GRN_CURSOR_BY_KEY | + (((temp & 0x100) == 0x100) ? GRN_CURSOR_LT : GRN_CURSOR_LE) | + (((temp & 0x200) == 0x200) ? GRN_CURSOR_GT : GRN_CURSOR_GE) | + (((temp & 0x400) == 0x400) ? + GRN_CURSOR_DESCENDING : GRN_CURSOR_ASCENDING); + + const bool disables_min = !(rand() % 32); + const bool disables_max = !(rand() % 32); + + grn_pat_cursor * const pat_cursor = + grn_pat_cursor_open(&ctx, pat, disables_min ? NULL : min_str.c_str(), + disables_min ? 0 : min_str.length(), + disables_max ? NULL : max_str.c_str(), + disables_max ? 0 : max_str.length(), + offset, limit, flags); + cut_assert_not_null(pat_cursor); + + grn_dat_cursor * const dat_cursor = + grn_dat_cursor_open(&ctx, dat, disables_min ? NULL : min_str.c_str(), + disables_min ? 0 : min_str.length(), + disables_max ? NULL : max_str.c_str(), + disables_max ? 0 : max_str.length(), + offset, limit, flags); + cut_assert_not_null(dat_cursor); + + grn_id pat_id; + grn_id dat_id; + do { + pat_id = grn_pat_cursor_next(&ctx, pat_cursor); + dat_id = grn_dat_cursor_next(&ctx, dat_cursor); + cppcut_assert_equal(pat_id, dat_id); + } while (pat_id != GRN_ID_NIL); + + grn_pat_cursor_close(&ctx, pat_cursor); + grn_dat_cursor_close(&ctx, dat_cursor); + } + + cppcut_assert_equal(GRN_SUCCESS, grn_pat_close(&ctx, pat)); + cppcut_assert_equal(GRN_SUCCESS, grn_dat_close(&ctx, dat)); + } + + void test_prefix_cursor(void) + { + const char * const filename = "test_prefix_cursor"; + + std::vector<std::string> keys; + create_keys(&keys, 1000, 3, 5); + grn_pat * const pat = create_pat(filename, keys); + grn_dat * const dat = create_dat(filename, keys); + + std::string max_str; + for (int i = 0; i < 1000; ++i) { + create_key(&max_str, 3, 5); + + const int temp = std::rand(); + const int offset = temp & 0x03; + const int limit = ((temp & 0xF0) == 0xF0) ? -1 : ((temp & 0xF0) >> 4); + const int flags = GRN_CURSOR_PREFIX | + (((temp & 0x100) == 0x100) ? GRN_CURSOR_LT : GRN_CURSOR_LE) | + (((temp & 0x200) == 0x200) ? GRN_CURSOR_GT : GRN_CURSOR_GE) | + (((temp & 0x400) == 0x400) ? + GRN_CURSOR_DESCENDING : GRN_CURSOR_ASCENDING); + + const int min_length = std::rand() % (max_str.length() + 1); + + grn_pat_cursor * const pat_cursor = + grn_pat_cursor_open(&ctx, pat, NULL, min_length, max_str.c_str(), + max_str.length(), offset, limit, flags); + cut_assert_not_null(pat_cursor); + + grn_dat_cursor * const dat_cursor = + grn_dat_cursor_open(&ctx, dat, NULL, min_length, max_str.c_str(), + max_str.length(), offset, limit, flags); + cut_assert_not_null(dat_cursor); + + grn_id pat_id; + grn_id dat_id; + do { + pat_id = grn_pat_cursor_next(&ctx, pat_cursor); + dat_id = grn_dat_cursor_next(&ctx, dat_cursor); + cppcut_assert_equal(pat_id, dat_id); + } while (pat_id != GRN_ID_NIL); + + grn_pat_cursor_close(&ctx, pat_cursor); + grn_dat_cursor_close(&ctx, dat_cursor); + } + + cppcut_assert_equal(GRN_SUCCESS, grn_pat_close(&ctx, pat)); + cppcut_assert_equal(GRN_SUCCESS, grn_dat_close(&ctx, dat)); + } + + void test_predictive_cursor(void) + { + const char * const filename = "test_predictive_cursor"; + + std::vector<std::string> keys; + create_keys(&keys, 1000, 3, 5); + grn_pat * const pat = create_pat(filename, keys); + grn_dat * const dat = create_dat(filename, keys); + + std::string min_str; + for (int i = 0; i < 1000; ++i) { + create_key(&min_str, 3, 5); + + const int temp = std::rand(); + const int offset = temp & 0x0F; + const int limit = ((temp & 0xF0) == 0xF0) ? -1 : ((temp & 0xF0) >> 4); + const int flags = GRN_CURSOR_PREFIX | + (((temp & 0x100) == 0x100) ? GRN_CURSOR_LT : GRN_CURSOR_LE) | + (((temp & 0x200) == 0x200) ? GRN_CURSOR_GT : GRN_CURSOR_GE) | + (((temp & 0x400) == 0x400) ? + GRN_CURSOR_DESCENDING : GRN_CURSOR_ASCENDING); + + grn_pat_cursor * const pat_cursor = + grn_pat_cursor_open(&ctx, pat, min_str.c_str(), min_str.length(), + NULL, 0, offset, limit, flags); + cut_assert_not_null(pat_cursor); + + grn_dat_cursor *dat_cursor = + grn_dat_cursor_open(&ctx, dat, min_str.c_str(), min_str.length(), + NULL, 0, offset, limit, flags); + cut_assert_not_null(dat_cursor); + + grn_id pat_id; + grn_id dat_id; + do { + pat_id = grn_pat_cursor_next(&ctx, pat_cursor); + dat_id = grn_dat_cursor_next(&ctx, dat_cursor); + cppcut_assert_equal(pat_id, dat_id); + } while (pat_id != GRN_ID_NIL); + + grn_pat_cursor_close(&ctx, pat_cursor); + grn_dat_cursor_close(&ctx, dat_cursor); + } + + cppcut_assert_equal(GRN_SUCCESS, grn_pat_close(&ctx, pat)); + cppcut_assert_equal(GRN_SUCCESS, grn_dat_close(&ctx, dat)); + } +} Modified: test/unit/core/dat/test-trie.cpp (+1 -0) =================================================================== --- test/unit/core/dat/test-trie.cpp 2011-11-17 03:59:43 +0000 (071e834) +++ test/unit/core/dat/test-trie.cpp 2011-11-17 04:57:02 +0000 (509a570) @@ -103,6 +103,7 @@ namespace test_dat_trie void cut_setup(void) { std::srand(static_cast<unsigned int>(std::time(NULL))); + base_dir = grn_test_get_tmp_dir(); cut_remove_path(base_dir, NULL); g_mkdir_with_parents(base_dir, 0755);