susumu.yata
null+****@clear*****
Tue Sep 2 17:49:01 JST 2014
susumu.yata 2014-09-02 17:49:01 +0900 (Tue, 02 Sep 2014) New Revision: f695f78aaad628305d0b9b852e2a6d5305349cd2 https://github.com/groonga/grnxx/commit/f695f78aaad628305d0b9b852e2a6d5305349cd2 Message: Add Vector<Text>. 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 (+12 -2) =================================================================== --- include/grnxx/datum.hpp 2014-09-02 11:32:50 +0900 (5ea8174) +++ include/grnxx/datum.hpp 2014-09-02 17:49:01 +0900 (dd52e38) @@ -22,7 +22,7 @@ class Datum { Datum(GeoPoint value) : type_(GEO_POINT_DATA), geo_point_(value) {} - Datum(String value) + Datum(Text value) : type_(TEXT_DATA), text_(value) {} Datum(Vector<Bool> value) @@ -37,6 +37,9 @@ class Datum { Datum(Vector<GeoPoint> value) : type_(GEO_POINT_VECTOR_DATA), geo_point_vector_(value) {} + Datum(Vector<Text> value) + : type_(TEXT_VECTOR_DATA), + text_vector_(value) {} // Return the data type. DataType type() const { @@ -71,6 +74,9 @@ class Datum { Vector<GeoPoint> force_geo_point_vector() const { return geo_point_vector_; } + Vector<Text> force_text_vector() const { + return text_vector_; + } // Force the specified interpretation. void force(Bool *value) const { @@ -100,6 +106,9 @@ class Datum { void force(Vector<GeoPoint> *value) const { *value = geo_point_vector_; } + void force(Vector<Text> *value) const { + *value = text_vector_; + } private: DataType type_; @@ -108,11 +117,12 @@ class Datum { Int int_; Float float_; GeoPoint geo_point_; - String text_; + Text text_; Vector<Bool> bool_vector_; Vector<Int> int_vector_; Vector<Float> float_vector_; Vector<GeoPoint> geo_point_vector_; + Vector<Text> text_vector_; }; }; Modified: include/grnxx/types.hpp (+88 -0) =================================================================== --- include/grnxx/types.hpp 2014-09-02 11:32:50 +0900 (08059e7) +++ include/grnxx/types.hpp 2014-09-02 17:49:01 +0900 (22eec0c) @@ -454,10 +454,90 @@ inline Bool operator!=(Vector<GeoPoint> lhs, Vector<GeoPoint> rhs) { return false; } +// TODO: Improve the implementation of Vector<Text>. +template <> +class Vector<Text> { + public: + Vector() = default; + Vector(const Text *data, Int size) + : is_direct_(1), + size_(size), + data_(data) {} + Vector(const void *headers, const char *bodies, Int size) + : is_direct_(0), + size_(size), + headers_(static_cast<const Header *>(headers)), + bodies_(bodies) {} + Vector(const Vector &) = default; + + Vector &operator=(const Vector &) = default; + + // Return the number of Text values. + Int size() const { + return static_cast<Int>(size_); + } + // Return the "i"-th Text value. + // + // If "i" is invalid, the result is undefined. + Text get(Int i) const { + if (is_direct_) { + return data_[i]; + } else { + return Text(&bodies_[headers_[i].offset], headers_[i].size); + } + } + + // Return the "i"-th Text value. + // + // If "i" is invalid, the result is undefined. + Text operator[](Int i) const { + return get(i); + } + + private: + struct Header { + Int offset; + Int size; + }; + bool is_direct_; + Int size_; + union { + const Text *data_; + struct { + const Header *headers_; + const char *bodies_; + }; + }; +}; + +inline Bool operator==(Vector<Text> lhs, Vector<Text> 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<Text> lhs, Vector<Text> 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>; +using TextVector = Vector<Text>; // Type information. template <typename T> struct TypeTraits; @@ -533,6 +613,14 @@ template <> struct TypeTraits <Vector<GeoPoint>> { return Vector<GeoPoint>(nullptr, 0); } }; +template <> struct TypeTraits <Vector<Text>> { + static DataType data_type() { + return TEXT_VECTOR_DATA; + } + static Vector<Text> default_value() { + return Vector<Text>(nullptr, 0); + } +}; // Zero is reserved for representing a null reference. constexpr Int NULL_ROW_ID = 0; Modified: lib/grnxx/column.cpp (+95 -1) =================================================================== --- lib/grnxx/column.cpp 2014-09-02 11:32:50 +0900 (78a2036) +++ lib/grnxx/column.cpp 2014-09-02 17:49:01 +0900 (a0de861) @@ -101,6 +101,9 @@ unique_ptr<Column> Column::create(Error *error, case GEO_POINT_VECTOR_DATA: { return ColumnImpl<Vector<GeoPoint>>::create(error, table, name, options); } + case TEXT_VECTOR_DATA: { + return ColumnImpl<Vector<Text>>::create(error, table, name, options); + } default: { // TODO: Other data types are not supported yet. GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not suported yet"); @@ -546,7 +549,7 @@ ColumnImpl<Vector<Float>>::ColumnImpl() : Column(), headers_(), bodies_() {} // -- ColumnImpl<Vector<GeoPoint>> -- bool ColumnImpl<Vector<GeoPoint>>::set(Error *error, Int row_id, - const Datum &datum) { + const Datum &datum) { if (datum.type() != GEO_POINT_VECTOR_DATA) { GRNXX_ERROR_SET(error, INVALID_ARGUMENT, "Wrong data type"); return false; @@ -631,4 +634,95 @@ void ColumnImpl<Vector<GeoPoint>>::unset(Int row_id) { ColumnImpl<Vector<GeoPoint>>::ColumnImpl() : Column(), headers_(), bodies_() {} +// -- ColumnImpl<Vector<Text>> -- + +bool ColumnImpl<Vector<Text>>::set(Error *error, Int row_id, + const Datum &datum) { + if (datum.type() != TEXT_VECTOR_DATA) { + GRNXX_ERROR_SET(error, INVALID_ARGUMENT, "Wrong data type"); + return false; + } + if (!table_->test_row(error, row_id)) { + return false; + } + Vector<Text> value = datum.force_text_vector(); + if (value.size() == 0) { + headers_[row_id] = Header{ 0, 0 }; + return true; + } + Int text_headers_offset = text_headers_.size(); + if (!text_headers_.resize(error, text_headers_offset + value.size())) { + return false; + } + Int total_size = 0; + for (Int i = 0; i < value.size(); ++i) { + total_size += value[i].size(); + } + Int bodies_offset = bodies_.size(); + if (!bodies_.resize(error, bodies_offset + total_size)) { + return false; + } + headers_[row_id] = Header{ text_headers_offset, value.size() }; + for (Int i = 0; i < value.size(); ++i) { + text_headers_[text_headers_offset + i].offset = bodies_offset; + text_headers_[text_headers_offset + i].size = value[i].size(); + std::memcpy(&bodies_[bodies_offset], value[i].data(), value[i].size()); + bodies_offset += value[i].size(); + } + return true; +} + +bool ColumnImpl<Vector<Text>>::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<Text>>> ColumnImpl<Vector<Text>>::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, + TEXT_VECTOR_DATA, options)) { + return nullptr; + } + if (!column->headers_.resize(error, table->max_row_id() + 1, + Header{ 0, 0 })) { + return nullptr; + } + return column; +} + +ColumnImpl<Vector<Text>>::~ColumnImpl() {} + +bool ColumnImpl<Vector<Text>>::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] = Header{ 0, 0 }; + return true; +} + +void ColumnImpl<Vector<Text>>::unset(Int row_id) { + headers_[row_id] = Header{ 0, 0 }; +} + +ColumnImpl<Vector<Text>>::ColumnImpl() + : Column(), + headers_(), + text_headers_(), + bodies_() {} + } // namespace grnxx Modified: lib/grnxx/column_impl.hpp (+46 -0) =================================================================== --- lib/grnxx/column_impl.hpp 2014-09-02 11:32:50 +0900 (77b3aa9) +++ lib/grnxx/column_impl.hpp 2014-09-02 17:49:01 +0900 (bd31aed) @@ -282,6 +282,52 @@ class ColumnImpl<Vector<GeoPoint>> : public Column { ColumnImpl(); }; +// TODO: Improve the implementation. +template <> +class ColumnImpl<Vector<Text>> : 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<Text> get(Int row_id) const { + return Vector<Text>(&text_headers_[headers_[row_id].offset], + bodies_.data(), headers_[row_id].size); + } + + protected: + struct Header { + Int offset; + Int size; + }; + Array<Header> headers_; + Array<Header> text_headers_; + Array<char> bodies_; + + ColumnImpl(); +}; + } // namespace grnxx #endif // GRNXX_COLUMN_IMPL_HPP Modified: lib/grnxx/expression.cpp (+17 -0) =================================================================== --- lib/grnxx/expression.cpp 2014-09-02 11:32:50 +0900 (b09a278) +++ lib/grnxx/expression.cpp 2014-09-02 17:49:01 +0900 (def886e) @@ -2487,6 +2487,7 @@ GRNXX_INSTANTIATE_EXPRESSION_EVALUATE(Vector<Bool>); GRNXX_INSTANTIATE_EXPRESSION_EVALUATE(Vector<Int>); GRNXX_INSTANTIATE_EXPRESSION_EVALUATE(Vector<Float>); GRNXX_INSTANTIATE_EXPRESSION_EVALUATE(Vector<GeoPoint>); +GRNXX_INSTANTIATE_EXPRESSION_EVALUATE(Vector<Text>); #undef GRNXX_INSTANTIATE_EXPRESSION_EVALUATE template <typename T> @@ -2672,6 +2673,10 @@ unique_ptr<Node> ExpressionBuilder::create_datum_node( return DatumNode<Vector<Float>>::create(error, datum.force_float_vector()); } + case TEXT_VECTOR_DATA: { + return DatumNode<Vector<Text>>::create(error, + datum.force_text_vector()); + } case GEO_POINT_VECTOR_DATA: { return DatumNode<Vector<GeoPoint>>::create( error, datum.force_geo_point_vector()); @@ -2740,6 +2745,9 @@ unique_ptr<Node> ExpressionBuilder::create_column_node( case GEO_POINT_VECTOR_DATA: { return ColumnNode<Vector<GeoPoint>>::create(error, column); } + case TEXT_VECTOR_DATA: { + return ColumnNode<Vector<Text>>::create(error, column); + } default: { // TODO: Other types are not supported yet. GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not supported yet"); @@ -3005,6 +3013,11 @@ unique_ptr<Node> ExpressionBuilder::create_equality_test_node( 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)); + } // TODO: Support other types. default: { GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not supported yet"); @@ -3131,6 +3144,10 @@ unique_ptr<Node> ExpressionBuilder::create_subscript_node( return SubscriptNode<GeoPoint>::create( error, std::move(arg1), std::move(arg2)); } + case TEXT_VECTOR_DATA: { + return SubscriptNode<Text>::create( + error, std::move(arg1), std::move(arg2)); + } default: { GRNXX_ERROR_SET(error, INVALID_OPERAND, "Invalid data type"); return nullptr; -------------- next part -------------- HTML����������������������������... 다운로드