[Groonga-commit] groonga/grnxx at f98e112 [new_data_types] Add SubscriptNode. (#106)

Back to archive index

susumu.yata null+****@clear*****
Mon Nov 17 21:12:30 JST 2014


susumu.yata	2014-11-17 21:12:30 +0900 (Mon, 17 Nov 2014)

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

  Message:
    Add SubscriptNode. (#106)

  Modified files:
    include/grnxx/data_types/vector/bool.hpp
    include/grnxx/data_types/vector/float.hpp
    include/grnxx/data_types/vector/geo_point.hpp
    include/grnxx/data_types/vector/int.hpp
    lib/grnxx/impl/expression.cpp
    lib/grnxx/impl/expression.hpp

  Modified: include/grnxx/data_types/vector/bool.hpp (+8 -2)
===================================================================
--- include/grnxx/data_types/vector/bool.hpp    2014-11-17 20:32:08 +0900 (4a6f34f)
+++ include/grnxx/data_types/vector/bool.hpp    2014-11-17 21:12:30 +0900 (674bf8a)
@@ -21,8 +21,14 @@ class Vector<Bool> {
   constexpr Vector(const Bool *data, size_t size) : data_(data), size_(size) {}
   explicit constexpr Vector(NA) : data_(nullptr), size_(NA()) {}
 
-  // TODO: The argument should be Int.
-  //       Also, N/A should be returned for an invalid "i".
+  Bool operator[](Int i) const {
+    if (is_na() || (static_cast<uint64_t>(i.value()) >=
+                    static_cast<uint64_t>(size_.value()))) {
+      return Bool::na();
+    }
+    return data_[i.value()];
+  }
+  // TODO: To be removed.
   const Bool &operator[](size_t i) const {
     return data_[i];
   }

  Modified: include/grnxx/data_types/vector/float.hpp (+8 -2)
===================================================================
--- include/grnxx/data_types/vector/float.hpp    2014-11-17 20:32:08 +0900 (916a923)
+++ include/grnxx/data_types/vector/float.hpp    2014-11-17 21:12:30 +0900 (81341bf)
@@ -23,8 +23,14 @@ class Vector<Float> {
         size_(size) {}
   explicit constexpr Vector(NA) : data_(nullptr), size_(NA()) {}
 
-  // TODO: The argument should be Int.
-  //       Also, N/A should be returned for an invalid "i".
+  Float operator[](Int i) const {
+    if (is_na() || (static_cast<uint64_t>(i.value()) >=
+                    static_cast<uint64_t>(size_.value()))) {
+      return Float::na();
+    }
+    return data_[i.value()];
+  }
+  // TODO: To be removed.
   const Float &operator[](size_t i) const {
     return data_[i];
   }

  Modified: include/grnxx/data_types/vector/geo_point.hpp (+8 -2)
===================================================================
--- include/grnxx/data_types/vector/geo_point.hpp    2014-11-17 20:32:08 +0900 (2014fd1)
+++ include/grnxx/data_types/vector/geo_point.hpp    2014-11-17 21:12:30 +0900 (3494f23)
@@ -23,8 +23,14 @@ class Vector<GeoPoint> {
         size_(size) {}
   explicit constexpr Vector(NA) : data_(nullptr), size_(NA()) {}
 
-  // TODO: The argument should be Int.
-  //       Also, N/A should be returned for an invalid "i".
+  GeoPoint operator[](Int i) const {
+    if (is_na() || (static_cast<uint64_t>(i.value()) >=
+                    static_cast<uint64_t>(size_.value()))) {
+      return GeoPoint::na();
+    }
+    return data_[i.value()];
+  }
+  // TODO: To be removed.
   const GeoPoint &operator[](size_t i) const {
     return data_[i];
   }

  Modified: include/grnxx/data_types/vector/int.hpp (+8 -2)
===================================================================
--- include/grnxx/data_types/vector/int.hpp    2014-11-17 20:32:08 +0900 (dc9b709)
+++ include/grnxx/data_types/vector/int.hpp    2014-11-17 21:12:30 +0900 (4344a7f)
@@ -21,8 +21,14 @@ class Vector<Int> {
   constexpr Vector(const Int *data, size_t size) : data_(data), size_(size) {}
   explicit constexpr Vector(NA) : data_(nullptr), size_(NA()) {}
 
-  // TODO: The argument should be Int.
-  //       Also, N/A should be returned for an invalid "i".
+  Int operator[](Int i) const {
+    if (is_na() || (static_cast<uint64_t>(i.value()) >=
+                    static_cast<uint64_t>(size_.value()))) {
+      return Int::na();
+    }
+    return data_[i.value()];
+  }
+  // TODO: To be removed.
   const Int &operator[](size_t i) const {
     return data_[i];
   }

  Modified: lib/grnxx/impl/expression.cpp (+130 -3)
===================================================================
--- lib/grnxx/impl/expression.cpp    2014-11-17 20:32:08 +0900 (4d5663b)
+++ lib/grnxx/impl/expression.cpp    2014-11-17 21:12:30 +0900 (f9b1275)
@@ -1232,6 +1232,106 @@ struct ModulusOperator {
 template <typename T>
 using ModulusNode = GenericBinaryNode<ModulusOperator<T>>;
 
+// ---- SubscriptNode ----
+
+template <typename T>
+class SubscriptNode : public BinaryNode<T, Vector<T>, Int> {
+ public:
+  using Value = T;
+  using Arg1 = Vector<T>;
+  using Arg2 = Int;
+
+  SubscriptNode(std::unique_ptr<Node> &&arg1, std::unique_ptr<Node> &&arg2)
+      : BinaryNode<Value, Arg1, Arg2>(std::move(arg1), std::move(arg2)) {}
+  ~SubscriptNode() = default;
+
+  const Table *reference_table() const {
+    return this->arg1_->reference_table();
+  }
+
+  void evaluate(ArrayCRef<Record> records, ArrayRef<Value> results);
+};
+
+template <typename T>
+void SubscriptNode<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] = this->arg1_values_[i][this->arg2_values_[i]];
+  }
+}
+
+template <>
+class SubscriptNode<Bool> : public BinaryNode<Bool, Vector<Bool>, Int> {
+ public:
+  using Value = Bool;
+  using Arg1 = Vector<Bool>;
+  using Arg2 = Int;
+
+  SubscriptNode(std::unique_ptr<Node> &&arg1, std::unique_ptr<Node> &&arg2)
+      : BinaryNode<Value, Arg1, Arg2>(std::move(arg1), std::move(arg2)) {}
+  ~SubscriptNode() = default;
+
+  void filter(ArrayCRef<Record> input_records,
+              ArrayRef<Record> *output_records);
+  void evaluate(ArrayCRef<Record> records, ArrayRef<Value> results);
+};
+
+void SubscriptNode<Bool>::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 (this->arg1_values_[i][this->arg2_values_[i]].is_true()) {
+      (*output_records)[count] = input_records[i];
+      ++count;
+    }
+  }
+  *output_records = output_records->ref(0, count);
+}
+
+void SubscriptNode<Bool>::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] = this->arg1_values_[i][this->arg2_values_[i]];
+  }
+}
+
+template <>
+class SubscriptNode<Float> : public BinaryNode<Float, Vector<Float>, Int> {
+ public:
+  using Value = Float;
+  using Arg1 = Vector<Float>;
+  using Arg2 = Int;
+
+  SubscriptNode(std::unique_ptr<Node> &&arg1, std::unique_ptr<Node> &&arg2)
+      : BinaryNode<Value, Arg1, Arg2>(std::move(arg1), std::move(arg2)) {}
+  ~SubscriptNode() = default;
+
+  void adjust(ArrayRef<Record> records);
+  void evaluate(ArrayCRef<Record> records, ArrayRef<Value> results);
+};
+
+void SubscriptNode<Float>::adjust(ArrayRef<Record> records) {
+  fill_arg1_values(records);
+  fill_arg2_values(records);
+  for (size_t i = 0; i < records.size(); ++i) {
+    records[i].score = this->arg1_values_[i][this->arg2_values_[i]];
+  }
+}
+
+void SubscriptNode<Float>::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] = this->arg1_values_[i][this->arg2_values_[i]];
+  }
+}
 
 // ---- DereferenceNode ----
 
@@ -2027,9 +2127,9 @@ Node *ExpressionBuilder::create_binary_node(
         }
       }
     }
-//    case SUBSCRIPT_OPERATOR: {
-//      return create_subscript_node(error, std::move(arg1), std::move(arg2));
-//    }
+    case SUBSCRIPT_OPERATOR: {
+      return create_subscript_node(std::move(arg1), std::move(arg2));
+    }
     default: {
       throw "Not supported yet";  // TODO
     }
@@ -2141,6 +2241,33 @@ Node *ExpressionBuilder::create_arithmetic_node(
   }
 }
 
+Node *ExpressionBuilder::create_subscript_node(std::unique_ptr<Node> &&arg1,
+                                               std::unique_ptr<Node> &&arg2) {
+  if (arg2->data_type() != INT_DATA) {
+    throw "Invalid data type";  // TODO
+  }
+  switch (arg1->data_type()) {
+    case BOOL_VECTOR_DATA: {
+      return new SubscriptNode<Bool>(std::move(arg1), std::move(arg2));
+    }
+    case INT_VECTOR_DATA: {
+      return new SubscriptNode<Int>(std::move(arg1), std::move(arg2));
+    }
+    case FLOAT_VECTOR_DATA: {
+      return new SubscriptNode<Float>(std::move(arg1), std::move(arg2));
+    }
+    case GEO_POINT_VECTOR_DATA: {
+      return new SubscriptNode<GeoPoint>(std::move(arg1), std::move(arg2));
+    }
+//    case TEXT_VECTOR_DATA: {
+//      return new SubscriptNode<Text>(std::move(arg1), std::move(arg2));
+//    }
+    default: {
+      throw "Invalid data type";  // TODO
+    }
+  }
+}
+
 Node *ExpressionBuilder::create_dereference_node(
     std::unique_ptr<Node> &&arg1,
     std::unique_ptr<Node> &&arg2,

  Modified: lib/grnxx/impl/expression.hpp (+6 -0)
===================================================================
--- lib/grnxx/impl/expression.hpp    2014-11-17 20:32:08 +0900 (2894886)
+++ lib/grnxx/impl/expression.hpp    2014-11-17 21:12:30 +0900 (f0953f1)
@@ -182,6 +182,12 @@ class ExpressionBuilder : public ExpressionBuilderInterface {
                                std::unique_ptr<Node> &&arg1,
                                std::unique_ptr<Node> &&arg2);
 
+  // Create a node associated with a subscript operator.
+  //
+  // On failure, throws an exception.
+  Node *create_subscript_node(std::unique_ptr<Node> &&arg1,
+                              std::unique_ptr<Node> &&arg2);
+
   // Create a node associated with a dereference operator.
   //
   // On failure, throws an exception.
-------------- next part --------------
HTML����������������������������...
下載 



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