susumu.yata
null+****@clear*****
Tue Dec 16 10:49:57 JST 2014
susumu.yata 2014-11-06 23:41:38 +0900 (Thu, 06 Nov 2014) New Revision: 1baeb801f67d8d14c019214c5294eebb98461c20 https://github.com/groonga/grnxx/commit/1baeb801f67d8d14c019214c5294eebb98461c20 Message: Enable a draft version of Column<Float>. 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/float.cpp lib/grnxx/impl/column/scalar/float.hpp Modified: lib/grnxx/impl/column/base.cpp (+4 -4) =================================================================== --- lib/grnxx/impl/column/base.cpp 2014-11-06 22:55:55 +0900 (cda986b) +++ lib/grnxx/impl/column/base.cpp 2014-11-06 23:41:38 +0900 (7bda38c) @@ -187,10 +187,10 @@ std::unique_ptr<ColumnBase> ColumnBase::create( column.reset(new impl::Column<Int>(table, name, options)); break; } -// case FLOAT_DATA: { -// column.reset(new impl::Column<Float>(table, name, options)); -// break; -// } + case FLOAT_DATA: { + column.reset(new impl::Column<Float>(table, name, options)); + break; + } // case GEO_POINT_DATA: { // column.reset(new impl::Column<GeoPoint>(table, name, options)); // break; Modified: lib/grnxx/impl/column/scalar.hpp (+1 -1) =================================================================== --- lib/grnxx/impl/column/scalar.hpp 2014-11-06 22:55:55 +0900 (a2f7635) +++ lib/grnxx/impl/column/scalar.hpp 2014-11-06 23:41:38 +0900 (7dfc96b) @@ -2,7 +2,7 @@ #define GRNXX_IMPL_COLUMN_SCALAR_HPP #include "grnxx/impl/column/scalar/bool.hpp" -//#include "grnxx/impl/column/scalar/float.hpp" +#include "grnxx/impl/column/scalar/float.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-06 22:55:55 +0900 (491594f) +++ lib/grnxx/impl/column/scalar/Makefile.am 2014-11-06 23:41:38 +0900 (3230819) @@ -10,9 +10,9 @@ libgrnxx_impl_column_scalar_la_LDFLAGS = @AM_LTLDFLAGS@ libgrnxx_impl_column_scalar_la_SOURCES = \ bool.cpp \ + float.cpp \ int.cpp -# float.cpp \ # geo_point.cpp \ # text.cpp Modified: lib/grnxx/impl/column/scalar/float.cpp (+104 -70) =================================================================== --- lib/grnxx/impl/column/scalar/float.cpp 2014-11-06 22:55:55 +0900 (aff1f36) +++ lib/grnxx/impl/column/scalar/float.cpp 2014-11-06 23:41:38 +0900 (fe02c70) @@ -1,101 +1,135 @@ -#include "grnxx/impl/column/column.hpp" +#include "grnxx/impl/column/scalar/float.hpp" -#include "grnxx/cursor.hpp" -#include "grnxx/impl/db.hpp" #include "grnxx/impl/table.hpp" -#include "grnxx/index.hpp" - -#include <cmath> +//#include "grnxx/index.hpp" namespace grnxx { namespace impl { -bool Column<Float>::set(Error *error, Int row_id, const Datum &datum) { - if (datum.type() != TypeTraits<Float>::data_type()) { - GRNXX_ERROR_SET(error, INVALID_ARGUMENT, "Wrong data type"); - return false; +Column<Float>::Column(Table *table, + const String &name, + const ColumnOptions &) + : ColumnBase(table, name, FLOAT_DATA), + values_() {} + +Column<Float>::~Column() {} + +void Column<Float>::set(Int row_id, const Datum &datum) { + Float new_value = parse_datum(datum); + if (!table_->test_row(row_id)) { + throw "Invalid row ID"; // TODO } - if (!table_->test_row(error, row_id)) { - return false; + if (new_value.is_na()) { + unset(row_id); + return; } Float old_value = get(row_id); - Float new_value = datum.force_float(); - if ((new_value != old_value) || - (std::isnan(new_value) != std::isnan(old_value))) { - for (Int i = 0; i < num_indexes(); ++i) { - if (!indexes_[i]->insert(error, row_id, datum)) { - for (Int j = 0; j < i; ++i) { - indexes_[j]->remove(nullptr, row_id, datum); - } - return false; - } - } - for (Int i = 0; i < num_indexes(); ++i) { - indexes_[i]->remove(nullptr, row_id, old_value); - } + if (old_value == new_value) { + return; } - values_.set(row_id, new_value); - return true; + 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, Float::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; } -bool Column<Float>::get(Error *error, Int row_id, Datum *datum) const { - if (!table_->test_row(error, row_id)) { - return false; +void Column<Float>::get(Int row_id, Datum *datum) const { + size_t value_id = row_id.value(); + if (value_id >= values_.size()) { + *datum = Float::na(); + } else { + *datum = values_[value_id]; } - *datum = values_[row_id]; - return true; } -unique_ptr<Column<Float>> Column<Float>::create(Error *error, - Table *table, - const StringCRef &name, - const ColumnOptions &options) { - unique_ptr<Column> column(new (nothrow) Column); - if (!column) { - GRNXX_ERROR_SET(error, NO_MEMORY, "Memory allocation failed"); - return nullptr; - } - if (!column->initialize_base(error, table, name, - TypeTraits<Float>::data_type(), options)) { - return nullptr; - } - if (!column->values_.resize(error, table->max_row_id() + 1, - TypeTraits<Float>::default_value())) { - return nullptr; +bool Column<Float>::contains(const Datum &datum) const { + // TODO: Use an index if exists. + Float 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].value() == value.value()) { + return true; + } + } } - return column; + return false; } -Column<Float>::~Column() {} - -bool Column<Float>::set_default_value(Error *error, Int row_id) { - if (row_id >= values_.size()) { - if (!values_.resize(error, row_id + 1, - TypeTraits<Float>::default_value())) { - return false; +Int Column<Float>::find_one(const Datum &datum) const { + // TODO: Use an index if exists. + Float 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); + } } - } - Float value = TypeTraits<Float>::default_value(); - for (Int i = 0; i < num_indexes(); ++i) { - if (!indexes_[i]->insert(error, row_id, value)) { - for (Int j = 0; j < i; ++j) { - indexes_[j]->remove(nullptr, row_id, value); + } else { + for (size_t i = 0; i < values_.size(); ++i) { + if (values_[i].value() == value.value()) { + return Int(i); } - return false; } } - values_.set(row_id, value); - return true; + return Int::na(); } void Column<Float>::unset(Int row_id) { - for (Int i = 0; i < num_indexes(); ++i) { - indexes_[i]->remove(nullptr, row_id, get(row_id)); + Float 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()] = Float::na(); + } +} + +void Column<Float>::read(ArrayCRef<Record> records, + ArrayRef<Float> 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)); } - values_.set(row_id, TypeTraits<Float>::default_value()); } -Column<Float>::Column() : ColumnBase(), values_() {} +Float Column<Float>::parse_datum(const Datum &datum) { + switch (datum.type()) { + case NA_DATA: { + return Float::na(); + } + case FLOAT_DATA: { + return datum.as_float(); + } + default: { + throw "Wrong data type"; // TODO + } + } +} } // namespace impl } // namespace grnxx Modified: lib/grnxx/impl/column/scalar/float.hpp (+25 -27) =================================================================== --- lib/grnxx/impl/column/scalar/float.hpp 2014-11-06 22:55:55 +0900 (809efd8) +++ lib/grnxx/impl/column/scalar/float.hpp 2014-11-06 23:41:38 +0900 (1e65fd5) @@ -1,56 +1,54 @@ #ifndef GRNXX_IMPL_COLUMN_SCALAR_FLOAT_HPP #define GRNXX_IMPL_COLUMN_SCALAR_FLOAT_HPP -#include "grnxx/impl/column/column.hpp" +#include "grnxx/impl/column/base.hpp" namespace grnxx { namespace impl { +template <typename T> class Column; + template <> class Column<Float> : public ColumnBase { public: // -- Public API (grnxx/column.hpp) -- - bool set(Error *error, Int row_id, const Datum &datum); - bool get(Error *error, Int row_id, Datum *datum) const; + Column(Table *table, const String &name, const ColumnOptions &options); + ~Column(); - // -- Internal API (grnxx/impl/column/column_base.hpp) -- + void set(Int row_id, const Datum &datum); + void get(Int row_id, Datum *datum) const; - ~Column(); + bool contains(const Datum &datum) const; + Int find_one(const Datum &datum) const; - bool set_default_value(Error *error, Int row_id); + // -- Internal API (grnxx/impl/column/base.hpp) -- + + // Unset the value. void unset(Int row_id); // -- 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<Column> create(Error *error, - Table *table, - const StringCRef &name, - const ColumnOptions &options); - - // Return a value identified by "row_id". + // Return a value. // - // Assumes that "row_id" is valid. Otherwise, the result is undefined. + // If "row_id" is valid, returns the stored value. + // If "row_id" is invalid, returns N/A. Float get(Int row_id) const { - return values_[row_id]; - } - - // Read values. - void read(ArrayCRef<Record> records, ArrayRef<Float> values) const { - for (Int i = 0; i < records.size(); ++i) { - values.set(i, get(records.get_row_id(i))); + size_t value_id = row_id.value(); + if (value_id >= values_.size()) { + return Float::na(); } + return values_[value_id]; } + // Read values. + // + // On failure, throws an exception. + void read(ArrayCRef<Record> records, ArrayRef<Float> values) const; - private: + protected: Array<Float> values_; - Column(); + static Float parse_datum(const Datum &datum); }; } // namespace impl -------------- next part -------------- HTML����������������������������... 다운로드