susumu.yata
null+****@clear*****
Tue Sep 2 11:32:38 JST 2014
susumu.yata 2014-09-02 11:32:38 +0900 (Tue, 02 Sep 2014) New Revision: f82aa61692fb7ab5adc325d78f83a0322234771e https://github.com/groonga/grnxx/commit/f82aa61692fb7ab5adc325d78f83a0322234771e Message: Add Vector<GeoPoint>. Modified files: include/grnxx/datum.hpp include/grnxx/types.hpp lib/grnxx/column.cpp lib/grnxx/column_impl.hpp lib/grnxx/expression.cpp Modified: include/grnxx/datum.hpp (+10 -0) =================================================================== --- include/grnxx/datum.hpp 2014-09-02 11:02:26 +0900 (fbd826f) +++ include/grnxx/datum.hpp 2014-09-02 11:32:38 +0900 (5ea8174) @@ -34,6 +34,9 @@ class Datum { Datum(Vector<Float> value) : type_(FLOAT_VECTOR_DATA), float_vector_(value) {} + Datum(Vector<GeoPoint> value) + : type_(GEO_POINT_VECTOR_DATA), + geo_point_vector_(value) {} // Return the data type. DataType type() const { @@ -65,6 +68,9 @@ class Datum { Vector<Float> force_float_vector() const { return float_vector_; } + Vector<GeoPoint> force_geo_point_vector() const { + return geo_point_vector_; + } // Force the specified interpretation. void force(Bool *value) const { @@ -91,6 +97,9 @@ class Datum { void force(Vector<Float> *value) const { *value = float_vector_; } + void force(Vector<GeoPoint> *value) const { + *value = geo_point_vector_; + } private: DataType type_; @@ -103,6 +112,7 @@ class Datum { Vector<Bool> bool_vector_; Vector<Int> int_vector_; Vector<Float> float_vector_; + Vector<GeoPoint> geo_point_vector_; }; }; Modified: include/grnxx/types.hpp (+67 -3) =================================================================== --- include/grnxx/types.hpp 2014-09-02 11:02:26 +0900 (f3af08f) +++ include/grnxx/types.hpp 2014-09-02 11:32:38 +0900 (08059e7) @@ -399,9 +399,65 @@ inline Bool operator!=(Vector<Float> lhs, Vector<Float> rhs) { return false; } -using BoolVector = Vector<Bool>; -using IntVector = Vector<Int>; -using FloatVector = Vector<Float>; +template <> +class Vector<GeoPoint> { + public: + Vector() = default; + Vector(const GeoPoint *data, Int size) : data_(data), size_(size) {} + Vector(const Vector &) = default; + + Vector &operator=(const Vector &) = default; + + // Return the number of GeoPoint values. + Int size() const { + return size_; + } + // Return the "i"-th GeoPoint value. + // + // If "i" is invalid, the result is undefined. + GeoPoint get(Int i) const { + return data_[i]; + } + + // Return the "i"-th GeoPoint value. + // + // If "i" is invalid, the result is undefined. + GeoPoint operator[](Int i) const { + return get(i); + } + + private: + const GeoPoint *data_; + Int size_; +}; + +inline Bool operator==(Vector<GeoPoint> lhs, Vector<GeoPoint> rhs) { + if (lhs.size() != rhs.size()) { + return false; + } + for (Int i = 0; i < lhs.size(); ++i) { + if (lhs[i] != rhs[i]) { + return false; + } + } + return true; +} +inline Bool operator!=(Vector<GeoPoint> lhs, Vector<GeoPoint> rhs) { + if (lhs.size() != rhs.size()) { + return true; + } + for (Int i = 0; i < lhs.size(); ++i) { + if (lhs[i] != rhs[i]) { + return true; + } + } + return false; +} + +using BoolVector = Vector<Bool>; +using IntVector = Vector<Int>; +using FloatVector = Vector<Float>; +using GeoPointVector = Vector<GeoPoint>; // Type information. template <typename T> struct TypeTraits; @@ -469,6 +525,14 @@ template <> struct TypeTraits <Vector<Float>> { return Vector<Float>(nullptr, 0); } }; +template <> struct TypeTraits <Vector<GeoPoint>> { + static DataType data_type() { + return GEO_POINT_VECTOR_DATA; + } + static Vector<GeoPoint> default_value() { + return Vector<GeoPoint>(nullptr, 0); + } +}; // Zero is reserved for representing a null reference. constexpr Int NULL_ROW_ID = 0; Modified: lib/grnxx/column.cpp (+91 -0) =================================================================== --- lib/grnxx/column.cpp 2014-09-02 11:02:26 +0900 (3c66975) +++ lib/grnxx/column.cpp 2014-09-02 11:32:38 +0900 (78a2036) @@ -98,6 +98,9 @@ unique_ptr<Column> Column::create(Error *error, case FLOAT_VECTOR_DATA: { return ColumnImpl<Vector<Float>>::create(error, table, name, options); } + case GEO_POINT_VECTOR_DATA: { + return ColumnImpl<Vector<GeoPoint>>::create(error, table, name, options); + } default: { // TODO: Other data types are not supported yet. GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not suported yet"); @@ -540,4 +543,92 @@ void ColumnImpl<Vector<Float>>::unset(Int row_id) { ColumnImpl<Vector<Float>>::ColumnImpl() : Column(), headers_(), bodies_() {} +// -- ColumnImpl<Vector<GeoPoint>> -- + +bool ColumnImpl<Vector<GeoPoint>>::set(Error *error, Int row_id, + const Datum &datum) { + if (datum.type() != GEO_POINT_VECTOR_DATA) { + GRNXX_ERROR_SET(error, INVALID_ARGUMENT, "Wrong data type"); + return false; + } + if (!table_->test_row(error, row_id)) { + return false; + } + Vector<GeoPoint> value = datum.force_geo_point_vector(); + if (value.size() == 0) { + headers_[row_id] = 0; + return true; + } + Int offset = bodies_.size(); + if (value.size() < 0xFFFF) { + if (!bodies_.resize(error, offset + value.size())) { + return false; + } + for (Int i = 0; i < value.size(); ++i) { + bodies_[offset + i] = value[i]; + } + headers_[row_id] = (offset << 16) | value.size(); + } else { + // The size of a long vector is stored in front of the body. + if (!bodies_.resize(error, offset + 1 + value.size())) { + return false; + } + Int size_for_copy = value.size(); + std::memcpy(&bodies_[offset], &size_for_copy, sizeof(Int)); + for (Int i = 0; i < value.size(); ++i) { + bodies_[offset + 1 + i] = value[i]; + } + headers_[row_id] = (offset << 16) | 0xFFFF; + } + return true; +} + +bool ColumnImpl<Vector<GeoPoint>>::get(Error *error, Int row_id, + Datum *datum) const { + if (!table_->test_row(error, row_id)) { + return false; + } + *datum = get(row_id); + return true; +} + +unique_ptr<ColumnImpl<Vector<GeoPoint>>> ColumnImpl<Vector<GeoPoint>>::create( + Error *error, + Table *table, + String name, + const ColumnOptions &options) { + unique_ptr<ColumnImpl> column(new (nothrow) ColumnImpl); + if (!column) { + GRNXX_ERROR_SET(error, NO_MEMORY, "Memory allocation failed"); + return nullptr; + } + if (!column->initialize_base(error, table, name, + GEO_POINT_VECTOR_DATA, options)) { + return nullptr; + } + if (!column->headers_.resize(error, table->max_row_id() + 1, 0)) { + return nullptr; + } + return column; +} + +ColumnImpl<Vector<GeoPoint>>::~ColumnImpl() {} + +bool ColumnImpl<Vector<GeoPoint>>::set_default_value(Error *error, + Int row_id) { + if (row_id >= headers_.size()) { + if (!headers_.resize(error, row_id + 1)) { + return false; + } + } + headers_[row_id] = 0; + return true; +} + +void ColumnImpl<Vector<GeoPoint>>::unset(Int row_id) { + headers_[row_id] = 0; +} + +ColumnImpl<Vector<GeoPoint>>::ColumnImpl() : Column(), headers_(), bodies_() {} + } // namespace grnxx Modified: lib/grnxx/column_impl.hpp (+50 -0) =================================================================== --- lib/grnxx/column_impl.hpp 2014-09-02 11:02:26 +0900 (05ab25a) +++ lib/grnxx/column_impl.hpp 2014-09-02 11:32:38 +0900 (77b3aa9) @@ -232,6 +232,56 @@ class ColumnImpl<Vector<Float>> : public Column { ColumnImpl(); }; +template <> +class ColumnImpl<Vector<GeoPoint>> : public Column { + public: + // -- Public API -- + + bool set(Error *error, Int row_id, const Datum &datum); + bool get(Error *error, Int row_id, Datum *datum) const; + + // -- Internal API -- + + // Create a new column. + // + // Returns a pointer to the column on success. + // On failure, returns nullptr and stores error information into "*error" if + // "error" != nullptr. + static unique_ptr<ColumnImpl> create(Error *error, + Table *table, + String name, + const ColumnOptions &options); + + ~ColumnImpl(); + + bool set_default_value(Error *error, Int row_id); + void unset(Int row_id); + + // Return a value identified by "row_id". + // + // Assumes that "row_id" is valid. Otherwise, the result is undefined. + Vector<GeoPoint> get(Int row_id) const { + Int size = static_cast<Int>(headers_[row_id] & 0xFFFF); + if (size == 0) { + return Vector<GeoPoint>(nullptr, 0); + } + Int offset = static_cast<Int>(headers_[row_id] >> 16); + if (size < 0xFFFF) { + return Vector<GeoPoint>(&bodies_[offset], size); + } else { + // The size of a long vector is stored in front of the body. + std::memcpy(&size, &bodies_[offset], sizeof(Int)); + return Vector<GeoPoint>(&bodies_[offset + 1], size); + } + } + + protected: + Array<uint64_t> headers_; + Array<GeoPoint> bodies_; + + ColumnImpl(); +}; + } // namespace grnxx #endif // GRNXX_COLUMN_IMPL_HPP Modified: lib/grnxx/expression.cpp (+19 -1) =================================================================== --- lib/grnxx/expression.cpp 2014-09-02 11:02:26 +0900 (f0e5b28) +++ lib/grnxx/expression.cpp 2014-09-02 11:32:38 +0900 (b09a278) @@ -2486,6 +2486,7 @@ GRNXX_INSTANTIATE_EXPRESSION_EVALUATE(Text); GRNXX_INSTANTIATE_EXPRESSION_EVALUATE(Vector<Bool>); GRNXX_INSTANTIATE_EXPRESSION_EVALUATE(Vector<Int>); GRNXX_INSTANTIATE_EXPRESSION_EVALUATE(Vector<Float>); +GRNXX_INSTANTIATE_EXPRESSION_EVALUATE(Vector<GeoPoint>); #undef GRNXX_INSTANTIATE_EXPRESSION_EVALUATE template <typename T> @@ -2668,7 +2669,12 @@ unique_ptr<Node> ExpressionBuilder::create_datum_node( return DatumNode<Vector<Int>>::create(error, datum.force_int_vector()); } case FLOAT_VECTOR_DATA: { - return DatumNode<Vector<Float>>::create(error, datum.force_float_vector()); + return DatumNode<Vector<Float>>::create(error, + datum.force_float_vector()); + } + case GEO_POINT_VECTOR_DATA: { + return DatumNode<Vector<GeoPoint>>::create( + error, datum.force_geo_point_vector()); } default: { // TODO: Other types are not supported yet. @@ -2731,6 +2737,9 @@ unique_ptr<Node> ExpressionBuilder::create_column_node( case FLOAT_VECTOR_DATA: { return ColumnNode<Vector<Float>>::create(error, column); } + case GEO_POINT_VECTOR_DATA: { + return ColumnNode<Vector<GeoPoint>>::create(error, column); + } default: { // TODO: Other types are not supported yet. GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not supported yet"); @@ -2991,6 +3000,11 @@ unique_ptr<Node> ExpressionBuilder::create_equality_test_node( 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)); + } // TODO: Support other types. default: { GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not supported yet"); @@ -3113,6 +3127,10 @@ unique_ptr<Node> ExpressionBuilder::create_subscript_node( return SubscriptNode<Float>::create( error, std::move(arg1), std::move(arg2)); } + case GEO_POINT_VECTOR_DATA: { + return SubscriptNode<GeoPoint>::create( + error, std::move(arg1), std::move(arg2)); + } default: { GRNXX_ERROR_SET(error, INVALID_OPERAND, "Invalid data type"); return nullptr; -------------- next part -------------- HTML����������������������������... 下載