[Groonga-commit] groonga/grnxx at 1baeb80 [new_data_types] Enable a draft version of Column<Float>.

Back to archive index

susumu.yata null+****@clear*****
Thu Nov 6 23:41:38 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����������������������������...
下載 



More information about the Groonga-commit mailing list
Back to archive index