[Groonga-commit] groonga/grnxx at dd4619c [new_data_types] Enable comparison operators. (#106)

Back to archive index

susumu.yata null+****@clear*****
Thu Nov 13 21:49:25 JST 2014


susumu.yata	2014-11-13 21:49:25 +0900 (Thu, 13 Nov 2014)

  New Revision: dd4619cbf89078cad3f4aa3b4fa091cdf879fcfe
  https://github.com/groonga/grnxx/commit/dd4619cbf89078cad3f4aa3b4fa091cdf879fcfe

  Message:
    Enable comparison operators. (#106)

  Modified files:
    lib/grnxx/impl/expression.cpp
    lib/grnxx/impl/expression.hpp

  Modified: lib/grnxx/impl/expression.cpp (+253 -24)
===================================================================
--- lib/grnxx/impl/expression.cpp    2014-11-13 20:58:43 +0900 (4d1b9ee)
+++ lib/grnxx/impl/expression.cpp    2014-11-13 21:49:25 +0900 (a89e074)
@@ -889,6 +889,149 @@ void LogicalOrNode::evaluate(ArrayCRef<Record> records,
   }
 }
 
+// ---- ComparisonNode ----
+
+template <typename T>
+class ComparisonNode
+    : public BinaryNode<Bool, typename T::Arg, typename T::Arg> {
+ public:
+  using Comparer = T;
+  using Value = Bool;
+  using Arg1 = typename T::Arg;
+  using Arg2 = typename T::Arg;
+
+  ComparisonNode(std::unique_ptr<Node> &&arg1, std::unique_ptr<Node> &&arg2)
+      : BinaryNode<Value, Arg1, Arg2>(std::move(arg1), std::move(arg2)),
+        comparer_() {}
+  ~ComparisonNode() = default;
+
+  void filter(ArrayCRef<Record> input_records,
+              ArrayRef<Record> *output_records);
+  void evaluate(ArrayCRef<Record> records, ArrayRef<Value> results);
+
+ protected:
+  Comparer comparer_;
+};
+
+template <typename T>
+void ComparisonNode<T>::filter(ArrayCRef<Record> input_records,
+                               ArrayRef<Record> *output_records) {
+  this->fill_arg1_values(input_records);
+  this->fill_arg2_values(input_records);
+  size_t count = 0;
+  for (size_t i = 0; i < input_records.size(); ++i) {
+    if (comparer_(this->arg1_values_[i], this->arg2_values_[i]).is_true()) {
+      (*output_records)[count] = input_records[i];
+      ++count;
+    }
+  }
+  *output_records = output_records->ref(0, count);
+}
+
+template <typename T>
+void ComparisonNode<T>::evaluate(ArrayCRef<Record> records,
+                                 ArrayRef<Value> results) {
+  this->fill_arg1_values(records);
+  this->fill_arg2_values(records);
+  for (size_t i = 0; i < records.size(); ++i) {
+    results[i] = comparer_(this->arg1_values_[i], this->arg2_values_[i]);
+  }
+}
+
+// ----- EqualNode -----
+
+// TODO: EqualNode for Bool should be specialized.
+
+struct Equal {
+  template <typename T>
+  struct Comparer {
+    using Arg = T;
+    Bool operator()(const Arg &arg1, const Arg &arg2) const {
+      return arg1 == arg2;
+    }
+  };
+};
+
+template <typename T>
+using EqualNode = ComparisonNode<Equal::Comparer<T>>;
+
+// ----- NotEqualNode -----
+
+// TODO: NotEqualNode for Bool should be specialized.
+
+struct NotEqual {
+  template <typename T>
+  struct Comparer {
+    using Arg = T;
+    Bool operator()(const Arg &arg1, const Arg &arg2) const {
+      return arg1 != arg2;
+    }
+  };
+};
+
+template <typename T>
+using NotEqualNode = ComparisonNode<NotEqual::Comparer<T>>;
+
+// ----- LessNode -----
+
+struct Less {
+  template <typename T>
+  struct Comparer {
+    using Arg = T;
+    Bool operator()(const Arg &arg1, const Arg &arg2) const {
+      return arg1 < arg2;
+    }
+  };
+};
+
+template <typename T>
+using LessNode = ComparisonNode<Less::Comparer<T>>;
+
+// ----- LessEqualNode -----
+
+struct LessEqual {
+  template <typename T>
+  struct Comparer {
+    using Arg = T;
+    Bool operator()(const Arg &arg1, const Arg &arg2) const {
+      return arg1 <= arg2;
+    }
+  };
+};
+
+template <typename T>
+using LessEqualNode = ComparisonNode<LessEqual::Comparer<T>>;
+
+// ----- GreaterNode -----
+
+struct Greater {
+  template <typename T>
+  struct Comparer {
+    using Arg = T;
+    Bool operator()(const Arg &arg1, const Arg &arg2) const {
+      return arg1 > arg2;
+    }
+  };
+};
+
+template <typename T>
+using GreaterNode = ComparisonNode<Greater::Comparer<T>>;
+
+// ----- GreaterEqualNode -----
+
+struct GreaterEqual {
+  template <typename T>
+  struct Comparer {
+    using Arg = T;
+    Bool operator()(const Arg &arg1, const Arg &arg2) const {
+      return arg1 >= arg2;
+    }
+  };
+};
+
+template <typename T>
+using GreaterEqualNode = ComparisonNode<GreaterEqual::Comparer<T>>;
+
 }  // namespace expression
 
 using namespace expression;
@@ -1401,30 +1544,30 @@ Node *ExpressionBuilder::create_binary_node(
       }
       return new LogicalOrNode(std::move(arg1), std::move(arg2));
     }
-//    case EQUAL_OPERATOR: {
-//      return create_equality_test_node<Equal>(
-//          error, std::move(arg1), std::move(arg2));
-//    }
-//    case NOT_EQUAL_OPERATOR: {
-//      return create_equality_test_node<NotEqual>(
-//          error, std::move(arg1), std::move(arg2));
-//    }
-//    case LESS_OPERATOR: {
-//      return create_comparison_node<Less>(
-//          error, std::move(arg1), std::move(arg2));
-//    }
-//    case LESS_EQUAL_OPERATOR: {
-//      return create_comparison_node<LessEqual>(
-//          error, std::move(arg1), std::move(arg2));
-//    }
-//    case GREATER_OPERATOR: {
-//      return create_comparison_node<Greater>(
-//          error, std::move(arg1), std::move(arg2));
-//    }
-//    case GREATER_EQUAL_OPERATOR: {
-//      return create_comparison_node<GreaterEqual>(
-//          error, std::move(arg1), std::move(arg2));
-//    }
+    case EQUAL_OPERATOR: {
+      return create_equality_test_node<Equal>(
+          std::move(arg1), std::move(arg2));
+    }
+    case NOT_EQUAL_OPERATOR: {
+      return create_equality_test_node<NotEqual>(
+          std::move(arg1), std::move(arg2));
+    }
+    case LESS_OPERATOR: {
+      return create_comparison_node<Less>(
+          std::move(arg1), std::move(arg2));
+    }
+    case LESS_EQUAL_OPERATOR: {
+      return create_comparison_node<LessEqual>(
+          std::move(arg1), std::move(arg2));
+    }
+    case GREATER_OPERATOR: {
+      return create_comparison_node<Greater>(
+          std::move(arg1), std::move(arg2));
+    }
+    case GREATER_EQUAL_OPERATOR: {
+      return create_comparison_node<GreaterEqual>(
+          std::move(arg1), std::move(arg2));
+    }
 //    case BITWISE_AND_OPERATOR:
 //    case BITWISE_OR_OPERATOR:
 //    case BITWISE_XOR_OPERATOR: {
@@ -1481,5 +1624,91 @@ Node *ExpressionBuilder::create_binary_node(
   throw "Memory allocation failed";  // TODO
 }
 
+// Create a node associated with an equality test operator.
+template <typename T>
+Node *ExpressionBuilder::create_equality_test_node(
+    std::unique_ptr<Node> &&arg1,
+    std::unique_ptr<Node> &&arg2) {
+  if (arg1->data_type() != arg2->data_type()) {
+    throw "Data type conflict";  // TODO
+  }
+  switch (arg1->data_type()) {
+    case BOOL_DATA: {
+      return new ComparisonNode<typename T:: template Comparer<Bool>>(
+          std::move(arg1), std::move(arg2));
+    }
+    case INT_DATA: {
+      return new ComparisonNode<typename T:: template Comparer<Int>>(
+          std::move(arg1), std::move(arg2));
+    }
+    case FLOAT_DATA: {
+      return new ComparisonNode<typename T:: template Comparer<Float>>(
+          std::move(arg1), std::move(arg2));
+    }
+    case GEO_POINT_DATA: {
+      return new ComparisonNode<typename T:: template Comparer<GeoPoint>>(
+          std::move(arg1), std::move(arg2));
+    }
+    case TEXT_DATA: {
+      return new ComparisonNode<typename T:: template Comparer<Text>>(
+          std::move(arg1), std::move(arg2));
+    }
+//    case BOOL_VECTOR_DATA: {
+//      typedef typename T:: template Comparer<Vector<Bool>> Functor;
+//      return ComparisonNode<Functor>::create(
+//          error, std::move(arg1), std::move(arg2));
+//    }
+//    case INT_VECTOR_DATA: {
+//      typedef typename T:: template Comparer<Vector<Int>> Functor;
+//      return ComparisonNode<Functor>::create(
+//          error, std::move(arg1), std::move(arg2));
+//    }
+//    case FLOAT_VECTOR_DATA: {
+//      typedef typename T:: template Comparer<Vector<Float>> Functor;
+//      return ComparisonNode<Functor>::create(
+//          error, std::move(arg1), std::move(arg2));
+//    }
+//    case GEO_POINT_VECTOR_DATA: {
+//      typedef typename T:: template Comparer<Vector<GeoPoint>> Functor;
+//      return ComparisonNode<Functor>::create(
+//          error, std::move(arg1), std::move(arg2));
+//    }
+//    case TEXT_VECTOR_DATA: {
+//      typedef typename T:: template Comparer<Vector<Text>> Functor;
+//      return ComparisonNode<Functor>::create(
+//          error, std::move(arg1), std::move(arg2));
+//    }
+    default: {
+      throw "Invalid data type";  // TODO
+    }
+  }
+}
+
+// Create a node associated with a comparison operator.
+template <typename T>
+Node *ExpressionBuilder::create_comparison_node(std::unique_ptr<Node> &&arg1,
+                                                std::unique_ptr<Node> &&arg2) {
+  if (arg1->data_type() != arg2->data_type()) {
+    throw "Data type conflict";  // TODO
+  }
+  switch (arg1->data_type()) {
+    case INT_DATA: {
+      return new ComparisonNode<typename T:: template Comparer<Int>>(
+          std::move(arg1), std::move(arg2));
+    }
+    case FLOAT_DATA: {
+      return new ComparisonNode<typename T:: template Comparer<Float>>(
+          std::move(arg1), std::move(arg2));
+    }
+    case TEXT_DATA: {
+      return new ComparisonNode<typename T:: template Comparer<Text>>(
+          std::move(arg1), std::move(arg2));
+    }
+    default: {
+      throw "Invalid data type";  // TODO
+    }
+  }
+}
+
 }  // namespace impl
 }  // namespace grnxx

  Modified: lib/grnxx/impl/expression.hpp (+19 -7)
===================================================================
--- lib/grnxx/impl/expression.hpp    2014-11-13 20:58:43 +0900 (08fc2d8)
+++ lib/grnxx/impl/expression.hpp    2014-11-13 21:49:25 +0900 (0fe020b)
@@ -128,17 +128,29 @@ class ExpressionBuilder : public ExpressionBuilderInterface {
   // Create a node associated with a unary operator.
   //
   // On failure, throws an exception.
-  Node *create_unary_node(
-      OperatorType operator_type,
-      std::unique_ptr<Node> &&arg);
+  Node *create_unary_node(OperatorType operator_type,
+                          std::unique_ptr<Node> &&arg);
 
   // Create a node associated with a binary operator.
   //
   // On failure, throws an exception.
-  Node *create_binary_node(
-      OperatorType operator_type,
-      std::unique_ptr<Node> &&arg1,
-      std::unique_ptr<Node> &&arg2);
+  Node *create_binary_node(OperatorType operator_type,
+                           std::unique_ptr<Node> &&arg1,
+                           std::unique_ptr<Node> &&arg2);
+
+  // Create a node associated with an equality test operator.
+  //
+  // On failure, throws an exception.
+  template <typename T>
+  Node *create_equality_test_node(std::unique_ptr<Node> &&arg1,
+                                  std::unique_ptr<Node> &&arg2);
+
+  // Create a node associated with a comparison operator.
+  //
+  // On failure, throws an exception.
+  template <typename T>
+  Node *create_comparison_node(std::unique_ptr<Node> &&arg1,
+                               std::unique_ptr<Node> &&arg2);
 };
 
 }  // namespace impl
-------------- next part --------------
HTML����������������������������...
下載 



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