susumu.yata
null+****@clear*****
Tue Dec 16 10:46:34 JST 2014
susumu.yata 2014-11-28 16:00:19 +0900 (Fri, 28 Nov 2014) New Revision: c6863bd0e2871c1c5b98dc5201199fb27dd4f223 https://github.com/groonga/grnxx/commit/c6863bd0e2871c1c5b98dc5201199fb27dd4f223 Message: Enable tests for Index. (#121) Modified files: test/Makefile.am test/test_index.cpp Modified: test/Makefile.am (+3 -4) =================================================================== --- test/Makefile.am 2014-11-28 15:59:44 +0900 (9694e48) +++ test/Makefile.am 2014-11-28 16:00:19 +0900 (94ce4bb) @@ -5,14 +5,13 @@ TESTS = \ test_db \ test_table \ test_column \ + test_index \ test_expression \ test_sorter \ test_merger \ test_pipeline \ test_issue_62 -# test_index - check_PROGRAMS = $(TESTS) test_string_SOURCES = test_string.cpp @@ -33,8 +32,8 @@ test_table_LDADD = $(top_srcdir)/lib/grnxx/libgrnxx.la test_column_SOURCES = test_column.cpp test_column_LDADD = $(top_srcdir)/lib/grnxx/libgrnxx.la -#test_index_SOURCES = test_index.cpp -#test_index_LDADD = $(top_srcdir)/lib/grnxx/libgrnxx.la +test_index_SOURCES = test_index.cpp +test_index_LDADD = $(top_srcdir)/lib/grnxx/libgrnxx.la test_expression_SOURCES = test_expression.cpp test_expression_LDADD = $(top_srcdir)/lib/grnxx/libgrnxx.la Modified: test/test_index.cpp (+863 -796) =================================================================== --- test/test_index.cpp 2014-11-28 15:59:44 +0900 (3049942) +++ test/test_index.cpp 2014-11-28 16:00:19 +0900 (81bd758) @@ -28,308 +28,319 @@ std::mt19937_64 mersenne_twister; void test_index() { - grnxx::Error error; - // Create a database with the default options. - auto db = grnxx::open_db(&error, ""); - assert(db); + auto db = grnxx::open_db(""); // Create a table with the default options. - auto table = db->create_table(&error, "Table"); - assert(table); + auto table = db->create_table("Table"); // Append the first row. - grnxx::Int row_id; - assert(table->insert_row(&error, grnxx::NULL_ROW_ID, - grnxx::Datum(), &row_id)); + grnxx::Int row_id = table->insert_row(); // Create a column named "Column". - auto column = table->create_column(&error, "Column", grnxx::INT_DATA); - assert(column); + auto column = table->create_column("Column", grnxx::INT_DATA); // Create an index named "Index". - auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); - assert(index); + auto index = column->create_index("Index", grnxx::TREE_INDEX); assert(index->column() == column); assert(index->name() == "Index"); assert(index->type() == grnxx::TREE_INDEX); } void test_set_and_index() { - constexpr grnxx::Int NUM_ROWS = 1 << 16; - - grnxx::Error error; + constexpr size_t NUM_ROWS = 1 << 16; // Create a database with the default options. - auto db = grnxx::open_db(&error, ""); - assert(db); + auto db = grnxx::open_db(""); // Create a table with the default options. - auto table = db->create_table(&error, "Table"); - assert(table); + auto table = db->create_table("Table"); // Create a column. - auto column = table->create_column(&error, "Int", grnxx::INT_DATA); - assert(column); + auto column = table->create_column("Int", grnxx::INT_DATA); // Generate random values. - // Int: [0, 100). + // Int: [0, 100) or N/A. grnxx::Array<grnxx::Int> values; - assert(values.resize(&error, NUM_ROWS + 1)); - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - values.set(i, mersenne_twister() % 100); + values.resize(NUM_ROWS); + size_t total_count = 0; + for (size_t i = 0; i < NUM_ROWS; ++i) { + if ((mersenne_twister() % 128) != 0) { + values[i] = grnxx::Int(mersenne_twister() % 100); + ++total_count; + } else { + values[i] = grnxx::Int::na(); + } } // Store generated values into columns. - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - grnxx::Int row_id; - assert(table->insert_row(&error, grnxx::NULL_ROW_ID, - grnxx::Datum(), &row_id)); - assert(row_id == i); - assert(column->set(&error, row_id, values[i])); + for (size_t i = 0; i < NUM_ROWS; ++i) { + grnxx::Int row_id = table->insert_row(); + assert(row_id.match(grnxx::Int(i))); + column->set(row_id, values[i]); } // Create an index. - auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); - assert(index); - - // Create a cursor. - auto cursor = index->find_in_range(&error); - assert(cursor); - - grnxx::Array<grnxx::Record> records; - auto result = cursor->read_all(&error, &records); - assert(result.is_ok); - assert(result.count == NUM_ROWS); - for (grnxx::Int i = 1; i < NUM_ROWS; ++i) { - assert(values[records.get_row_id(i - 1)] <= values[records.get_row_id(i)]); - } + auto index = column->create_index("Index", grnxx::TREE_INDEX); + +// // Create a cursor. +// auto cursor = index->find_in_range(); + +// grnxx::Array<grnxx::Record> records; +// size_t count = cursor->read_all(&records); +// assert(count == total_count); +// for (size_t i = 1; i < NUM_ROWS; ++i) { +// size_t lhs_row_id = records[i - 1].row_id.raw(); +// size_t rhs_row_id = records[i].row_id.raw(); +// grnxx::Int lhs_value = values[lhs_row_id]; +// grnxx::Int rhs_value = values[rhs_row_id]; +// assert(!lhs_value.is_na()); +// assert(!rhs_value.is_na()); +// assert(lhs_value.raw() <= rhs_value.raw()); +// if (lhs_value.match(rhs_value)) { +// assert(lhs_row_id < rhs_row_id); +// } +// } } void test_index_and_set() { - constexpr grnxx::Int NUM_ROWS = 1 << 16; - - grnxx::Error error; + constexpr size_t NUM_ROWS = 1 << 16; // Create a database with the default options. - auto db = grnxx::open_db(&error, ""); - assert(db); + auto db = grnxx::open_db(""); // Create a table with the default options. - auto table = db->create_table(&error, "Table"); - assert(table); + auto table = db->create_table("Table"); // Create a column. - auto column = table->create_column(&error, "Int", grnxx::INT_DATA); - assert(column); + auto column = table->create_column("Int", grnxx::INT_DATA); // Create an index. - auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); - assert(index); + auto index = column->create_index("Index", grnxx::TREE_INDEX); // Generate random values. - // Int: [0, 100). + // Int: [0, 100) or N/A. grnxx::Array<grnxx::Int> values; - assert(values.resize(&error, NUM_ROWS + 1)); - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - values.set(i, mersenne_twister() % 100); + values.resize(NUM_ROWS); + size_t total_count = 0; + for (size_t i = 0; i < NUM_ROWS; ++i) { + if ((mersenne_twister() % 128) != 0) { + values[i] = grnxx::Int(mersenne_twister() % 100); + ++total_count; + } else { + values[i] = grnxx::Int::na(); + } } // Store generated values into columns. - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - grnxx::Int row_id; - assert(table->insert_row(&error, grnxx::NULL_ROW_ID, - grnxx::Datum(), &row_id)); - assert(row_id == i); - assert(column->set(&error, row_id, values[i])); + for (size_t i = 0; i < NUM_ROWS; ++i) { + grnxx::Int row_id = table->insert_row(); + assert(row_id.match(grnxx::Int(i))); + column->set(row_id, values[i]); } - // Create a cursor. - auto cursor = index->find_in_range(&error); - assert(cursor); - - grnxx::Array<grnxx::Record> records; - auto result = cursor->read_all(&error, &records); - assert(result.is_ok); - assert(result.count == NUM_ROWS); - for (grnxx::Int i = 1; i < NUM_ROWS; ++i) { - assert(values[records.get_row_id(i - 1)] <= values[records.get_row_id(i)]); - } +// // Create a cursor. +// auto cursor = index->find_in_range(); + +// grnxx::Array<grnxx::Record> records; +// size_t count = cursor->read_all(&records); +// assert(count == NUM_ROWS); +// for (size_t i = 1; i < NUM_ROWS; ++i) { +// size_t lhs_row_id = records[i - 1].row_id.raw(); +// size_t rhs_row_id = records[i].row_id.raw(); +// grnxx::Int lhs_value = values[lhs_row_id]; +// grnxx::Int rhs_value = values[rhs_row_id]; +// assert(!lhs_value.is_na()); +// assert(!rhs_value.is_na()); +// assert(lhs_value.raw() <= rhs_value.raw()); +// if (lhs_value.match(rhs_value)) { +// assert(lhs_row_id < rhs_row_id); +// } +// } } void test_remove() { - constexpr grnxx::Int NUM_ROWS = 1 << 16; - - grnxx::Error error; + constexpr size_t NUM_ROWS = 1 << 16; // Create a database with the default options. - auto db = grnxx::open_db(&error, ""); - assert(db); + auto db = grnxx::open_db(""); // Create a table with the default options. - auto table = db->create_table(&error, "Table"); - assert(table); + auto table = db->create_table("Table"); // Create a column. - auto column = table->create_column(&error, "Int", grnxx::INT_DATA); - assert(column); + auto column = table->create_column("Int", grnxx::INT_DATA); // Generate random values. - // Int: [0, 100). + // Int: [0, 100) or N/A. grnxx::Array<grnxx::Int> values; - assert(values.resize(&error, NUM_ROWS + 1)); - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - values.set(i, mersenne_twister() % 100); + values.resize(NUM_ROWS); + size_t total_count = 0; + for (size_t i = 0; i < NUM_ROWS; ++i) { + if ((mersenne_twister() % 128) != 0) { + values[i] = grnxx::Int(mersenne_twister() % 100); + ++total_count; + } else { + values[i] = grnxx::Int::na(); + } } // Store generated values into columns. - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - grnxx::Int row_id; - assert(table->insert_row(&error, grnxx::NULL_ROW_ID, - grnxx::Datum(), &row_id)); - assert(row_id == i); - assert(column->set(&error, row_id, values[i])); + for (size_t i = 0; i < NUM_ROWS; ++i) { + grnxx::Int row_id = table->insert_row(); + assert(row_id.match(grnxx::Int(i))); + column->set(row_id, values[i]); } // Create an index. - auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); - assert(index); - - // Remove odd rows. - for (grnxx::Int i = 1; i <= NUM_ROWS; i += 2) { - assert(table->remove_row(&error, i)); - assert(!table->test_row(&error, i)); + auto index = column->create_index("Index", grnxx::TREE_INDEX); + + // Remove even rows. + size_t odd_count = total_count; + for (size_t i = 0; i < NUM_ROWS; i += 2) { + grnxx::Int row_id(i); + grnxx::Datum datum; + column->get(row_id, &datum); + if (datum.as_int().is_na()) { + --odd_count; + } + table->remove_row(row_id); + assert(!table->test_row(row_id)); } // Create a cursor. - auto cursor = index->find_in_range(&error); - assert(cursor); - - grnxx::Array<grnxx::Record> records; - auto result = cursor->read_all(&error, &records); - assert(result.is_ok); - assert(result.count == NUM_ROWS / 2); - for (grnxx::Int i = 1; i < (NUM_ROWS / 2); ++i) { - assert(values[records.get_row_id(i - 1)] <= values[records.get_row_id(i)]); - } +// auto cursor = index->find_in_range(); + +// grnxx::Array<grnxx::Record> records; +// size_t count = cursor->read_all(&records); +// assert(count == odd_count); +// for (size_t i = 0; i < count; ++i) { +// size_t lhs_row_id = records[i - 1].row_id.raw(); +// size_t rhs_row_id = records[i].row_id.raw(); +// grnxx::Int lhs_value = values[lhs_row_id]; +// grnxx::Int rhs_value = values[rhs_row_id]; +// assert(!lhs_value.is_na()); +// assert(!rhs_value.is_na()); +// assert(lhs_value.raw() <= rhs_value.raw()); +// if (lhs_value.match(rhs_value)) { +// assert(lhs_row_id < rhs_row_id); +// } +// } } -void test_bool_exact_match() { - constexpr grnxx::Int NUM_ROWS = 1 << 16; - - grnxx::Error error; - - // Create a database with the default options. - auto db = grnxx::open_db(&error, ""); - assert(db); - - // Create a table with the default options. - auto table = db->create_table(&error, "Table"); - assert(table); - - // Create a column. - auto column = table->create_column(&error, "Bool", grnxx::BOOL_DATA); - assert(column); - - // Create an index. - auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); - assert(index); - - // Generate random values. - // Bool: [false, true]. - grnxx::Array<grnxx::Bool> values; - assert(values.resize(&error, NUM_ROWS + 1)); - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - values.set(i, (mersenne_twister() & 1) == 1); - } - - // Store generated values into columns. - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - grnxx::Int row_id; - assert(table->insert_row(&error, grnxx::NULL_ROW_ID, - grnxx::Datum(), &row_id)); - assert(row_id == i); - assert(column->set(&error, row_id, values[i])); - } - - // Test cursors for each value. - grnxx::Bool possible_values[2] = { false, true }; - for (int possible_value_id = 0; possible_value_id < 2; ++possible_value_id) { - grnxx::Bool value = possible_values[possible_value_id]; - - auto cursor = index->find(&error, value); - assert(cursor); - - grnxx::Array<grnxx::Record> records; - auto result = cursor->read_all(&error, &records); - assert(result.is_ok); - for (grnxx::Int i = 1; i < records.size(); ++i) { - assert(values[records.get_row_id(i)] == value); - } - - grnxx::Int count = 0; - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - if (values[i] == value) { - ++count; - } - } - assert(count == records.size()); - } -} +//void test_bool_exact_match() { +// constexpr grnxx::Int NUM_ROWS = 1 << 16; + +// grnxx::Error error; + +// // Create a database with the default options. +// auto db = grnxx::open_db(&error, ""); +// assert(db); + +// // Create a table with the default options. +// auto table = db->create_table(&error, "Table"); +// assert(table); + +// // Create a column. +// auto column = table->create_column(&error, "Bool", grnxx::BOOL_DATA); +// assert(column); + +// // Create an index. +// auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); +// assert(index); + +// // Generate random values. +// // Bool: [false, true]. +// grnxx::Array<grnxx::Bool> values; +// assert(values.resize(&error, NUM_ROWS + 1)); +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// values.set(i, (mersenne_twister() & 1) == 1); +// } + +// // Store generated values into columns. +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// grnxx::Int row_id; +// assert(table->insert_row(&error, grnxx::NULL_ROW_ID, +// grnxx::Datum(), &row_id)); +// assert(row_id == i); +// assert(column->set(&error, row_id, values[i])); +// } + +// // Test cursors for each value. +// grnxx::Bool possible_values[2] = { false, true }; +// for (int possible_value_id = 0; possible_value_id < 2; ++possible_value_id) { +// grnxx::Bool value = possible_values[possible_value_id]; + +// auto cursor = index->find(&error, value); +// assert(cursor); + +// grnxx::Array<grnxx::Record> records; +// auto result = cursor->read_all(&error, &records); +// assert(result.is_ok); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// assert(values[records.get_row_id(i)] == value); +// } + +// grnxx::Int count = 0; +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// if (values[i] == value) { +// ++count; +// } +// } +// assert(count == records.size()); +// } +//} void test_int_exact_match() { - constexpr grnxx::Int NUM_ROWS = 1 << 16; - - grnxx::Error error; + constexpr size_t NUM_ROWS = 1 << 16; // Create a database with the default options. - auto db = grnxx::open_db(&error, ""); - assert(db); + auto db = grnxx::open_db(""); // Create a table with the default options. - auto table = db->create_table(&error, "Table"); - assert(table); + auto table = db->create_table("Table"); // Create a column. - auto column = table->create_column(&error, "Int", grnxx::INT_DATA); - assert(column); + auto column = table->create_column("Int", grnxx::INT_DATA); // Create an index. - auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); - assert(index); + auto index = column->create_index("Index", grnxx::TREE_INDEX); // Generate random values. - // Int: [0, 100). + // Int: [0, 100) or N/A. grnxx::Array<grnxx::Int> values; - assert(values.resize(&error, NUM_ROWS + 1)); - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - values.set(i, mersenne_twister() % 100); + values.resize(NUM_ROWS); + size_t total_count = 0; + for (size_t i = 0; i < NUM_ROWS; ++i) { + if ((mersenne_twister() % 128) != 0) { + values[i] = grnxx::Int(mersenne_twister() % 100); + ++total_count; + } else { + values[i] = grnxx::Int::na(); + } } // Store generated values into columns. - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - grnxx::Int row_id; - assert(table->insert_row(&error, grnxx::NULL_ROW_ID, - grnxx::Datum(), &row_id)); - assert(row_id == i); - assert(column->set(&error, row_id, values[i])); + for (size_t i = 0; i < NUM_ROWS; ++i) { + grnxx::Int row_id = table->insert_row(); + assert(row_id.match(grnxx::Int(i))); + column->set(row_id, values[i]); } // Test cursors for each value. - for (grnxx::Int value = 0; value < 100; ++value) { - auto cursor = index->find(&error, value); - assert(cursor); + for (int raw = 0; raw < 100; ++raw) { + grnxx::Int value(raw); + auto cursor = index->find(value); grnxx::Array<grnxx::Record> records; - auto result = cursor->read_all(&error, &records); - assert(result.is_ok); - for (grnxx::Int i = 1; i < records.size(); ++i) { - assert(values[records.get_row_id(i)] == value); + size_t count = cursor->read_all(&records); + for (size_t i = 0; i < records.size(); ++i) { + assert(values[records[i].row_id.raw()].match(value)); } - grnxx::Int count = 0; - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - if (values[i] == value) { + count = 0; + for (size_t i = 0; i < NUM_ROWS; ++i) { + if (values[i].match(value)) { ++count; } } @@ -338,126 +349,55 @@ void test_int_exact_match() { } void test_float_exact_match() { - constexpr grnxx::Int NUM_ROWS = 1 << 16; - - grnxx::Error error; + constexpr size_t NUM_ROWS = 1 << 16; // Create a database with the default options. - auto db = grnxx::open_db(&error, ""); - assert(db); + auto db = grnxx::open_db(""); // Create a table with the default options. - auto table = db->create_table(&error, "Table"); - assert(table); + auto table = db->create_table("Table"); // Create a column. - auto column = table->create_column(&error, "Float", grnxx::FLOAT_DATA); - assert(column); + auto column = table->create_column("Float", grnxx::FLOAT_DATA); // Create an index. - auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); - assert(index); + auto index = column->create_index("Index", grnxx::TREE_INDEX); // Generate random values. - // Float: [0.0, 1.0). + // Float: [0, 1.0) or N/A. grnxx::Array<grnxx::Float> values; - assert(values.resize(&error, NUM_ROWS + 1)); - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - values.set(i, (mersenne_twister() % 256) / 256.0); - } - - // Store generated values into columns. - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - grnxx::Int row_id; - assert(table->insert_row(&error, grnxx::NULL_ROW_ID, - grnxx::Datum(), &row_id)); - assert(row_id == i); - assert(column->set(&error, row_id, values[i])); - } - - // Test cursors for each value. - for (grnxx::Int int_value = 0; int_value < 256; ++int_value) { - grnxx::Float value = int_value / 256.0; - - auto cursor = index->find(&error, value); - assert(cursor); - - grnxx::Array<grnxx::Record> records; - auto result = cursor->read_all(&error, &records); - assert(result.is_ok); - for (grnxx::Int i = 1; i < records.size(); ++i) { - assert(values[records.get_row_id(i)] == value); - } - - grnxx::Int count = 0; - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - if (values[i] == value) { - ++count; - } + values.resize(NUM_ROWS); + size_t total_count = 0; + for (size_t i = 0; i < NUM_ROWS; ++i) { + if ((mersenne_twister() % 256) != 0) { + values[i] = grnxx::Float((mersenne_twister() % 256) / 256.0); + ++total_count; + } else { + values[i] = grnxx::Float::na(); } - assert(count == records.size()); - } -} - -void test_text_exact_match() { - constexpr grnxx::Int NUM_ROWS = 1 << 16; - - grnxx::Error error; - - // Create a database with the default options. - auto db = grnxx::open_db(&error, ""); - assert(db); - - // Create a table with the default options. - auto table = db->create_table(&error, "Table"); - assert(table); - - // Create a column. - auto column = table->create_column(&error, "Text", grnxx::TEXT_DATA); - assert(column); - - // Create an index. - auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); - assert(index); - - // Generate random values. - // Text: ["0", "99"]. - grnxx::Array<grnxx::Text> values; - char bodies[100][3]; - assert(values.resize(&error, NUM_ROWS + 1)); - for (int i = 0; i < 100; ++i) { - std::sprintf(bodies[i], "%d", i); - } - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - values.set(i, bodies[mersenne_twister() % 100]); } // Store generated values into columns. - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - grnxx::Int row_id; - assert(table->insert_row(&error, grnxx::NULL_ROW_ID, - grnxx::Datum(), &row_id)); - assert(row_id == i); - assert(column->set(&error, row_id, values[i])); + for (size_t i = 0; i < NUM_ROWS; ++i) { + grnxx::Int row_id = table->insert_row(); + assert(row_id.match(grnxx::Int(i))); + column->set(row_id, values[i]); } // Test cursors for each value. - for (int int_value = 0; int_value < 100; ++int_value) { - grnxx::Text value = bodies[int_value]; - - auto cursor = index->find(&error, value); - assert(cursor); + for (int raw = 0; raw < 256; ++raw) { + grnxx::Float value(raw / 256.0); + auto cursor = index->find(value); grnxx::Array<grnxx::Record> records; - auto result = cursor->read_all(&error, &records); - assert(result.is_ok); - for (grnxx::Int i = 1; i < records.size(); ++i) { - assert(values[records.get_row_id(i)] == value); + size_t count = cursor->read_all(&records); + for (size_t i = 0; i < records.size(); ++i) { + assert(values[records[i].row_id.raw()].match(value)); } - grnxx::Int count = 0; - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - if (values[i] == value) { + count = 0; + for (size_t i = 0; i < NUM_ROWS; ++i) { + if (values[i].match(value)) { ++count; } } @@ -465,370 +405,60 @@ void test_text_exact_match() { } } -void test_int_range() { - constexpr grnxx::Int NUM_ROWS = 1 << 16; - - grnxx::Error error; - - // Create a database with the default options. - auto db = grnxx::open_db(&error, ""); - assert(db); - - // Create a table with the default options. - auto table = db->create_table(&error, "Table"); - assert(table); - - // Create a column. - auto column = table->create_column(&error, "Int", grnxx::INT_DATA); - assert(column); - - // Create an index. - auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); - assert(index); - - // Generate random values. - // Int: [0, 100). - grnxx::Array<grnxx::Int> values; - assert(values.resize(&error, NUM_ROWS + 1)); - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - values.set(i, mersenne_twister() % 100); - } - - // Store generated values into columns. - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - grnxx::Int row_id; - assert(table->insert_row(&error, grnxx::NULL_ROW_ID, - grnxx::Datum(), &row_id)); - assert(row_id == i); - assert(column->set(&error, row_id, values[i])); - } - - // Create a cursor. - grnxx::IndexRange range; - range.set_lower_bound(grnxx::Int(10), grnxx::INCLUSIVE_END_POINT); - range.set_upper_bound(grnxx::Int(90), grnxx::EXCLUSIVE_END_POINT); - auto cursor = index->find_in_range(&error, range); - assert(cursor); - - grnxx::Array<grnxx::Record> records; - auto result = cursor->read_all(&error, &records); - assert(result.is_ok); - for (grnxx::Int i = 1; i < records.size(); ++i) { - assert(values[records.get_row_id(i - 1)] <= values[records.get_row_id(i)]); - } - - grnxx::Int count = 0; - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - if ((values[i] >= 10) && (values[i] < 90)) { - ++count; - } - } - assert(count == records.size()); -} - -void test_float_range() { - constexpr grnxx::Int NUM_ROWS = 1 << 16; - - grnxx::Error error; - - // Create a database with the default options. - auto db = grnxx::open_db(&error, ""); - assert(db); - - // Create a table with the default options. - auto table = db->create_table(&error, "Table"); - assert(table); - - // Create a column. - auto column = table->create_column(&error, "Float", grnxx::FLOAT_DATA); - assert(column); - - // Create an index. - auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); - assert(index); - - // Generate random values. - // Float: [0.0, 1.0). - grnxx::Array<grnxx::Float> values; - assert(values.resize(&error, NUM_ROWS + 1)); - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - values.set(i, (mersenne_twister() % 256) / 256.0); - } - - // Store generated values into columns. - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - grnxx::Int row_id; - assert(table->insert_row(&error, grnxx::NULL_ROW_ID, - grnxx::Datum(), &row_id)); - assert(row_id == i); - assert(column->set(&error, row_id, values[i])); - } - - // Create a cursor. - grnxx::IndexRange range; - range.set_lower_bound(grnxx::Float(64 / 256.0), grnxx::INCLUSIVE_END_POINT); - range.set_upper_bound(grnxx::Float(192 / 256.0), grnxx::EXCLUSIVE_END_POINT); - auto cursor = index->find_in_range(&error, range); - assert(cursor); - - grnxx::Array<grnxx::Record> records; - auto result = cursor->read_all(&error, &records); - assert(result.is_ok); - for (grnxx::Int i = 1; i < records.size(); ++i) { - assert(values[records.get_row_id(i - 1)] <= values[records.get_row_id(i)]); - } - - grnxx::Int count = 0; - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - if ((values[i] >= (64 / 256.0)) && (values[i] < (192 / 256.0))) { - ++count; - } - } - assert(count == records.size()); -} - -void test_text_range() { - constexpr grnxx::Int NUM_ROWS = 1 << 16; - - grnxx::Error error; +void test_text_exact_match() { + constexpr size_t NUM_ROWS = 1 << 16; // Create a database with the default options. - auto db = grnxx::open_db(&error, ""); - assert(db); + auto db = grnxx::open_db(""); // Create a table with the default options. - auto table = db->create_table(&error, "Table"); - assert(table); + auto table = db->create_table("Table"); // Create a column. - auto column = table->create_column(&error, "Text", grnxx::TEXT_DATA); - assert(column); + auto column = table->create_column("Text", grnxx::TEXT_DATA); // Create an index. - auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); - assert(index); + auto index = column->create_index("Index", grnxx::TREE_INDEX); // Generate random values. - // Text: ["0", "99"]. - grnxx::Array<grnxx::Text> values; - char bodies[100][3]; - assert(values.resize(&error, NUM_ROWS + 1)); - for (int i = 0; i < 100; ++i) { + // Text: ["0", "256") or N/A. + char bodies[256][4]; + for (int i = 0; i < 256; ++i) { std::sprintf(bodies[i], "%d", i); } - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - values.set(i, bodies[mersenne_twister() % 100]); - } - - // Store generated values into columns. - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - grnxx::Int row_id; - assert(table->insert_row(&error, grnxx::NULL_ROW_ID, - grnxx::Datum(), &row_id)); - assert(row_id == i); - assert(column->set(&error, row_id, values[i])); - } - - // Create a cursor. - grnxx::IndexRange range; - range.set_lower_bound(grnxx::Text("25"), grnxx::EXCLUSIVE_END_POINT); - range.set_upper_bound(grnxx::Text("75"), grnxx::INCLUSIVE_END_POINT); - auto cursor = index->find_in_range(&error, range); - assert(cursor); - - grnxx::Array<grnxx::Record> records; - auto result = cursor->read_all(&error, &records); - assert(result.is_ok); - for (grnxx::Int i = 1; i < records.size(); ++i) { - assert(values[records.get_row_id(i - 1)] <= values[records.get_row_id(i)]); - } - - grnxx::Int count = 0; - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - if ((values[i] > "25") && (values[i] <= "75")) { - ++count; - } - } - assert(count == records.size()); -} - -bool inclusive_starts_with(const grnxx::Text &arg1, const grnxx::Text &arg2) { - if (arg1.size() < arg2.size()) { - return false; - } - for (grnxx::Int i = 0; i < arg2.size(); ++i) { - if (arg1[i] != arg2[i]) { - return false; - } - } - return true; -} - -bool exclusive_starts_with(const grnxx::Text &arg1, const grnxx::Text &arg2) { - if (arg1.size() <= arg2.size()) { - return false; - } - for (grnxx::Int i = 0; i < arg2.size(); ++i) { - if (arg1[i] != arg2[i]) { - return false; - } - } - return true; -} - -void test_text_find_starts_with() { - constexpr grnxx::Int NUM_ROWS = 1 << 16; - - grnxx::Error error; - - // Create a database with the default options. - auto db = grnxx::open_db(&error, ""); - assert(db); - - // Create a table with the default options. - auto table = db->create_table(&error, "Table"); - assert(table); - - // Create a column. - auto column = table->create_column(&error, "Text", grnxx::TEXT_DATA); - assert(column); - - // Create an index. - auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); - assert(index); - - // Generate random values. - // Text: ["0", "99"]. grnxx::Array<grnxx::Text> values; - char bodies[100][3]; - assert(values.resize(&error, NUM_ROWS + 1)); - for (int i = 0; i < 100; ++i) { - std::sprintf(bodies[i], "%d", i); - } - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - values.set(i, bodies[mersenne_twister() % 100]); - } - - // Store generated values into columns. - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - grnxx::Int row_id; - assert(table->insert_row(&error, grnxx::NULL_ROW_ID, - grnxx::Datum(), &row_id)); - assert(row_id == i); - assert(column->set(&error, row_id, values[i])); - } - - // Test cursors for each value. - for (int int_value = 0; int_value < 100; ++int_value) { - grnxx::Text value = bodies[int_value]; - - grnxx::EndPoint prefix; - prefix.value = value; - prefix.type = grnxx::INCLUSIVE_END_POINT; - auto cursor = index->find_starts_with(&error, prefix); - assert(cursor); - - grnxx::Array<grnxx::Record> records; - auto result = cursor->read_all(&error, &records); - assert(result.is_ok); - for (grnxx::Int i = 1; i < records.size(); ++i) { - assert(inclusive_starts_with(values[records.get_row_id(i)], value)); - } - - grnxx::Int count = 0; - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - if (inclusive_starts_with(values[i], value)) { - ++count; - } + values.resize(NUM_ROWS); + size_t total_count = 0; + for (size_t i = 0; i < NUM_ROWS; ++i) { + if ((mersenne_twister() % 256) != 0) { + values[i] = grnxx::Text(bodies[mersenne_twister() % 256]); + ++total_count; + } else { + values[i] = grnxx::Text::na(); } - assert(count == records.size()); - } - - // Test cursors for each value. - for (int int_value = 0; int_value < 100; ++int_value) { - grnxx::Text value = bodies[int_value]; - - grnxx::EndPoint prefix; - prefix.value = value; - prefix.type = grnxx::EXCLUSIVE_END_POINT; - auto cursor = index->find_starts_with(&error, prefix); - assert(cursor); - - grnxx::Array<grnxx::Record> records; - auto result = cursor->read_all(&error, &records); - assert(result.is_ok); - for (grnxx::Int i = 1; i < records.size(); ++i) { - assert(exclusive_starts_with(values[records.get_row_id(i)], value)); - } - - grnxx::Int count = 0; - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - if (exclusive_starts_with(values[i], value)) { - ++count; - } - } - assert(count == records.size()); - } -} - -void test_text_find_prefixes() { - constexpr grnxx::Int NUM_ROWS = 1 << 16; - - grnxx::Error error; - - // Create a database with the default options. - auto db = grnxx::open_db(&error, ""); - assert(db); - - // Create a table with the default options. - auto table = db->create_table(&error, "Table"); - assert(table); - - // Create a column. - auto column = table->create_column(&error, "Text", grnxx::TEXT_DATA); - assert(column); - - // Create an index. - auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); - assert(index); - - // Generate random values. - // Text: ["0", "99"]. - grnxx::Array<grnxx::Text> values; - char bodies[100][3]; - assert(values.resize(&error, NUM_ROWS + 1)); - for (int i = 0; i < 100; ++i) { - std::sprintf(bodies[i], "%d", i); - } - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - values.set(i, bodies[mersenne_twister() % 100]); } // Store generated values into columns. - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - grnxx::Int row_id; - assert(table->insert_row(&error, grnxx::NULL_ROW_ID, - grnxx::Datum(), &row_id)); - assert(row_id == i); - assert(column->set(&error, row_id, values[i])); + for (size_t i = 0; i < NUM_ROWS; ++i) { + grnxx::Int row_id = table->insert_row(); + assert(row_id.match(grnxx::Int(i))); + column->set(row_id, values[i]); } // Test cursors for each value. - for (int int_value = 0; int_value < 100; ++int_value) { - grnxx::Text value = bodies[int_value]; - auto cursor = index->find_prefixes(&error, value); - assert(cursor); + for (int raw = 0; raw < 256; ++raw) { + grnxx::Text value(bodies[raw]); + auto cursor = index->find(value); grnxx::Array<grnxx::Record> records; - auto result = cursor->read_all(&error, &records); - assert(result.is_ok); - for (grnxx::Int i = 1; i < records.size(); ++i) { - assert(inclusive_starts_with(value, values[records.get_row_id(i)])); + size_t count = cursor->read_all(&records); + for (size_t i = 0; i < records.size(); ++i) { + assert(values[records[i].row_id.raw()].match(value)); } - grnxx::Int count = 0; - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - if (inclusive_starts_with(value, values[i])) { + count = 0; + for (size_t i = 0; i < NUM_ROWS; ++i) { + if (values[i].match(value)) { ++count; } } @@ -836,149 +466,586 @@ void test_text_find_prefixes() { } } -void test_reverse() { - constexpr grnxx::Int NUM_ROWS = 1 << 16; - - grnxx::Error error; - - // Create a database with the default options. - auto db = grnxx::open_db(&error, ""); - assert(db); - - // Create a table with the default options. - auto table = db->create_table(&error, "Table"); - assert(table); - - // Create a column. - auto column = table->create_column(&error, "Int", grnxx::INT_DATA); - assert(column); - - // Create an index. - auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); - assert(index); - - // Generate random values. - // Int: [0, 100). - grnxx::Array<grnxx::Int> values; - assert(values.resize(&error, NUM_ROWS + 1)); - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - values.set(i, mersenne_twister() % 100); - } - - // Store generated values into columns. - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - grnxx::Int row_id; - assert(table->insert_row(&error, grnxx::NULL_ROW_ID, - grnxx::Datum(), &row_id)); - assert(row_id == i); - assert(column->set(&error, row_id, values[i])); - } - - // Create a cursor. - grnxx::IndexRange range; - range.set_lower_bound(grnxx::Int(10), grnxx::INCLUSIVE_END_POINT); - range.set_upper_bound(grnxx::Int(90), grnxx::EXCLUSIVE_END_POINT); - grnxx::CursorOptions options; - options.order_type = grnxx::REVERSE_ORDER; - auto cursor = index->find_in_range(&error, range, options); - assert(cursor); - - grnxx::Array<grnxx::Record> records; - auto result = cursor->read_all(&error, &records); - assert(result.is_ok); - for (grnxx::Int i = 1; i < records.size(); ++i) { - assert(values[records.get_row_id(i - 1)] >= values[records.get_row_id(i)]); - } - - grnxx::Int count = 0; - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - if ((values[i] >= 10) && (values[i] < 90)) { - ++count; - } - } - assert(count == records.size()); -} - -void test_offset_and_limit() { - constexpr grnxx::Int NUM_ROWS = 1 << 16; - - grnxx::Error error; - - // Create a database with the default options. - auto db = grnxx::open_db(&error, ""); - assert(db); - - // Create a table with the default options. - auto table = db->create_table(&error, "Table"); - assert(table); - - // Create a column. - auto column = table->create_column(&error, "Int", grnxx::INT_DATA); - assert(column); - - // Generate random values. - // Int: [0, 100). - grnxx::Array<grnxx::Int> values; - assert(values.resize(&error, NUM_ROWS + 1)); - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - values.set(i, mersenne_twister() % 100); - } - - // Store generated values into columns. - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - grnxx::Int row_id; - assert(table->insert_row(&error, grnxx::NULL_ROW_ID, - grnxx::Datum(), &row_id)); - assert(row_id == i); - assert(column->set(&error, row_id, values[i])); - } - - // Create an index. - auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); - assert(index); - - // Create a cursor. - auto cursor = index->find_in_range(&error); - assert(cursor); - - grnxx::Array<grnxx::Record> records; - auto result = cursor->read_all(&error, &records); - assert(result.is_ok); - assert(result.count == NUM_ROWS); - - constexpr grnxx::Int OFFSET = 1000; - - // Create a cursor with an offset. - grnxx::CursorOptions options; - options.offset = OFFSET; - cursor = index->find_in_range(&error, grnxx::IndexRange(), options); - - grnxx::Array<grnxx::Record> records_with_offset; - result = cursor->read_all(&error, &records_with_offset); - assert(result.is_ok); - assert(result.count == (NUM_ROWS - OFFSET)); - - for (grnxx::Int i = 0; i < records_with_offset.size(); ++i) { - assert(records.get_row_id(OFFSET + i) == - records_with_offset.get_row_id(i)); - } - - constexpr grnxx::Int LIMIT = 100; - - // Create a cursor with an offset and a limit. - options.limit = LIMIT; - cursor = index->find_in_range(&error, grnxx::IndexRange(), options); - - grnxx::Array<grnxx::Record> records_with_offset_and_limit; - result = cursor->read_all(&error, &records_with_offset_and_limit); - assert(result.is_ok); - assert(result.count == LIMIT); - - for (grnxx::Int i = 0; i < records_with_offset_and_limit.size(); ++i) { - assert(records.get_row_id(OFFSET + i) == - records_with_offset_and_limit.get_row_id(i)); - } -} +//void test_text_exact_match() { +// constexpr grnxx::Int NUM_ROWS = 1 << 16; + +// grnxx::Error error; + +// // Create a database with the default options. +// auto db = grnxx::open_db(&error, ""); +// assert(db); + +// // Create a table with the default options. +// auto table = db->create_table(&error, "Table"); +// assert(table); + +// // Create a column. +// auto column = table->create_column(&error, "Text", grnxx::TEXT_DATA); +// assert(column); + +// // Create an index. +// auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); +// assert(index); + +// // Generate random values. +// // Text: ["0", "99"]. +// grnxx::Array<grnxx::Text> values; +// char bodies[100][3]; +// assert(values.resize(&error, NUM_ROWS + 1)); +// for (int i = 0; i < 100; ++i) { +// std::sprintf(bodies[i], "%d", i); +// } +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// values.set(i, bodies[mersenne_twister() % 100]); +// } + +// // Store generated values into columns. +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// grnxx::Int row_id; +// assert(table->insert_row(&error, grnxx::NULL_ROW_ID, +// grnxx::Datum(), &row_id)); +// assert(row_id == i); +// assert(column->set(&error, row_id, values[i])); +// } + +// // Test cursors for each value. +// for (int int_value = 0; int_value < 100; ++int_value) { +// grnxx::Text value = bodies[int_value]; + +// auto cursor = index->find(&error, value); +// assert(cursor); + +// grnxx::Array<grnxx::Record> records; +// auto result = cursor->read_all(&error, &records); +// assert(result.is_ok); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// assert(values[records.get_row_id(i)] == value); +// } + +// grnxx::Int count = 0; +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// if (values[i] == value) { +// ++count; +// } +// } +// assert(count == records.size()); +// } +//} + +//void test_int_range() { +// constexpr grnxx::Int NUM_ROWS = 1 << 16; + +// grnxx::Error error; + +// // Create a database with the default options. +// auto db = grnxx::open_db(&error, ""); +// assert(db); + +// // Create a table with the default options. +// auto table = db->create_table(&error, "Table"); +// assert(table); + +// // Create a column. +// auto column = table->create_column(&error, "Int", grnxx::INT_DATA); +// assert(column); + +// // Create an index. +// auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); +// assert(index); + +// // Generate random values. +// // Int: [0, 100). +// grnxx::Array<grnxx::Int> values; +// assert(values.resize(&error, NUM_ROWS + 1)); +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// values.set(i, mersenne_twister() % 100); +// } + +// // Store generated values into columns. +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// grnxx::Int row_id; +// assert(table->insert_row(&error, grnxx::NULL_ROW_ID, +// grnxx::Datum(), &row_id)); +// assert(row_id == i); +// assert(column->set(&error, row_id, values[i])); +// } + +// // Create a cursor. +// grnxx::IndexRange range; +// range.set_lower_bound(grnxx::Int(10), grnxx::INCLUSIVE_END_POINT); +// range.set_upper_bound(grnxx::Int(90), grnxx::EXCLUSIVE_END_POINT); +// auto cursor = index->find_in_range(&error, range); +// assert(cursor); + +// grnxx::Array<grnxx::Record> records; +// auto result = cursor->read_all(&error, &records); +// assert(result.is_ok); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// assert(values[records.get_row_id(i - 1)] <= values[records.get_row_id(i)]); +// } + +// grnxx::Int count = 0; +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// if ((values[i] >= 10) && (values[i] < 90)) { +// ++count; +// } +// } +// assert(count == records.size()); +//} + +//void test_float_range() { +// constexpr grnxx::Int NUM_ROWS = 1 << 16; + +// grnxx::Error error; + +// // Create a database with the default options. +// auto db = grnxx::open_db(&error, ""); +// assert(db); + +// // Create a table with the default options. +// auto table = db->create_table(&error, "Table"); +// assert(table); + +// // Create a column. +// auto column = table->create_column(&error, "Float", grnxx::FLOAT_DATA); +// assert(column); + +// // Create an index. +// auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); +// assert(index); + +// // Generate random values. +// // Float: [0.0, 1.0). +// grnxx::Array<grnxx::Float> values; +// assert(values.resize(&error, NUM_ROWS + 1)); +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// values.set(i, (mersenne_twister() % 256) / 256.0); +// } + +// // Store generated values into columns. +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// grnxx::Int row_id; +// assert(table->insert_row(&error, grnxx::NULL_ROW_ID, +// grnxx::Datum(), &row_id)); +// assert(row_id == i); +// assert(column->set(&error, row_id, values[i])); +// } + +// // Create a cursor. +// grnxx::IndexRange range; +// range.set_lower_bound(grnxx::Float(64 / 256.0), grnxx::INCLUSIVE_END_POINT); +// range.set_upper_bound(grnxx::Float(192 / 256.0), grnxx::EXCLUSIVE_END_POINT); +// auto cursor = index->find_in_range(&error, range); +// assert(cursor); + +// grnxx::Array<grnxx::Record> records; +// auto result = cursor->read_all(&error, &records); +// assert(result.is_ok); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// assert(values[records.get_row_id(i - 1)] <= values[records.get_row_id(i)]); +// } + +// grnxx::Int count = 0; +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// if ((values[i] >= (64 / 256.0)) && (values[i] < (192 / 256.0))) { +// ++count; +// } +// } +// assert(count == records.size()); +//} + +//void test_text_range() { +// constexpr grnxx::Int NUM_ROWS = 1 << 16; + +// grnxx::Error error; + +// // Create a database with the default options. +// auto db = grnxx::open_db(&error, ""); +// assert(db); + +// // Create a table with the default options. +// auto table = db->create_table(&error, "Table"); +// assert(table); + +// // Create a column. +// auto column = table->create_column(&error, "Text", grnxx::TEXT_DATA); +// assert(column); + +// // Create an index. +// auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); +// assert(index); + +// // Generate random values. +// // Text: ["0", "99"]. +// grnxx::Array<grnxx::Text> values; +// char bodies[100][3]; +// assert(values.resize(&error, NUM_ROWS + 1)); +// for (int i = 0; i < 100; ++i) { +// std::sprintf(bodies[i], "%d", i); +// } +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// values.set(i, bodies[mersenne_twister() % 100]); +// } + +// // Store generated values into columns. +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// grnxx::Int row_id; +// assert(table->insert_row(&error, grnxx::NULL_ROW_ID, +// grnxx::Datum(), &row_id)); +// assert(row_id == i); +// assert(column->set(&error, row_id, values[i])); +// } + +// // Create a cursor. +// grnxx::IndexRange range; +// range.set_lower_bound(grnxx::Text("25"), grnxx::EXCLUSIVE_END_POINT); +// range.set_upper_bound(grnxx::Text("75"), grnxx::INCLUSIVE_END_POINT); +// auto cursor = index->find_in_range(&error, range); +// assert(cursor); + +// grnxx::Array<grnxx::Record> records; +// auto result = cursor->read_all(&error, &records); +// assert(result.is_ok); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// assert(values[records.get_row_id(i - 1)] <= values[records.get_row_id(i)]); +// } + +// grnxx::Int count = 0; +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// if ((values[i] > "25") && (values[i] <= "75")) { +// ++count; +// } +// } +// assert(count == records.size()); +//} + +//bool inclusive_starts_with(const grnxx::Text &arg1, const grnxx::Text &arg2) { +// if (arg1.size() < arg2.size()) { +// return false; +// } +// for (grnxx::Int i = 0; i < arg2.size(); ++i) { +// if (arg1[i] != arg2[i]) { +// return false; +// } +// } +// return true; +//} + +//bool exclusive_starts_with(const grnxx::Text &arg1, const grnxx::Text &arg2) { +// if (arg1.size() <= arg2.size()) { +// return false; +// } +// for (grnxx::Int i = 0; i < arg2.size(); ++i) { +// if (arg1[i] != arg2[i]) { +// return false; +// } +// } +// return true; +//} + +//void test_text_find_starts_with() { +// constexpr grnxx::Int NUM_ROWS = 1 << 16; + +// grnxx::Error error; + +// // Create a database with the default options. +// auto db = grnxx::open_db(&error, ""); +// assert(db); + +// // Create a table with the default options. +// auto table = db->create_table(&error, "Table"); +// assert(table); + +// // Create a column. +// auto column = table->create_column(&error, "Text", grnxx::TEXT_DATA); +// assert(column); + +// // Create an index. +// auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); +// assert(index); + +// // Generate random values. +// // Text: ["0", "99"]. +// grnxx::Array<grnxx::Text> values; +// char bodies[100][3]; +// assert(values.resize(&error, NUM_ROWS + 1)); +// for (int i = 0; i < 100; ++i) { +// std::sprintf(bodies[i], "%d", i); +// } +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// values.set(i, bodies[mersenne_twister() % 100]); +// } + +// // Store generated values into columns. +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// grnxx::Int row_id; +// assert(table->insert_row(&error, grnxx::NULL_ROW_ID, +// grnxx::Datum(), &row_id)); +// assert(row_id == i); +// assert(column->set(&error, row_id, values[i])); +// } + +// // Test cursors for each value. +// for (int int_value = 0; int_value < 100; ++int_value) { +// grnxx::Text value = bodies[int_value]; + +// grnxx::EndPoint prefix; +// prefix.value = value; +// prefix.type = grnxx::INCLUSIVE_END_POINT; +// auto cursor = index->find_starts_with(&error, prefix); +// assert(cursor); + +// grnxx::Array<grnxx::Record> records; +// auto result = cursor->read_all(&error, &records); +// assert(result.is_ok); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// assert(inclusive_starts_with(values[records.get_row_id(i)], value)); +// } + +// grnxx::Int count = 0; +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// if (inclusive_starts_with(values[i], value)) { +// ++count; +// } +// } +// assert(count == records.size()); +// } + +// // Test cursors for each value. +// for (int int_value = 0; int_value < 100; ++int_value) { +// grnxx::Text value = bodies[int_value]; + +// grnxx::EndPoint prefix; +// prefix.value = value; +// prefix.type = grnxx::EXCLUSIVE_END_POINT; +// auto cursor = index->find_starts_with(&error, prefix); +// assert(cursor); + +// grnxx::Array<grnxx::Record> records; +// auto result = cursor->read_all(&error, &records); +// assert(result.is_ok); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// assert(exclusive_starts_with(values[records.get_row_id(i)], value)); +// } + +// grnxx::Int count = 0; +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// if (exclusive_starts_with(values[i], value)) { +// ++count; +// } +// } +// assert(count == records.size()); +// } +//} + +//void test_text_find_prefixes() { +// constexpr grnxx::Int NUM_ROWS = 1 << 16; + +// grnxx::Error error; + +// // Create a database with the default options. +// auto db = grnxx::open_db(&error, ""); +// assert(db); + +// // Create a table with the default options. +// auto table = db->create_table(&error, "Table"); +// assert(table); + +// // Create a column. +// auto column = table->create_column(&error, "Text", grnxx::TEXT_DATA); +// assert(column); + +// // Create an index. +// auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); +// assert(index); + +// // Generate random values. +// // Text: ["0", "99"]. +// grnxx::Array<grnxx::Text> values; +// char bodies[100][3]; +// assert(values.resize(&error, NUM_ROWS + 1)); +// for (int i = 0; i < 100; ++i) { +// std::sprintf(bodies[i], "%d", i); +// } +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// values.set(i, bodies[mersenne_twister() % 100]); +// } + +// // Store generated values into columns. +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// grnxx::Int row_id; +// assert(table->insert_row(&error, grnxx::NULL_ROW_ID, +// grnxx::Datum(), &row_id)); +// assert(row_id == i); +// assert(column->set(&error, row_id, values[i])); +// } + +// // Test cursors for each value. +// for (int int_value = 0; int_value < 100; ++int_value) { +// grnxx::Text value = bodies[int_value]; +// auto cursor = index->find_prefixes(&error, value); +// assert(cursor); + +// grnxx::Array<grnxx::Record> records; +// auto result = cursor->read_all(&error, &records); +// assert(result.is_ok); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// assert(inclusive_starts_with(value, values[records.get_row_id(i)])); +// } + +// grnxx::Int count = 0; +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// if (inclusive_starts_with(value, values[i])) { +// ++count; +// } +// } +// assert(count == records.size()); +// } +//} + +//void test_reverse() { +// constexpr grnxx::Int NUM_ROWS = 1 << 16; + +// grnxx::Error error; + +// // Create a database with the default options. +// auto db = grnxx::open_db(&error, ""); +// assert(db); + +// // Create a table with the default options. +// auto table = db->create_table(&error, "Table"); +// assert(table); + +// // Create a column. +// auto column = table->create_column(&error, "Int", grnxx::INT_DATA); +// assert(column); + +// // Create an index. +// auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); +// assert(index); + +// // Generate random values. +// // Int: [0, 100). +// grnxx::Array<grnxx::Int> values; +// assert(values.resize(&error, NUM_ROWS + 1)); +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// values.set(i, mersenne_twister() % 100); +// } + +// // Store generated values into columns. +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// grnxx::Int row_id; +// assert(table->insert_row(&error, grnxx::NULL_ROW_ID, +// grnxx::Datum(), &row_id)); +// assert(row_id == i); +// assert(column->set(&error, row_id, values[i])); +// } + +// // Create a cursor. +// grnxx::IndexRange range; +// range.set_lower_bound(grnxx::Int(10), grnxx::INCLUSIVE_END_POINT); +// range.set_upper_bound(grnxx::Int(90), grnxx::EXCLUSIVE_END_POINT); +// grnxx::CursorOptions options; +// options.order_type = grnxx::REVERSE_ORDER; +// auto cursor = index->find_in_range(&error, range, options); +// assert(cursor); + +// grnxx::Array<grnxx::Record> records; +// auto result = cursor->read_all(&error, &records); +// assert(result.is_ok); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// assert(values[records.get_row_id(i - 1)] >= values[records.get_row_id(i)]); +// } + +// grnxx::Int count = 0; +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// if ((values[i] >= 10) && (values[i] < 90)) { +// ++count; +// } +// } +// assert(count == records.size()); +//} + +//void test_offset_and_limit() { +// constexpr grnxx::Int NUM_ROWS = 1 << 16; + +// grnxx::Error error; + +// // Create a database with the default options. +// auto db = grnxx::open_db(&error, ""); +// assert(db); + +// // Create a table with the default options. +// auto table = db->create_table(&error, "Table"); +// assert(table); + +// // Create a column. +// auto column = table->create_column(&error, "Int", grnxx::INT_DATA); +// assert(column); + +// // Generate random values. +// // Int: [0, 100). +// grnxx::Array<grnxx::Int> values; +// assert(values.resize(&error, NUM_ROWS + 1)); +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// values.set(i, mersenne_twister() % 100); +// } + +// // Store generated values into columns. +// for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { +// grnxx::Int row_id; +// assert(table->insert_row(&error, grnxx::NULL_ROW_ID, +// grnxx::Datum(), &row_id)); +// assert(row_id == i); +// assert(column->set(&error, row_id, values[i])); +// } + +// // Create an index. +// auto index = column->create_index(&error, "Index", grnxx::TREE_INDEX); +// assert(index); + +// // Create a cursor. +// auto cursor = index->find_in_range(&error); +// assert(cursor); + +// grnxx::Array<grnxx::Record> records; +// auto result = cursor->read_all(&error, &records); +// assert(result.is_ok); +// assert(result.count == NUM_ROWS); + +// constexpr grnxx::Int OFFSET = 1000; + +// // Create a cursor with an offset. +// grnxx::CursorOptions options; +// options.offset = OFFSET; +// cursor = index->find_in_range(&error, grnxx::IndexRange(), options); + +// grnxx::Array<grnxx::Record> records_with_offset; +// result = cursor->read_all(&error, &records_with_offset); +// assert(result.is_ok); +// assert(result.count == (NUM_ROWS - OFFSET)); + +// for (grnxx::Int i = 0; i < records_with_offset.size(); ++i) { +// assert(records.get_row_id(OFFSET + i) == +// records_with_offset.get_row_id(i)); +// } + +// constexpr grnxx::Int LIMIT = 100; + +// // Create a cursor with an offset and a limit. +// options.limit = LIMIT; +// cursor = index->find_in_range(&error, grnxx::IndexRange(), options); + +// grnxx::Array<grnxx::Record> records_with_offset_and_limit; +// result = cursor->read_all(&error, &records_with_offset_and_limit); +// assert(result.is_ok); +// assert(result.count == LIMIT); + +// for (grnxx::Int i = 0; i < records_with_offset_and_limit.size(); ++i) { +// assert(records.get_row_id(OFFSET + i) == +// records_with_offset_and_limit.get_row_id(i)); +// } +//} int main() { test_index(); @@ -987,20 +1054,20 @@ int main() { test_index_and_set(); test_remove(); - test_bool_exact_match(); +// test_bool_exact_match(); test_int_exact_match(); test_float_exact_match(); test_text_exact_match(); - test_int_range(); - test_float_range(); - test_text_range(); +// test_int_range(); +// test_float_range(); +// test_text_range(); - test_text_find_starts_with(); - test_text_find_prefixes(); +// test_text_find_starts_with(); +// test_text_find_prefixes(); - test_reverse(); - test_offset_and_limit(); +// test_reverse(); +// test_offset_and_limit(); return 0; } -------------- next part -------------- HTML����������������������������... 下载