[Groonga-commit] groonga/grnxx at 16eae6a [master] Add tests for composite sorting. (#42)

Back to archive index

susumu.yata null+****@clear*****
Mon Dec 15 16:48:50 JST 2014


susumu.yata	2014-12-15 16:48:50 +0900 (Mon, 15 Dec 2014)

  New Revision: 16eae6a58e0d10ac7fa7b099e361c1888ac7b010
  https://github.com/groonga/grnxx/commit/16eae6a58e0d10ac7fa7b099e361c1888ac7b010

  Message:
    Add tests for composite sorting. (#42)

  Modified files:
    test/test_sorter.cpp

  Modified: test/test_sorter.cpp (+174 -119)
===================================================================
--- test/test_sorter.cpp    2014-12-15 16:08:24 +0900 (49f73f1)
+++ test/test_sorter.cpp    2014-12-15 16:48:50 +0900 (aa489dd)
@@ -28,16 +28,6 @@
 #include "grnxx/table.hpp"
 #include "grnxx/sorter.hpp"
 
-struct {
-  std::unique_ptr<grnxx::DB> db;
-  grnxx::Table *table;
-  grnxx::Array<grnxx::Bool> bool_values;
-  grnxx::Array<grnxx::Int> int_values;
-  grnxx::Array<grnxx::Float> float_values;
-  grnxx::Array<grnxx::Text> text_values;
-  grnxx::Array<std::string> text_bodies;
-} test;
-
 constexpr size_t NUM_ROWS = 1 << 16;
 
 std::mt19937_64 rng;
@@ -82,63 +72,7 @@ void generate_value(grnxx::Text *value) {
   }
 }
 
-// TODO: To be removed.
-void init_test() {
-  // Create columns for various data types.
-  test.db = grnxx::open_db("");
-  test.table = test.db->create_table("Table");
-  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, false, and N/A.
-  // Int: [-128, 128) and N/A.
-  // Float: [-1.0, 1.0) and N/A.
-  // Text: length = [1, 4], byte = ['0', '9'], and N/A.
-  std::mt19937_64 mersenne_twister;
-  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) {
-    generate_value(&test.bool_values[i]);
-    generate_value(&test.int_values[i]);
-    generate_value(&test.float_values[i]);
-    generate_value(&test.text_values[i]);
-  }
-
-  // Store generated values into columns.
-  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]);
-  }
-}
-
-// TODO: To be removed.
-grnxx::Array<grnxx::Record> create_input_records() {
-  auto cursor = test.table->create_cursor();
-
-  grnxx::Array<grnxx::Record> records;
-  size_t count = cursor->read_all(&records);
-  assert(count == test.table->num_rows());
-
-  return records;
-}
-
-// TODO: To be removed.
-void shuffle_records(grnxx::Array<grnxx::Record> *records) {
-  std::shuffle(records->buffer(), records->buffer() + records->size(),
-               std::mt19937_64());
-}
-
-// TODO: To be renamed.
-grnxx::Array<grnxx::Record> get_records(grnxx::Table *table) {
+grnxx::Array<grnxx::Record> create_records(grnxx::Table *table) {
   auto cursor = table->create_cursor();
   grnxx::Array<grnxx::Record> records;
   assert(cursor->read_all(&records) == NUM_ROWS);
@@ -147,11 +81,10 @@ grnxx::Array<grnxx::Record> get_records(grnxx::Table *table) {
   return records;
 }
 
-// TODO: To be renamed.
-grnxx::Array<grnxx::Record> get_records(
+grnxx::Array<grnxx::Record> create_records(
     grnxx::Table *table,
     const std::vector<grnxx::Float> &scores) {
-  auto records = get_records(table);
+  auto records = create_records(table);
   for (size_t i = 0; i < NUM_ROWS; ++i) {
     records[i].score = scores[i];
   }
@@ -212,7 +145,7 @@ void test_row_id() {
   orders[0].expression = expression_builder->release();
   orders[0].type = grnxx::SORTER_REGULAR_ORDER;
   auto sorter = grnxx::Sorter::create(std::move(orders));
-  auto records = get_records(table);
+  auto records = create_records(table);
   sorter->sort(&records);
   for (size_t i = 0; i < records.size(); ++i) {
     assert(records[i].row_id.raw() == static_cast<int64_t>(i));
@@ -224,7 +157,7 @@ void test_row_id() {
   orders[0].expression = expression_builder->release();
   orders[0].type = grnxx::SORTER_REVERSE_ORDER;
   sorter = grnxx::Sorter::create(std::move(orders));
-  records = get_records(table);
+  records = create_records(table);
   sorter->sort(&records);
   for (size_t i = 0; i < records.size(); ++i) {
     assert(records[i].row_id.raw() == static_cast<int64_t>(NUM_ROWS - i - 1));
@@ -238,7 +171,7 @@ void test_row_id() {
   grnxx::SorterOptions options;
   options.limit = 100;
   sorter = grnxx::Sorter::create(std::move(orders), options);
-  records = get_records(table);
+  records = create_records(table);
   sorter->sort(&records);
   assert(records.size() == options.limit);
   for (size_t i = 0; i < records.size(); ++i) {
@@ -252,7 +185,7 @@ void test_row_id() {
   orders[0].type = grnxx::SORTER_REVERSE_ORDER;
   options.limit = 100;
   sorter = grnxx::Sorter::create(std::move(orders), options);
-  records = get_records(table);
+  records = create_records(table);
   sorter->sort(&records);
   assert(records.size() == options.limit);
   for (size_t i = 0; i < records.size(); ++i) {
@@ -267,7 +200,7 @@ void test_row_id() {
   options.offset = 100;
   options.limit = 100;
   sorter = grnxx::Sorter::create(std::move(orders), options);
-  records = get_records(table);
+  records = create_records(table);
   sorter->sort(&records);
   assert(records.size() == options.limit);
   for (size_t i = 0; i < records.size(); ++i) {
@@ -301,7 +234,7 @@ void test_score() {
   orders[0].expression = expression_builder->release();
   orders[0].type = grnxx::SORTER_REGULAR_ORDER;
   auto sorter = grnxx::Sorter::create(std::move(orders));
-  auto records = get_records(table, scores);
+  auto records = create_records(table, scores);
   sorter->sort(&records);
   for (size_t i = 0; i < records.size(); ++i) {
     assert(records[i].score.match(regular_scores[i]));
@@ -313,7 +246,7 @@ void test_score() {
   orders[0].expression = expression_builder->release();
   orders[0].type = grnxx::SORTER_REVERSE_ORDER;
   sorter = grnxx::Sorter::create(std::move(orders));
-  records = get_records(table, scores);
+  records = create_records(table, scores);
   sorter->sort(&records);
   for (size_t i = 0; i < records.size(); ++i) {
     assert(records[i].score.match(reverse_scores[i]));
@@ -327,7 +260,7 @@ void test_score() {
   grnxx::SorterOptions options;
   options.limit = 100;
   sorter = grnxx::Sorter::create(std::move(orders), options);
-  records = get_records(table, scores);
+  records = create_records(table, scores);
   sorter->sort(&records);
   assert(records.size() == options.limit);
   for (size_t i = 0; i < records.size(); ++i) {
@@ -341,7 +274,7 @@ void test_score() {
   orders[0].type = grnxx::SORTER_REVERSE_ORDER;
   options.limit = 100;
   sorter = grnxx::Sorter::create(std::move(orders), options);
-  records = get_records(table, scores);
+  records = create_records(table, scores);
   sorter->sort(&records);
   assert(records.size() == options.limit);
   for (size_t i = 0; i < records.size(); ++i) {
@@ -356,7 +289,7 @@ void test_score() {
   options.offset = 100;
   options.limit = 100;
   sorter = grnxx::Sorter::create(std::move(orders), options);
-  records = get_records(table, scores);
+  records = create_records(table, scores);
   sorter->sort(&records);
   assert(records.size() == options.limit);
   for (size_t i = 0; i < records.size(); ++i) {
@@ -393,7 +326,7 @@ void test_value() {
   orders[0].expression = expression_builder->release();
   orders[0].type = grnxx::SORTER_REGULAR_ORDER;
   auto sorter = grnxx::Sorter::create(std::move(orders));
-  auto records = get_records(table);
+  auto records = create_records(table);
   sorter->sort(&records);
   for (size_t i = 0; i < records.size(); ++i) {
     size_t row_id = records[i].row_id.raw();
@@ -406,7 +339,7 @@ void test_value() {
   orders[0].expression = expression_builder->release();
   orders[0].type = grnxx::SORTER_REVERSE_ORDER;
   sorter = grnxx::Sorter::create(std::move(orders));
-  records = get_records(table);
+  records = create_records(table);
   sorter->sort(&records);
   for (size_t i = 0; i < records.size(); ++i) {
     size_t row_id = records[i].row_id.raw();
@@ -421,7 +354,7 @@ void test_value() {
   grnxx::SorterOptions options;
   options.limit = 100;
   sorter = grnxx::Sorter::create(std::move(orders), options);
-  records = get_records(table);
+  records = create_records(table);
   sorter->sort(&records);
   assert(records.size() == options.limit);
   for (size_t i = 0; i < records.size(); ++i) {
@@ -436,7 +369,7 @@ void test_value() {
   orders[0].type = grnxx::SORTER_REVERSE_ORDER;
   options.limit = 100;
   sorter = grnxx::Sorter::create(std::move(orders), options);
-  records = get_records(table);
+  records = create_records(table);
   sorter->sort(&records);
   assert(records.size() == options.limit);
   for (size_t i = 0; i < records.size(); ++i) {
@@ -452,7 +385,7 @@ void test_value() {
   options.offset = 100;
   options.limit = 100;
   sorter = grnxx::Sorter::create(std::move(orders), options);
-  records = get_records(table);
+  records = create_records(table);
   sorter->sort(&records);
   assert(records.size() == options.limit);
   for (size_t i = 0; i < records.size(); ++i) {
@@ -462,56 +395,179 @@ void test_value() {
 }
 
 void test_composite() {
-  // Create a cursor which reads all the records.
-  auto records = create_input_records();
+  // Create a table.
+  auto db = grnxx::open_db("");
+  auto table = db->create_table("Table");
+  auto bool_column = table->create_column("Bool", grnxx::BOOL_DATA);
+  auto int_column = table->create_column("Int", grnxx::INT_DATA);
+  auto float_column = table->create_column("Float", grnxx::FLOAT_DATA);
+  auto text_column = table->create_column("Text", grnxx::TEXT_DATA);
+  for (size_t i = 0; i < NUM_ROWS; ++i) {
+    table->insert_row();
+  }
 
-  // Create an object for building expressions.
-  auto expression_builder = grnxx::ExpressionBuilder::create(test.table);
+  // Generate values.
+  std::vector<grnxx::Bool> bool_values(NUM_ROWS);
+  std::vector<grnxx::Float> float_values(NUM_ROWS);
+  std::vector<grnxx::Int> int_values(NUM_ROWS);
+  std::vector<grnxx::Text> text_values(NUM_ROWS);
+  for (size_t i = 0; i < NUM_ROWS; ++i) {
+    generate_value(&bool_values[i]);
+    generate_value(&int_values[i]);
+    generate_value(&float_values[i]);
+    generate_value(&text_values[i]);
+    bool_column->set(grnxx::Int(i), bool_values[i]);
+    int_column->set(grnxx::Int(i), int_values[i]);
+    float_column->set(grnxx::Int(i), float_values[i]);
+    text_column->set(grnxx::Int(i), text_values[i]);
+  }
 
-  // Create a composite sorter.
+  // Test a regular sorter (Bool, Int, Float).
   grnxx::Array<grnxx::SorterOrder> orders;
   orders.resize(3);
+  auto expression_builder = grnxx::ExpressionBuilder::create(table);
   expression_builder->push_column("Bool");
-  auto expression = expression_builder->release();
-  assert(expression);
-  orders[0].expression = std::move(expression);
+  orders[0].expression = expression_builder->release();
   orders[0].type = grnxx::SORTER_REGULAR_ORDER;
   expression_builder->push_column("Int");
-  expression = expression_builder->release();
-  orders[1].expression = std::move(expression);
-  orders[1].type = grnxx::SORTER_REVERSE_ORDER;
-  expression_builder->push_column("Text");
-  expression = expression_builder->release();
-  orders[2].expression = std::move(expression);
+  orders[1].expression = expression_builder->release();
+  orders[1].type = grnxx::SORTER_REGULAR_ORDER;
+  expression_builder->push_column("Float");
+  orders[2].expression = expression_builder->release();
   orders[2].type = grnxx::SORTER_REGULAR_ORDER;
   auto sorter = grnxx::Sorter::create(std::move(orders));
+  auto records = create_records(table);
+  sorter->sort(&records);
+  for (size_t i = 1; i < records.size(); ++i) {
+    size_t lhs_row_id = records[i - 1].row_id.raw();
+    size_t rhs_row_id = records[i].row_id.raw();
+    auto lhs_value = bool_values[lhs_row_id];
+    auto rhs_value = bool_values[rhs_row_id];
+    if (lhs_value.unmatch(rhs_value)) {
+      assert(RegularComparer()(lhs_value, rhs_value));
+    } else {
+      auto lhs_value = int_values[lhs_row_id];
+      auto rhs_value = int_values[rhs_row_id];
+      if (lhs_value.unmatch(rhs_value)) {
+        assert(RegularComparer()(lhs_value, rhs_value));
+      } else {
+        auto lhs_value = float_values[lhs_row_id];
+        auto rhs_value = float_values[rhs_row_id];
+        if (lhs_value.unmatch(rhs_value)) {
+          assert(RegularComparer()(lhs_value, rhs_value));
+        }
+      }
+    }
+  }
 
+  // Test a reverse sorter (Int, Float, Bool).
+  orders.resize(3);
+  expression_builder->push_column("Int");
+  orders[0].expression = expression_builder->release();
+  orders[0].type = grnxx::SORTER_REVERSE_ORDER;
+  expression_builder->push_column("Float");
+  orders[1].expression = expression_builder->release();
+  orders[1].type = grnxx::SORTER_REVERSE_ORDER;
+  expression_builder->push_column("Bool");
+  orders[2].expression = expression_builder->release();
+  orders[2].type = grnxx::SORTER_REVERSE_ORDER;
+  sorter = grnxx::Sorter::create(std::move(orders));
+  records = create_records(table);
   sorter->sort(&records);
   for (size_t i = 1; i < records.size(); ++i) {
     size_t lhs_row_id = records[i - 1].row_id.raw();
     size_t rhs_row_id = records[i].row_id.raw();
-    grnxx::Bool lhs_value = test.bool_values[lhs_row_id];
-    grnxx::Bool rhs_value = test.bool_values[rhs_row_id];
-    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());
+    auto lhs_value = int_values[lhs_row_id];
+    auto rhs_value = int_values[rhs_row_id];
+    if (lhs_value.unmatch(rhs_value)) {
+      assert(ReverseComparer()(lhs_value, rhs_value));
+    } else {
+      auto lhs_value = float_values[lhs_row_id];
+      auto rhs_value = float_values[rhs_row_id];
+      if (lhs_value.unmatch(rhs_value)) {
+        assert(ReverseComparer()(lhs_value, rhs_value));
+      } else {
+        auto lhs_value = bool_values[lhs_row_id];
+        auto rhs_value = bool_values[rhs_row_id];
+        if (lhs_value.unmatch(rhs_value)) {
+          assert(ReverseComparer()(lhs_value, rhs_value));
+        }
+      }
     }
-    if (lhs_value.match(rhs_value)) {
-      grnxx::Int lhs_value = test.int_values[lhs_row_id];
-      grnxx::Int rhs_value = test.int_values[rhs_row_id];
-      if (lhs_value.is_na()) {
-        assert(rhs_value.is_na());
+  }
+
+  // Test a regular sorter (Text, Bool, Int) with limit.
+  orders.resize(3);
+  expression_builder->push_column("Text");
+  orders[0].expression = expression_builder->release();
+  orders[0].type = grnxx::SORTER_REGULAR_ORDER;
+  expression_builder->push_column("Bool");
+  orders[1].expression = expression_builder->release();
+  orders[1].type = grnxx::SORTER_REGULAR_ORDER;
+  expression_builder->push_column("Int");
+  orders[2].expression = expression_builder->release();
+  orders[2].type = grnxx::SORTER_REGULAR_ORDER;
+  grnxx::SorterOptions options;
+  options.limit = 100;
+  sorter = grnxx::Sorter::create(std::move(orders), options);
+  records = create_records(table);
+  sorter->sort(&records);
+  assert(records.size() == options.limit);
+  for (size_t i = 1; i < records.size(); ++i) {
+    size_t lhs_row_id = records[i - 1].row_id.raw();
+    size_t rhs_row_id = records[i].row_id.raw();
+    auto lhs_value = text_values[lhs_row_id];
+    auto rhs_value = text_values[rhs_row_id];
+    if (lhs_value.unmatch(rhs_value)) {
+      assert(RegularComparer()(lhs_value, rhs_value));
+    } else {
+      auto lhs_value = bool_values[lhs_row_id];
+      auto rhs_value = bool_values[rhs_row_id];
+      if (lhs_value.unmatch(rhs_value)) {
+        assert(RegularComparer()(lhs_value, rhs_value));
       } else {
-        assert(rhs_value.is_na() || (lhs_value >= rhs_value).is_true());
+        auto lhs_value = int_values[lhs_row_id];
+        auto rhs_value = int_values[rhs_row_id];
+        if (lhs_value.unmatch(rhs_value)) {
+          assert(RegularComparer()(lhs_value, rhs_value));
+        }
       }
-      if (lhs_value.match(rhs_value)) {
-        grnxx::Text lhs_value = test.text_values[lhs_row_id];
-        grnxx::Text rhs_value = test.text_values[rhs_row_id];
-        if (lhs_value.is_na()) {
-          assert(rhs_value.is_na());
-        } else {
-          assert(rhs_value.is_na() || (lhs_value <= rhs_value).is_true());
+    }
+  }
+
+  // Test a reverse sorter (Text, Bool, Int) with limit.
+  orders.resize(3);
+  expression_builder->push_column("Bool");
+  orders[0].expression = expression_builder->release();
+  orders[0].type = grnxx::SORTER_REVERSE_ORDER;
+  expression_builder->push_column("Text");
+  orders[1].expression = expression_builder->release();
+  orders[1].type = grnxx::SORTER_REVERSE_ORDER;
+  expression_builder->push_column("Float");
+  orders[2].expression = expression_builder->release();
+  orders[2].type = grnxx::SORTER_REVERSE_ORDER;
+  options.limit = 100;
+  sorter = grnxx::Sorter::create(std::move(orders), options);
+  records = create_records(table);
+  sorter->sort(&records);
+  assert(records.size() == options.limit);
+  for (size_t i = 1; i < records.size(); ++i) {
+    size_t lhs_row_id = records[i - 1].row_id.raw();
+    size_t rhs_row_id = records[i].row_id.raw();
+    auto lhs_value = bool_values[lhs_row_id];
+    auto rhs_value = bool_values[rhs_row_id];
+    if (lhs_value.unmatch(rhs_value)) {
+      assert(ReverseComparer()(lhs_value, rhs_value));
+    } else {
+      auto lhs_value = text_values[lhs_row_id];
+      auto rhs_value = text_values[rhs_row_id];
+      if (lhs_value.unmatch(rhs_value)) {
+        assert(ReverseComparer()(lhs_value, rhs_value));
+      } else {
+        auto lhs_value = float_values[lhs_row_id];
+        auto rhs_value = float_values[rhs_row_id];
+        if (lhs_value.unmatch(rhs_value)) {
+          assert(ReverseComparer()(lhs_value, rhs_value));
         }
       }
     }
@@ -519,7 +575,6 @@ void test_composite() {
 }
 
 int main() {
-  init_test();
   test_row_id();
   test_score();
   test_value<grnxx::Bool>();
-------------- next part --------------
HTML����������������������������...
下载 



More information about the Groonga-commit mailing list
Back to archive index