susumu.yata
null+****@clear*****
Fri Nov 7 00:08:22 JST 2014
susumu.yata 2014-11-07 00:08:22 +0900 (Fri, 07 Nov 2014) New Revision: e894a9eade67840401d20e4aabe0daf0c1f449c9 https://github.com/groonga/grnxx/commit/e894a9eade67840401d20e4aabe0daf0c1f449c9 Message: Add a draft version of Column<GeoPoint>. Modified files: lib/grnxx/impl/column/base.cpp lib/grnxx/impl/column/scalar.hpp lib/grnxx/impl/column/scalar/Makefile.am lib/grnxx/impl/column/scalar/geo_point.cpp lib/grnxx/impl/column/scalar/geo_point.hpp Modified: lib/grnxx/impl/column/base.cpp (+4 -4) =================================================================== --- lib/grnxx/impl/column/base.cpp 2014-11-07 00:00:59 +0900 (7bda38c) +++ lib/grnxx/impl/column/base.cpp 2014-11-07 00:08:22 +0900 (3e7ff2f) @@ -191,10 +191,10 @@ std::unique_ptr<ColumnBase> ColumnBase::create( column.reset(new impl::Column<Float>(table, name, options)); break; } -// case GEO_POINT_DATA: { -// column.reset(new impl::Column<GeoPoint>(table, name, options)); -// break; -// } + case GEO_POINT_DATA: { + column.reset(new impl::Column<GeoPoint>(table, name, options)); + break; + } // case TEXT_DATA: { // column.reset(new impl::Column<Text>(table, name, options)); // break; Modified: lib/grnxx/impl/column/scalar.hpp (+1 -1) =================================================================== --- lib/grnxx/impl/column/scalar.hpp 2014-11-07 00:00:59 +0900 (7dfc96b) +++ lib/grnxx/impl/column/scalar.hpp 2014-11-07 00:08:22 +0900 (d6d9c3a) @@ -3,7 +3,7 @@ #include "grnxx/impl/column/scalar/bool.hpp" #include "grnxx/impl/column/scalar/float.hpp" -//#include "grnxx/impl/column/scalar/geo_point.hpp" +#include "grnxx/impl/column/scalar/geo_point.hpp" #include "grnxx/impl/column/scalar/int.hpp" //#include "grnxx/impl/column/scalar/text.hpp" Modified: lib/grnxx/impl/column/scalar/Makefile.am (+1 -1) =================================================================== --- lib/grnxx/impl/column/scalar/Makefile.am 2014-11-07 00:00:59 +0900 (3230819) +++ lib/grnxx/impl/column/scalar/Makefile.am 2014-11-07 00:08:22 +0900 (1e31021) @@ -11,9 +11,9 @@ libgrnxx_impl_column_scalar_la_LDFLAGS = @AM_LTLDFLAGS@ libgrnxx_impl_column_scalar_la_SOURCES = \ bool.cpp \ float.cpp \ + geo_point.cpp \ int.cpp -# geo_point.cpp \ # text.cpp libgrnxx_impl_column_scalar_includedir = ${includedir}/grnxx/impl/column/scalar Modified: lib/grnxx/impl/column/scalar/geo_point.cpp (+137 -0) =================================================================== --- lib/grnxx/impl/column/scalar/geo_point.cpp 2014-11-07 00:00:59 +0900 (e69de29) +++ lib/grnxx/impl/column/scalar/geo_point.cpp 2014-11-07 00:08:22 +0900 (02e735c) @@ -0,0 +1,137 @@ +#include "grnxx/impl/column/scalar/geo_point.hpp" + +#include "grnxx/impl/table.hpp" +//#include "grnxx/index.hpp" + +namespace grnxx { +namespace impl { + +Column<GeoPoint>::Column(Table *table, + const String &name, + const ColumnOptions &) + : ColumnBase(table, name, GEO_POINT_DATA), + values_() {} + +Column<GeoPoint>::~Column() {} + +void Column<GeoPoint>::set(Int row_id, const Datum &datum) { + GeoPoint new_value = parse_datum(datum); + if (!table_->test_row(row_id)) { + throw "Invalid row ID"; // TODO + } + if (new_value.is_na()) { + unset(row_id); + return; + } + GeoPoint old_value = get(row_id); + if (old_value == new_value) { + return; + } + if (!old_value.is_na()) { + // TODO: Remove the old value from indexes. +// for (size_t i = 0; i < num_indexes(); ++i) { +// indexes_[i]->remove(row_id, old_value); +// } + } + size_t value_id = row_id.value(); + if (value_id >= values_.size()) { + values_.resize(value_id + 1, GeoPoint::na()); + } + // TODO: Insert the new value into indexes. +// for (size_t i = 0; i < num_indexes(); ++i) try { +// indexes_[i]->insert(row_id, datum)) { +// } catch (...) { +// for (size_t j = 0; j < i; ++i) { +// indexes_[j]->remove(row_id, datum); +// } +// throw; +// } + values_[value_id] = new_value; +} + +void Column<GeoPoint>::get(Int row_id, Datum *datum) const { + size_t value_id = row_id.value(); + if (value_id >= values_.size()) { + *datum = GeoPoint::na(); + } else { + *datum = values_[value_id]; + } +} + +bool Column<GeoPoint>::contains(const Datum &datum) const { + // TODO: Use an index if exists. + GeoPoint value = parse_datum(datum); + if (value.is_na()) { + for (size_t i = 0; i < values_.size(); ++i) { + if (values_[i].is_na() && table_->_test_row(i)) { + return true; + } + } + } else { + for (size_t i = 0; i < values_.size(); ++i) { + if ((values_[i].latitude() == value.latitude()) && + (values_[i].longitude() == value.longitude())) { + return true; + } + } + } + return false; +} + +Int Column<GeoPoint>::find_one(const Datum &datum) const { + // TODO: Use an index if exists. + GeoPoint value = parse_datum(datum); + if (value.is_na()) { + for (size_t i = 0; i < values_.size(); ++i) { + if (values_[i].is_na() && table_->_test_row(i)) { + return Int(i); + } + } + } else { + for (size_t i = 0; i < values_.size(); ++i) { + if ((values_[i].latitude() == value.latitude()) && + (values_[i].longitude() == value.longitude())) { + return Int(i); + } + } + } + return Int::na(); +} + +void Column<GeoPoint>::unset(Int row_id) { + GeoPoint value = get(row_id); + if (!value.is_na()) { + // TODO: Update indexes if exist. +// for (size_t i = 0; i < num_indexes(); ++i) { +// indexes_[i]->remove(row_id, value); +// } + values_[row_id.value()] = GeoPoint::na(); + } +} + +void Column<GeoPoint>::read(ArrayCRef<Record> records, + ArrayRef<GeoPoint> values) const { + if (records.size() != values.size()) { + throw "Data size conflict"; // TODO + } + for (size_t i = 0; i < records.size(); ++i) { + values.set(i, get(records[i].row_id)); + } +} + +GeoPoint Column<GeoPoint>::parse_datum(const Datum &datum) { + switch (datum.type()) { + case NA_DATA: { + return GeoPoint::na(); + } + case GEO_POINT_DATA: { + return datum.as_geo_point(); + } + default: { + throw "Wrong data type"; // TODO + } + } +} + +} // namespace impl +} // namespace grnxx Modified: lib/grnxx/impl/column/scalar/geo_point.hpp (+45 -2) =================================================================== --- lib/grnxx/impl/column/scalar/geo_point.hpp 2014-11-07 00:00:59 +0900 (2d9d051) +++ lib/grnxx/impl/column/scalar/geo_point.hpp 2014-11-07 00:08:22 +0900 (4ad688b) @@ -1,12 +1,55 @@ #ifndef GRNXX_IMPL_COLUMN_SCALAR_GEO_POINT_HPP #define GRNXX_IMPL_COLUMN_SCALAR_GEO_POINT_HPP -#include "grnxx/impl/column/column.hpp" +#include "grnxx/impl/column/base.hpp" namespace grnxx { namespace impl { -// TODO +template <typename T> class Column; + +template <> +class Column<GeoPoint> : public ColumnBase { + public: + // -- Public API (grnxx/column.hpp) -- + + Column(Table *table, const String &name, const ColumnOptions &options); + ~Column(); + + void set(Int row_id, const Datum &datum); + void get(Int row_id, Datum *datum) const; + + bool contains(const Datum &datum) const; + Int find_one(const Datum &datum) const; + + // -- Internal API (grnxx/impl/column/base.hpp) -- + + // Unset the value. + void unset(Int row_id); + + // -- Internal API -- + + // Return a value. + // + // If "row_id" is valid, returns the stored value. + // If "row_id" is invalid, returns N/A. + GeoPoint get(Int row_id) const { + size_t value_id = row_id.value(); + if (value_id >= values_.size()) { + return GeoPoint::na(); + } + return values_[value_id]; + } + // Read values. + // + // On failure, throws an exception. + void read(ArrayCRef<Record> records, ArrayRef<GeoPoint> values) const; + + protected: + Array<GeoPoint> values_; + + static GeoPoint parse_datum(const Datum &datum); +}; } // namespace impl } // namespace grnxx -------------- next part -------------- HTML����������������������������... 下載