susumu.yata
null+****@clear*****
Tue Dec 16 10:43:54 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����������������������������... Descargar