Skip to content

Commit

Permalink
Enable a draft version of Column<Float>.
Browse files Browse the repository at this point in the history
  • Loading branch information
s-yata committed Nov 6, 2014
1 parent a9d07b8 commit 1baeb80
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 103 deletions.
8 changes: 4 additions & 4 deletions lib/grnxx/impl/column/base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion lib/grnxx/impl/column/scalar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion lib/grnxx/impl/column/scalar/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
174 changes: 104 additions & 70 deletions lib/grnxx/impl/column/scalar/float.cpp
Original file line number Diff line number Diff line change
@@ -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
52 changes: 25 additions & 27 deletions lib/grnxx/impl/column/scalar/float.hpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down

0 comments on commit 1baeb80

Please sign in to comment.