susumu.yata
null+****@clear*****
Tue Dec 16 10:43:57 JST 2014
susumu.yata 2014-11-20 17:47:31 +0900 (Thu, 20 Nov 2014) New Revision: 2c1a8e40ec733539ccc27a480b5905077cd9c482 https://github.com/groonga/grnxx/commit/2c1a8e40ec733539ccc27a480b5905077cd9c482 Message: Enable tests for Sorter for Bool. (#112) Modified files: test/Makefile.am test/test_sorter.cpp Modified: test/Makefile.am (+3 -3) =================================================================== --- test/Makefile.am 2014-11-20 17:47:04 +0900 (7650523) +++ test/Makefile.am 2014-11-20 17:47:31 +0900 (15f1aa9) @@ -6,11 +6,11 @@ TESTS = \ test_table \ test_column \ test_expression \ + test_sorter \ test_issue_62 # test_index \ # test_merger \ -# test_sorter \ # test_pipeline check_PROGRAMS = $(TESTS) @@ -42,8 +42,8 @@ test_expression_LDADD = $(top_srcdir)/lib/grnxx/libgrnxx.la #test_merger_SOURCES = test_merger.cpp #test_merger_LDADD = $(top_srcdir)/lib/grnxx/libgrnxx.la -#test_sorter_SOURCES = test_sorter.cpp -#test_sorter_LDADD = $(top_srcdir)/lib/grnxx/libgrnxx.la +test_sorter_SOURCES = test_sorter.cpp +test_sorter_LDADD = $(top_srcdir)/lib/grnxx/libgrnxx.la #test_pipeline_SOURCES = test_pipeline.cpp #test_pipeline_LDADD = $(top_srcdir)/lib/grnxx/libgrnxx.la Modified: test/test_sorter.cpp (+416 -411) =================================================================== --- test/test_sorter.cpp 2014-11-20 17:47:04 +0900 (03152f0) +++ test/test_sorter.cpp 2014-11-20 17:47:31 +0900 (ba5ab9b) @@ -27,7 +27,7 @@ #include "grnxx/sorter.hpp" struct { - grnxx::unique_ptr<grnxx::DB> db; + std::unique_ptr<grnxx::DB> db; grnxx::Table *table; grnxx::Array<grnxx::Bool> bool_values; grnxx::Array<grnxx::Int> int_values; @@ -37,466 +37,471 @@ struct { } test; void init_test() { - grnxx::Error error; - // Create a database with the default options. - test.db = grnxx::open_db(&error, ""); - assert(test.db); + test.db = grnxx::open_db(""); // Create a table with the default options. - test.table = test.db->create_table(&error, "Table"); - assert(test.table); + test.table = test.db->create_table("Table"); // Create columns for Bool, Int, Float, and Text values. - grnxx::DataType data_type = grnxx::BOOL_DATA; - auto bool_column = test.table->create_column(&error, "Bool", data_type); - assert(bool_column); - - data_type = grnxx::INT_DATA; - auto int_column = test.table->create_column(&error, "Int", data_type); - assert(int_column); - - data_type = grnxx::FLOAT_DATA; - auto float_column = test.table->create_column(&error, "Float", data_type); - assert(float_column); - - data_type = grnxx::TEXT_DATA; - auto text_column = test.table->create_column(&error, "Text", data_type); - assert(text_column); + auto bool_column = test.table->create_column("Bool", grnxx::BOOL_DATA); + auto int_column = test.table->create_column("Int", grnxx::INT_DATA); + auto float_column = test.table->create_column("Float", grnxx::FLOAT_DATA); + auto text_column = test.table->create_column("Text", grnxx::TEXT_DATA); // Generate random values. - // Bool: true or false. - // Int: [0, 100). - // Float: [0.0, 1.0]. - // Text: length = [1, 4], byte = ['0', '9']. - constexpr grnxx::Int NUM_ROWS = 1 << 16; - constexpr grnxx::Int MIN_LENGTH = 1; - constexpr grnxx::Int MAX_LENGTH = 4; + // Bool: true, false, and N/A. + // Int: [0, 100) and N/A. + // Float: [0.0, 1.0] and N/A. + // Text: length = [1, 4], byte = ['0', '9'], and N/A. + constexpr size_t NUM_ROWS = 1 << 16; std::mt19937_64 mersenne_twister; - assert(test.bool_values.resize(&error, NUM_ROWS + 1)); - assert(test.int_values.resize(&error, NUM_ROWS + 1)); - assert(test.float_values.resize(&error, NUM_ROWS + 1)); - assert(test.text_values.resize(&error, NUM_ROWS + 1)); - assert(test.text_bodies.resize(&error, NUM_ROWS + 1)); - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - test.bool_values.set(i, (mersenne_twister() & 1) != 0); - test.int_values.set(i, mersenne_twister() % 100); - if ((mersenne_twister() % 16) == 0) { - test.float_values.set(i, std::numeric_limits<grnxx::Float>::quiet_NaN()); + test.bool_values.resize(NUM_ROWS); + test.int_values.resize(NUM_ROWS); + test.float_values.resize(NUM_ROWS); + test.text_values.resize(NUM_ROWS); + test.text_bodies.resize(NUM_ROWS); + for (size_t i = 0; i < NUM_ROWS; ++i) { + uint64_t source = mersenne_twister() % 3; + switch (source) { + case 0: { + test.bool_values[i] = grnxx::Bool(false); + break; + } + case 1: { + test.bool_values[i] = grnxx::Bool(true); + break; + } + case 2: { + test.bool_values[i] = grnxx::Bool::na(); + break; + } + } + + source = mersenne_twister() % 101; + if (source == 0) { + test.int_values[i] = grnxx::Int::na(); + } else { + test.int_values[i] = grnxx::Int(source - 1); + } + + source = mersenne_twister() % 101; + if (source == 0) { + test.float_values[i] = grnxx::Float::na(); } else { - constexpr auto MAX_VALUE = mersenne_twister.max(); - test.float_values.set(i, 1.0 * mersenne_twister() / MAX_VALUE); + test.float_values[i] = grnxx::Float(source / 16.0); } - grnxx::Int length = - (mersenne_twister() % (MAX_LENGTH - MIN_LENGTH)) + MIN_LENGTH; - test.text_bodies[i].resize(length); - for (grnxx::Int j = 0; j < length; ++j) { - test.text_bodies[i][j] = '0' + (mersenne_twister() % 10); + + source = mersenne_twister() % 5; + if (source == 0) { + test.text_values[i] = grnxx::Text::na(); + } else { + size_t size = source - 1; + test.text_bodies[i].resize(size); + for (size_t j = 0; j < size; ++j) { + test.text_bodies[i][j] = '0' + (mersenne_twister() % 10); + } + test.text_values[i] = grnxx::Text(test.text_bodies[i].data(), size); } - test.text_values.set(i, grnxx::Text(test.text_bodies[i].data(), length)); } // Store generated values into columns. - for (grnxx::Int i = 1; i <= NUM_ROWS; ++i) { - grnxx::Int row_id; - assert(test.table->insert_row(&error, grnxx::NULL_ROW_ID, - grnxx::Datum(), &row_id)); - assert(bool_column->set(&error, row_id, test.bool_values[i])); - assert(int_column->set(&error, row_id, test.int_values[i])); - assert(float_column->set(&error, row_id, test.float_values[i])); - assert(text_column->set(&error, row_id, test.text_values[i])); + for (size_t i = 0; i < NUM_ROWS; ++i) { + grnxx::Int row_id = test.table->insert_row(); + bool_column->set(row_id, test.bool_values[i]); + int_column->set(row_id, test.int_values[i]); + float_column->set(row_id, test.float_values[i]); + text_column->set(row_id, test.text_values[i]); } } grnxx::Array<grnxx::Record> create_input_records() { - grnxx::Error error; - - auto cursor = test.table->create_cursor(&error); - assert(cursor); + auto cursor = test.table->create_cursor(); grnxx::Array<grnxx::Record> records; - auto result = cursor->read_all(&error, &records); - assert(result.is_ok); - assert(result.count == test.table->num_rows()); + size_t count = cursor->read_all(&records); + assert(count == test.table->num_rows()); return records; } void test_bool() { - grnxx::Error error; - // Create a cursor which reads all the records. auto records = create_input_records(); // Create an object for building expressions. - auto expression_builder = - grnxx::ExpressionBuilder::create(&error, test.table); - assert(expression_builder); + auto expression_builder = grnxx::ExpressionBuilder::create(test.table); // Create a regular sorter. - grnxx::Array<grnxx::SortOrder> orders; - assert(orders.resize(&error, 1)); - assert(expression_builder->push_column(&error, "Bool")); - auto expression = expression_builder->release(&error); - assert(expression); + grnxx::Array<grnxx::SorterOrder> orders; + orders.resize(1); + expression_builder->push_column("Bool"); + auto expression = expression_builder->release(); orders[0].expression = std::move(expression); - orders[0].type = grnxx::REGULAR_ORDER; - auto sorter = grnxx::Sorter::create(&error, std::move(orders)); + orders[0].type = grnxx::SORTER_REGULAR_ORDER; + auto sorter = grnxx::Sorter::create(std::move(orders)); - sorter->sort(&error, &records); - for (grnxx::Int i = 1; i < records.size(); ++i) { - grnxx::Int lhs_row_id = records.get_row_id(i - 1); - grnxx::Int rhs_row_id = records.get_row_id(i); + sorter->sort(&records); + for (size_t i = 1; i < records.size(); ++i) { + size_t lhs_row_id = records[i - 1].row_id.value(); + size_t rhs_row_id = records[i].row_id.value(); grnxx::Bool lhs_value = test.bool_values[lhs_row_id]; grnxx::Bool rhs_value = test.bool_values[rhs_row_id]; - assert(!lhs_value || rhs_value); + if (lhs_value.is_true()) { + assert(rhs_value.is_true() || rhs_value.is_na()); + } else if (lhs_value.is_na()) { + assert(rhs_value.is_na()); + } } // Create a reverse sorter. - assert(orders.resize(&error, 1)); - assert(expression_builder->push_column(&error, "Bool")); - expression = expression_builder->release(&error); - assert(expression); + orders.resize(1); + expression_builder->push_column("Bool"); + expression = expression_builder->release(); orders[0].expression = std::move(expression); - orders[0].type = grnxx::REVERSE_ORDER; - sorter = grnxx::Sorter::create(&error, std::move(orders)); + orders[0].type = grnxx::SORTER_REVERSE_ORDER; + sorter = grnxx::Sorter::create(std::move(orders)); - sorter->sort(&error, &records); - for (grnxx::Int i = 1; i < records.size(); ++i) { - grnxx::Int lhs_row_id = records.get_row_id(i - 1); - grnxx::Int rhs_row_id = records.get_row_id(i); + sorter->sort(&records); + for (size_t i = 1; i < records.size(); ++i) { + size_t lhs_row_id = records[i - 1].row_id.value(); + size_t rhs_row_id = records[i].row_id.value(); grnxx::Bool lhs_value = test.bool_values[lhs_row_id]; grnxx::Bool rhs_value = test.bool_values[rhs_row_id]; - assert(lhs_value || !rhs_value); - } - - // Create a multiple order sorter. - assert(orders.resize(&error, 2)); - assert(expression_builder->push_column(&error, "Bool")); - expression = expression_builder->release(&error); - assert(expression); - orders[0].expression = std::move(expression); - orders[0].type = grnxx::REGULAR_ORDER; - assert(expression_builder->push_row_id(&error)); - expression = expression_builder->release(&error); - assert(expression); - orders[1].expression = std::move(expression); - orders[1].type = grnxx::REGULAR_ORDER; - sorter = grnxx::Sorter::create(&error, std::move(orders)); - - sorter->sort(&error, &records); - for (grnxx::Int i = 1; i < records.size(); ++i) { - grnxx::Int lhs_row_id = records.get_row_id(i - 1); - grnxx::Int rhs_row_id = records.get_row_id(i); - grnxx::Bool lhs_value = test.bool_values[lhs_row_id]; - grnxx::Bool rhs_value = test.bool_values[rhs_row_id]; - assert(!lhs_value || rhs_value); - if (lhs_value == rhs_value) { - assert(lhs_row_id < rhs_row_id); - } - } -} - -void test_int() { - grnxx::Error error; - - // Create a cursor which reads all the records. - auto records = create_input_records(); - - // Create an object for building expressions. - auto expression_builder = - grnxx::ExpressionBuilder::create(&error, test.table); - assert(expression_builder); - - // Create a regular sorter. - grnxx::Array<grnxx::SortOrder> orders; - assert(orders.resize(&error, 1)); - assert(expression_builder->push_column(&error, "Int")); - auto expression = expression_builder->release(&error); - assert(expression); - orders[0].expression = std::move(expression); - orders[0].type = grnxx::REGULAR_ORDER; - auto sorter = grnxx::Sorter::create(&error, std::move(orders)); - - sorter->sort(&error, &records); - for (grnxx::Int i = 1; i < records.size(); ++i) { - grnxx::Int lhs_row_id = records.get_row_id(i - 1); - grnxx::Int rhs_row_id = records.get_row_id(i); - grnxx::Int lhs_value = test.int_values[lhs_row_id]; - grnxx::Int rhs_value = test.int_values[rhs_row_id]; - assert(lhs_value <= rhs_value); - } - - // Create a reverse sorter. - assert(orders.resize(&error, 1)); - assert(expression_builder->push_column(&error, "Int")); - expression = expression_builder->release(&error); - assert(expression); - orders[0].expression = std::move(expression); - orders[0].type = grnxx::REVERSE_ORDER; - sorter = grnxx::Sorter::create(&error, std::move(orders)); - - sorter->sort(&error, &records); - for (grnxx::Int i = 1; i < records.size(); ++i) { - grnxx::Int lhs_row_id = records.get_row_id(i - 1); - grnxx::Int rhs_row_id = records.get_row_id(i); - grnxx::Int lhs_value = test.int_values[lhs_row_id]; - grnxx::Int rhs_value = test.int_values[rhs_row_id]; - assert(lhs_value >= rhs_value); - } - - // Create a multiple order sorter. - assert(orders.resize(&error, 2)); - assert(expression_builder->push_column(&error, "Int")); - expression = expression_builder->release(&error); - assert(expression); - orders[0].expression = std::move(expression); - orders[0].type = grnxx::REGULAR_ORDER; - assert(expression_builder->push_row_id(&error)); - expression = expression_builder->release(&error); - assert(expression); - orders[1].expression = std::move(expression); - orders[1].type = grnxx::REGULAR_ORDER; - sorter = grnxx::Sorter::create(&error, std::move(orders)); - - sorter->sort(&error, &records); - for (grnxx::Int i = 1; i < records.size(); ++i) { - grnxx::Int lhs_row_id = records.get_row_id(i - 1); - grnxx::Int rhs_row_id = records.get_row_id(i); - grnxx::Int lhs_value = test.int_values[lhs_row_id]; - grnxx::Int rhs_value = test.int_values[rhs_row_id]; - assert(lhs_value <= rhs_value); - if (lhs_value == rhs_value) { - assert(lhs_row_id < rhs_row_id); - } - } -} - -struct LessEqual { - bool operator()(grnxx::Float lhs, grnxx::Float rhs) const { - // Numbers are prior to NaN. - if (std::isnan(rhs)) { - return true; - } else if (std::isnan(lhs)) { - return false; - } - return lhs <= rhs; - } -}; - -struct Equal { - bool operator()(grnxx::Float lhs, grnxx::Float rhs) const { - return (lhs == rhs) || (std::isnan(lhs) && std::isnan(rhs)); - } -}; - -void test_float() { - grnxx::Error error; - - // Create a cursor which reads all the records. - auto records = create_input_records(); - - // Create an object for building expressions. - auto expression_builder = - grnxx::ExpressionBuilder::create(&error, test.table); - assert(expression_builder); - - // Create a regular sorter. - grnxx::Array<grnxx::SortOrder> orders; - assert(orders.resize(&error, 1)); - assert(expression_builder->push_column(&error, "Float")); - auto expression = expression_builder->release(&error); - assert(expression); - orders[0].expression = std::move(expression); - orders[0].type = grnxx::REGULAR_ORDER; - auto sorter = grnxx::Sorter::create(&error, std::move(orders)); - - sorter->sort(&error, &records); - for (grnxx::Int i = 1; i < records.size(); ++i) { - grnxx::Int lhs_row_id = records.get_row_id(i - 1); - grnxx::Int rhs_row_id = records.get_row_id(i); - grnxx::Float lhs_value = test.float_values[lhs_row_id]; - grnxx::Float rhs_value = test.float_values[rhs_row_id]; - assert(LessEqual()(lhs_value, rhs_value)); - } - - // Create a reverse sorter. - assert(orders.resize(&error, 1)); - assert(expression_builder->push_column(&error, "Float")); - expression = expression_builder->release(&error); - assert(expression); - orders[0].expression = std::move(expression); - orders[0].type = grnxx::REVERSE_ORDER; - sorter = grnxx::Sorter::create(&error, std::move(orders)); - - sorter->sort(&error, &records); - for (grnxx::Int i = 1; i < records.size(); ++i) { - grnxx::Int lhs_row_id = records.get_row_id(i - 1); - grnxx::Int rhs_row_id = records.get_row_id(i); - grnxx::Float lhs_value = test.float_values[lhs_row_id]; - grnxx::Float rhs_value = test.float_values[rhs_row_id]; - assert(LessEqual()(rhs_value, lhs_value)); - } - - // Create a multiple order sorter. - assert(orders.resize(&error, 2)); - assert(expression_builder->push_column(&error, "Float")); - expression = expression_builder->release(&error); - assert(expression); - orders[0].expression = std::move(expression); - orders[0].type = grnxx::REGULAR_ORDER; - assert(expression_builder->push_row_id(&error)); - expression = expression_builder->release(&error); - assert(expression); - orders[1].expression = std::move(expression); - orders[1].type = grnxx::REGULAR_ORDER; - sorter = grnxx::Sorter::create(&error, std::move(orders)); - - sorter->sort(&error, &records); - for (grnxx::Int i = 1; i < records.size(); ++i) { - grnxx::Int lhs_row_id = records.get_row_id(i - 1); - grnxx::Int rhs_row_id = records.get_row_id(i); - grnxx::Float lhs_value = test.float_values[lhs_row_id]; - grnxx::Float rhs_value = test.float_values[rhs_row_id]; - assert(LessEqual()(lhs_value, rhs_value)); - if (Equal()(lhs_value, rhs_value)) { - assert(lhs_row_id < rhs_row_id); + if (lhs_value.is_false()) { + assert(rhs_value.is_false() || rhs_value.is_na()); + } else if (lhs_value.is_na()) { + assert(rhs_value.is_na()); } } -} - -void test_text() { - grnxx::Error error; - - // Create a cursor which reads all the records. - auto records = create_input_records(); - - // Create an object for building expressions. - auto expression_builder = - grnxx::ExpressionBuilder::create(&error, test.table); - assert(expression_builder); - - // Create a regular sorter. - grnxx::Array<grnxx::SortOrder> orders; - assert(orders.resize(&error, 1)); - assert(expression_builder->push_column(&error, "Text")); - auto expression = expression_builder->release(&error); - assert(expression); - orders[0].expression = std::move(expression); - orders[0].type = grnxx::REGULAR_ORDER; - auto sorter = grnxx::Sorter::create(&error, std::move(orders)); - - sorter->sort(&error, &records); - for (grnxx::Int i = 1; i < records.size(); ++i) { - grnxx::Int lhs_row_id = records.get_row_id(i - 1); - grnxx::Int rhs_row_id = records.get_row_id(i); - grnxx::Text lhs_value = test.text_values[lhs_row_id]; - grnxx::Text rhs_value = test.text_values[rhs_row_id]; - assert(lhs_value <= rhs_value); - } - - // Create a reverse sorter. - assert(orders.resize(&error, 1)); - assert(expression_builder->push_column(&error, "Text")); - expression = expression_builder->release(&error); - assert(expression); - orders[0].expression = std::move(expression); - orders[0].type = grnxx::REVERSE_ORDER; - sorter = grnxx::Sorter::create(&error, std::move(orders)); - - sorter->sort(&error, &records); - for (grnxx::Int i = 1; i < records.size(); ++i) { - grnxx::Int lhs_row_id = records.get_row_id(i - 1); - grnxx::Int rhs_row_id = records.get_row_id(i); - grnxx::Text lhs_value = test.text_values[lhs_row_id]; - grnxx::Text rhs_value = test.text_values[rhs_row_id]; - assert(lhs_value >= rhs_value); - } - // Create a multiple order sorter. - assert(orders.resize(&error, 2)); - assert(expression_builder->push_column(&error, "Text")); - expression = expression_builder->release(&error); - assert(expression); - orders[0].expression = std::move(expression); - orders[0].type = grnxx::REGULAR_ORDER; - assert(expression_builder->push_row_id(&error)); - expression = expression_builder->release(&error); - assert(expression); - orders[1].expression = std::move(expression); - orders[1].type = grnxx::REGULAR_ORDER; - sorter = grnxx::Sorter::create(&error, std::move(orders)); - - sorter->sort(&error, &records); - for (grnxx::Int i = 1; i < records.size(); ++i) { - grnxx::Int lhs_row_id = records.get_row_id(i - 1); - grnxx::Int rhs_row_id = records.get_row_id(i); - grnxx::Text lhs_value = test.text_values[lhs_row_id]; - grnxx::Text rhs_value = test.text_values[rhs_row_id]; - assert(lhs_value <= rhs_value); - if (lhs_value == rhs_value) { - assert(lhs_row_id < rhs_row_id); - } - } +// // Create a multiple order sorter. +// assert(orders.resize(&error, 2)); +// assert(expression_builder->push_column(&error, "Bool")); +// expression = expression_builder->release(&error); +// assert(expression); +// orders[0].expression = std::move(expression); +// orders[0].type = grnxx::REGULAR_ORDER; +// assert(expression_builder->push_row_id(&error)); +// expression = expression_builder->release(&error); +// assert(expression); +// orders[1].expression = std::move(expression); +// orders[1].type = grnxx::REGULAR_ORDER; +// sorter = grnxx::Sorter::create(&error, std::move(orders)); + +// sorter->sort(&error, &records); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// grnxx::Int lhs_row_id = records.get_row_id(i - 1); +// grnxx::Int rhs_row_id = records.get_row_id(i); +// grnxx::Bool lhs_value = test.bool_values[lhs_row_id]; +// grnxx::Bool rhs_value = test.bool_values[rhs_row_id]; +// assert(!lhs_value || rhs_value); +// if (lhs_value == rhs_value) { +// assert(lhs_row_id < rhs_row_id); +// } +// } } -void test_composite() { - grnxx::Error error; - - // Create a cursor which reads all the records. - auto records = create_input_records(); - - // Create an object for building expressions. - auto expression_builder = - grnxx::ExpressionBuilder::create(&error, test.table); - assert(expression_builder); - - // Create a composite sorter. - grnxx::Array<grnxx::SortOrder> orders; - assert(orders.resize(&error, 3)); - assert(expression_builder->push_column(&error, "Bool")); - auto expression = expression_builder->release(&error); - assert(expression); - orders[0].expression = std::move(expression); - orders[0].type = grnxx::REGULAR_ORDER; - assert(expression_builder->push_column(&error, "Int")); - expression = expression_builder->release(&error); - assert(expression); - orders[1].expression = std::move(expression); - orders[1].type = grnxx::REVERSE_ORDER; - assert(expression_builder->push_column(&error, "Text")); - expression = expression_builder->release(&error); - assert(expression); - orders[2].expression = std::move(expression); - orders[2].type = grnxx::REGULAR_ORDER; - auto sorter = grnxx::Sorter::create(&error, std::move(orders)); - - sorter->sort(&error, &records); - for (grnxx::Int i = 1; i < records.size(); ++i) { - grnxx::Int lhs_row_id = records.get_row_id(i - 1); - grnxx::Int rhs_row_id = records.get_row_id(i); - grnxx::Bool lhs_value = test.bool_values[lhs_row_id]; - grnxx::Bool rhs_value = test.bool_values[rhs_row_id]; - assert(!lhs_value || rhs_value); - if (lhs_value == rhs_value) { - grnxx::Int lhs_value = test.int_values[lhs_row_id]; - grnxx::Int rhs_value = test.int_values[rhs_row_id]; - assert(lhs_value >= rhs_value); - if (lhs_value == rhs_value) { - grnxx::Text lhs_value = test.text_values[lhs_row_id]; - grnxx::Text rhs_value = test.text_values[rhs_row_id]; - assert(lhs_value <= rhs_value); - } - } - } -} +//void test_int() { +// grnxx::Error error; + +// // Create a cursor which reads all the records. +// auto records = create_input_records(); + +// // Create an object for building expressions. +// auto expression_builder = +// grnxx::ExpressionBuilder::create(&error, test.table); +// assert(expression_builder); + +// // Create a regular sorter. +// grnxx::Array<grnxx::SortOrder> orders; +// assert(orders.resize(&error, 1)); +// assert(expression_builder->push_column(&error, "Int")); +// auto expression = expression_builder->release(&error); +// assert(expression); +// orders[0].expression = std::move(expression); +// orders[0].type = grnxx::REGULAR_ORDER; +// auto sorter = grnxx::Sorter::create(&error, std::move(orders)); + +// sorter->sort(&error, &records); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// grnxx::Int lhs_row_id = records.get_row_id(i - 1); +// grnxx::Int rhs_row_id = records.get_row_id(i); +// grnxx::Int lhs_value = test.int_values[lhs_row_id]; +// grnxx::Int rhs_value = test.int_values[rhs_row_id]; +// assert(lhs_value <= rhs_value); +// } + +// // Create a reverse sorter. +// assert(orders.resize(&error, 1)); +// assert(expression_builder->push_column(&error, "Int")); +// expression = expression_builder->release(&error); +// assert(expression); +// orders[0].expression = std::move(expression); +// orders[0].type = grnxx::REVERSE_ORDER; +// sorter = grnxx::Sorter::create(&error, std::move(orders)); + +// sorter->sort(&error, &records); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// grnxx::Int lhs_row_id = records.get_row_id(i - 1); +// grnxx::Int rhs_row_id = records.get_row_id(i); +// grnxx::Int lhs_value = test.int_values[lhs_row_id]; +// grnxx::Int rhs_value = test.int_values[rhs_row_id]; +// assert(lhs_value >= rhs_value); +// } + +// // Create a multiple order sorter. +// assert(orders.resize(&error, 2)); +// assert(expression_builder->push_column(&error, "Int")); +// expression = expression_builder->release(&error); +// assert(expression); +// orders[0].expression = std::move(expression); +// orders[0].type = grnxx::REGULAR_ORDER; +// assert(expression_builder->push_row_id(&error)); +// expression = expression_builder->release(&error); +// assert(expression); +// orders[1].expression = std::move(expression); +// orders[1].type = grnxx::REGULAR_ORDER; +// sorter = grnxx::Sorter::create(&error, std::move(orders)); + +// sorter->sort(&error, &records); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// grnxx::Int lhs_row_id = records.get_row_id(i - 1); +// grnxx::Int rhs_row_id = records.get_row_id(i); +// grnxx::Int lhs_value = test.int_values[lhs_row_id]; +// grnxx::Int rhs_value = test.int_values[rhs_row_id]; +// assert(lhs_value <= rhs_value); +// if (lhs_value == rhs_value) { +// assert(lhs_row_id < rhs_row_id); +// } +// } +//} + +//struct LessEqual { +// bool operator()(grnxx::Float lhs, grnxx::Float rhs) const { +// // Numbers are prior to NaN. +// if (std::isnan(rhs)) { +// return true; +// } else if (std::isnan(lhs)) { +// return false; +// } +// return lhs <= rhs; +// } +//}; + +//struct Equal { +// bool operator()(grnxx::Float lhs, grnxx::Float rhs) const { +// return (lhs == rhs) || (std::isnan(lhs) && std::isnan(rhs)); +// } +//}; + +//void test_float() { +// grnxx::Error error; + +// // Create a cursor which reads all the records. +// auto records = create_input_records(); + +// // Create an object for building expressions. +// auto expression_builder = +// grnxx::ExpressionBuilder::create(&error, test.table); +// assert(expression_builder); + +// // Create a regular sorter. +// grnxx::Array<grnxx::SortOrder> orders; +// assert(orders.resize(&error, 1)); +// assert(expression_builder->push_column(&error, "Float")); +// auto expression = expression_builder->release(&error); +// assert(expression); +// orders[0].expression = std::move(expression); +// orders[0].type = grnxx::REGULAR_ORDER; +// auto sorter = grnxx::Sorter::create(&error, std::move(orders)); + +// sorter->sort(&error, &records); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// grnxx::Int lhs_row_id = records.get_row_id(i - 1); +// grnxx::Int rhs_row_id = records.get_row_id(i); +// grnxx::Float lhs_value = test.float_values[lhs_row_id]; +// grnxx::Float rhs_value = test.float_values[rhs_row_id]; +// assert(LessEqual()(lhs_value, rhs_value)); +// } + +// // Create a reverse sorter. +// assert(orders.resize(&error, 1)); +// assert(expression_builder->push_column(&error, "Float")); +// expression = expression_builder->release(&error); +// assert(expression); +// orders[0].expression = std::move(expression); +// orders[0].type = grnxx::REVERSE_ORDER; +// sorter = grnxx::Sorter::create(&error, std::move(orders)); + +// sorter->sort(&error, &records); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// grnxx::Int lhs_row_id = records.get_row_id(i - 1); +// grnxx::Int rhs_row_id = records.get_row_id(i); +// grnxx::Float lhs_value = test.float_values[lhs_row_id]; +// grnxx::Float rhs_value = test.float_values[rhs_row_id]; +// assert(LessEqual()(rhs_value, lhs_value)); +// } + +// // Create a multiple order sorter. +// assert(orders.resize(&error, 2)); +// assert(expression_builder->push_column(&error, "Float")); +// expression = expression_builder->release(&error); +// assert(expression); +// orders[0].expression = std::move(expression); +// orders[0].type = grnxx::REGULAR_ORDER; +// assert(expression_builder->push_row_id(&error)); +// expression = expression_builder->release(&error); +// assert(expression); +// orders[1].expression = std::move(expression); +// orders[1].type = grnxx::REGULAR_ORDER; +// sorter = grnxx::Sorter::create(&error, std::move(orders)); + +// sorter->sort(&error, &records); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// grnxx::Int lhs_row_id = records.get_row_id(i - 1); +// grnxx::Int rhs_row_id = records.get_row_id(i); +// grnxx::Float lhs_value = test.float_values[lhs_row_id]; +// grnxx::Float rhs_value = test.float_values[rhs_row_id]; +// assert(LessEqual()(lhs_value, rhs_value)); +// if (Equal()(lhs_value, rhs_value)) { +// assert(lhs_row_id < rhs_row_id); +// } +// } +//} + +//void test_text() { +// grnxx::Error error; + +// // Create a cursor which reads all the records. +// auto records = create_input_records(); + +// // Create an object for building expressions. +// auto expression_builder = +// grnxx::ExpressionBuilder::create(&error, test.table); +// assert(expression_builder); + +// // Create a regular sorter. +// grnxx::Array<grnxx::SortOrder> orders; +// assert(orders.resize(&error, 1)); +// assert(expression_builder->push_column(&error, "Text")); +// auto expression = expression_builder->release(&error); +// assert(expression); +// orders[0].expression = std::move(expression); +// orders[0].type = grnxx::REGULAR_ORDER; +// auto sorter = grnxx::Sorter::create(&error, std::move(orders)); + +// sorter->sort(&error, &records); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// grnxx::Int lhs_row_id = records.get_row_id(i - 1); +// grnxx::Int rhs_row_id = records.get_row_id(i); +// grnxx::Text lhs_value = test.text_values[lhs_row_id]; +// grnxx::Text rhs_value = test.text_values[rhs_row_id]; +// assert(lhs_value <= rhs_value); +// } + +// // Create a reverse sorter. +// assert(orders.resize(&error, 1)); +// assert(expression_builder->push_column(&error, "Text")); +// expression = expression_builder->release(&error); +// assert(expression); +// orders[0].expression = std::move(expression); +// orders[0].type = grnxx::REVERSE_ORDER; +// sorter = grnxx::Sorter::create(&error, std::move(orders)); + +// sorter->sort(&error, &records); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// grnxx::Int lhs_row_id = records.get_row_id(i - 1); +// grnxx::Int rhs_row_id = records.get_row_id(i); +// grnxx::Text lhs_value = test.text_values[lhs_row_id]; +// grnxx::Text rhs_value = test.text_values[rhs_row_id]; +// assert(lhs_value >= rhs_value); +// } + +// // Create a multiple order sorter. +// assert(orders.resize(&error, 2)); +// assert(expression_builder->push_column(&error, "Text")); +// expression = expression_builder->release(&error); +// assert(expression); +// orders[0].expression = std::move(expression); +// orders[0].type = grnxx::REGULAR_ORDER; +// assert(expression_builder->push_row_id(&error)); +// expression = expression_builder->release(&error); +// assert(expression); +// orders[1].expression = std::move(expression); +// orders[1].type = grnxx::REGULAR_ORDER; +// sorter = grnxx::Sorter::create(&error, std::move(orders)); + +// sorter->sort(&error, &records); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// grnxx::Int lhs_row_id = records.get_row_id(i - 1); +// grnxx::Int rhs_row_id = records.get_row_id(i); +// grnxx::Text lhs_value = test.text_values[lhs_row_id]; +// grnxx::Text rhs_value = test.text_values[rhs_row_id]; +// assert(lhs_value <= rhs_value); +// if (lhs_value == rhs_value) { +// assert(lhs_row_id < rhs_row_id); +// } +// } +//} + +//void test_composite() { +// grnxx::Error error; + +// // Create a cursor which reads all the records. +// auto records = create_input_records(); + +// // Create an object for building expressions. +// auto expression_builder = +// grnxx::ExpressionBuilder::create(&error, test.table); +// assert(expression_builder); + +// // Create a composite sorter. +// grnxx::Array<grnxx::SortOrder> orders; +// assert(orders.resize(&error, 3)); +// assert(expression_builder->push_column(&error, "Bool")); +// auto expression = expression_builder->release(&error); +// assert(expression); +// orders[0].expression = std::move(expression); +// orders[0].type = grnxx::REGULAR_ORDER; +// assert(expression_builder->push_column(&error, "Int")); +// expression = expression_builder->release(&error); +// assert(expression); +// orders[1].expression = std::move(expression); +// orders[1].type = grnxx::REVERSE_ORDER; +// assert(expression_builder->push_column(&error, "Text")); +// expression = expression_builder->release(&error); +// assert(expression); +// orders[2].expression = std::move(expression); +// orders[2].type = grnxx::REGULAR_ORDER; +// auto sorter = grnxx::Sorter::create(&error, std::move(orders)); + +// sorter->sort(&error, &records); +// for (grnxx::Int i = 1; i < records.size(); ++i) { +// grnxx::Int lhs_row_id = records.get_row_id(i - 1); +// grnxx::Int rhs_row_id = records.get_row_id(i); +// grnxx::Bool lhs_value = test.bool_values[lhs_row_id]; +// grnxx::Bool rhs_value = test.bool_values[rhs_row_id]; +// assert(!lhs_value || rhs_value); +// if (lhs_value == rhs_value) { +// grnxx::Int lhs_value = test.int_values[lhs_row_id]; +// grnxx::Int rhs_value = test.int_values[rhs_row_id]; +// assert(lhs_value >= rhs_value); +// if (lhs_value == rhs_value) { +// grnxx::Text lhs_value = test.text_values[lhs_row_id]; +// grnxx::Text rhs_value = test.text_values[rhs_row_id]; +// assert(lhs_value <= rhs_value); +// } +// } +// } +//} int main() { init_test(); test_bool(); - test_int(); - test_float(); - test_text(); - test_composite(); +// test_int(); +// test_float(); +// test_text(); +// test_composite(); return 0; } -------------- next part -------------- HTML����������������������������... 下載