[Groonga-commit] groonga/grnxx at b976fc5 [new_data_types] Add a draft version of Column<Int>.

Back to archive index

susumu.yata null+****@clear*****
Thu Nov 6 19:51:13 JST 2014


susumu.yata	2014-11-06 19:51:13 +0900 (Thu, 06 Nov 2014)

  New Revision: b976fc5b085fdd4722585ae480dff6b398e1f741
  https://github.com/groonga/grnxx/commit/b976fc5b085fdd4722585ae480dff6b398e1f741

  Message:
    Add a draft version of Column<Int>.

  Modified files:
    lib/grnxx/impl/column/base.cpp
    lib/grnxx/impl/column/base.hpp
    lib/grnxx/impl/column/scalar.hpp
    lib/grnxx/impl/column/scalar/Makefile.am
    lib/grnxx/impl/column/scalar/int.cpp
    lib/grnxx/impl/column/scalar/int.hpp
    lib/grnxx/impl/table.cpp

  Modified: lib/grnxx/impl/column/base.cpp (+7 -7)
===================================================================
--- lib/grnxx/impl/column/base.cpp    2014-11-06 19:47:48 +0900 (caf5474)
+++ lib/grnxx/impl/column/base.cpp    2014-11-06 19:51:13 +0900 (cda986b)
@@ -183,10 +183,10 @@ std::unique_ptr<ColumnBase> ColumnBase::create(
       column.reset(new impl::Column<Bool>(table, name, options));
       break;
     }
-//    case INT_DATA: {
-//      column.reset(new impl::Column<Int>(table, name, options));
-//      break;
-//    }
+    case INT_DATA: {
+      column.reset(new impl::Column<Int>(table, name, options));
+      break;
+    }
 //    case FLOAT_DATA: {
 //      column.reset(new impl::Column<Float>(table, name, options));
 //      break;
@@ -249,9 +249,9 @@ void ColumnBase::set_key(Int, const Datum &) {
   throw "Not supported";  // TODO
 }
 
-void ColumnBase::clear_references(Int) {
-  throw "Not supported";  // TODO
-}
+//void ColumnBase::clear_references(Int) {
+//  throw "Not supported";  // TODO
+//}
 
 //bool ColumnBase::initialize_base(Error *error,
 //                                 Table *table,

  Modified: lib/grnxx/impl/column/base.hpp (+2 -2)
===================================================================
--- lib/grnxx/impl/column/base.hpp    2014-11-06 19:47:48 +0900 (ec8cb58)
+++ lib/grnxx/impl/column/base.hpp    2014-11-06 19:51:13 +0900 (1f9a90e)
@@ -103,8 +103,8 @@ class ColumnBase : public ColumnInterface {
   // Unset the value.
   virtual void unset(Int row_id) = 0;
 
-  // Replace references to "row_id" with NULL.
-  virtual void clear_references(Int row_id);
+//  // Replace references to "row_id" with NULL.
+//  virtual void clear_references(Int row_id);
 
  protected:
   Table *table_;

  Modified: lib/grnxx/impl/column/scalar.hpp (+1 -1)
===================================================================
--- lib/grnxx/impl/column/scalar.hpp    2014-11-06 19:47:48 +0900 (1b33481)
+++ lib/grnxx/impl/column/scalar.hpp    2014-11-06 19:51:13 +0900 (a2f7635)
@@ -4,7 +4,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/int.hpp"
+#include "grnxx/impl/column/scalar/int.hpp"
 //#include "grnxx/impl/column/scalar/text.hpp"
 
 #endif  // GRNXX_IMPL_COLUMN_SCALAR_HPP

  Modified: lib/grnxx/impl/column/scalar/Makefile.am (+2 -2)
===================================================================
--- lib/grnxx/impl/column/scalar/Makefile.am    2014-11-06 19:47:48 +0900 (690cb71)
+++ lib/grnxx/impl/column/scalar/Makefile.am    2014-11-06 19:51:13 +0900 (491594f)
@@ -9,11 +9,11 @@ lib_LTLIBRARIES = libgrnxx_impl_column_scalar.la
 libgrnxx_impl_column_scalar_la_LDFLAGS = @AM_LTLDFLAGS@
 
 libgrnxx_impl_column_scalar_la_SOURCES =	\
-	bool.cpp
+	bool.cpp				\
+	int.cpp
 
 #	float.cpp				\
 #	geo_point.cpp				\
-#	int.cpp					\
 #	text.cpp
 
 libgrnxx_impl_column_scalar_includedir = ${includedir}/grnxx/impl/column/scalar

  Modified: lib/grnxx/impl/column/scalar/int.cpp (+245 -226)
===================================================================
--- lib/grnxx/impl/column/scalar/int.cpp    2014-11-06 19:47:48 +0900 (bb80bfa)
+++ lib/grnxx/impl/column/scalar/int.cpp    2014-11-06 19:51:13 +0900 (7fd800b)
@@ -1,279 +1,298 @@
-#include "grnxx/impl/column/column_int.hpp"
+#include "grnxx/impl/column/scalar/int.hpp"
 
-#include "grnxx/cursor.hpp"
 #include "grnxx/impl/db.hpp"
 #include "grnxx/impl/table.hpp"
-#include "grnxx/index.hpp"
+//#include "grnxx/impl/index.hpp"
 
-#include <unordered_set>
+//#include <unordered_set>
 
 namespace grnxx {
 namespace impl {
 
-bool Column<Int>::set(Error *error, Int row_id, const Datum &datum) {
-  if (datum.type() != INT_DATA) {
-    GRNXX_ERROR_SET(error, INVALID_ARGUMENT, "Wrong data type");
-    return false;
-  }
-  if (!table_->test_row(error, row_id)) {
-    return false;
-  }
-  if (ref_table_) {
-    if (!ref_table_->test_row(error, datum.force_int())) {
-      return false;
-    }
-  }
-  Int old_value = get(row_id);
-  Int new_value = datum.force_int();
-  if (new_value != old_value) {
-    if (has_key_attribute_ && contains(datum)) {
-      GRNXX_ERROR_SET(error, ALREADY_EXISTS, "Key duplicate");
-      return false;
-    }
-    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);
+Column<Int>::Column(Table *table,
+                    const String &name,
+                    const ColumnOptions &options)
+    : ColumnBase(table, name, INT_DATA),
+      values_() {
+  if (!options.reference_table_name.is_empty()) {
+    reference_table_ = table->_db()->find_table(options.reference_table_name);
+    if (!reference_table_) {
+      throw "Table not found";  // TODO
     }
   }
-  values_.set(row_id, new_value);
-  return true;
 }
 
-bool Column<Int>::get(Error *error, Int row_id, Datum *datum) const {
-  if (!table_->test_row(error, row_id)) {
-    return false;
-  }
-  *datum = values_[row_id];
-  return true;
-}
+Column<Int>::~Column() {}
 
-unique_ptr<Column<Int>> Column<Int>::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;
+void Column<Int>::set(Int row_id, const Datum &datum) {
+  Int new_value = parse_datum(datum);
+  if (!table_->test_row(row_id)) {
+    throw "Invalid row ID";  // TODO
   }
-  if (!column->initialize_base(error, table, name, INT_DATA, options)) {
-    return nullptr;
+  if (is_key_) {
+    if (new_value.is_na()) {
+      throw "N/A key";  // TODO
+    }
   }
-  if (!column->values_.resize(error, table->max_row_id() + 1,
-                              TypeTraits<Int>::default_value())) {
-    return nullptr;
+  if (new_value.is_na()) {
+    unset(row_id);
+    return;
   }
-  if (column->ref_table()) {
-    if (!column->ref_table_->append_referrer_column(error, column.get())) {
-      return nullptr;
+  if (reference_table_) {
+    if (!reference_table_->test_row(new_value)) {
+      throw "Invalid reference";  // TODO
     }
   }
-  return column;
-}
-
-Column<Int>::~Column() {}
-
-bool Column<Int>::set_key_attribute(Error *error) {
-  if (has_key_attribute_) {
-    GRNXX_ERROR_SET(error, INVALID_OPERATION,
-                    "This column is a key column");
-    return false;
+  Int old_value = get(row_id);
+  if (old_value == new_value) {
+    return;
   }
-  // TODO: An index should be used if possible.
-  try {
-    std::unordered_set<Int> set;
-    // TODO: Functor-based inline callback may be better in this case,
-    //       because it does not require memory allocation.
-    auto cursor = table_->create_cursor(nullptr);
-    if (!cursor) {
-      return false;
-    }
-    Array<Record> records;
-    for ( ; ; ) {
-      auto result = cursor->read(nullptr, 1024, &records);
-      if (!result.is_ok) {
-        return false;
-      } else {
-        break;
-      }
-      for (Int i = 0; i < result.count; ++i) {
-        if (!set.insert(values_[records.get_row_id(i)]).second) {
-          GRNXX_ERROR_SET(error, INVALID_OPERATION, "Key duplicate");
-          return false;
-        }
-      }
-      records.clear();
-    }
-  } catch (...) {
-    GRNXX_ERROR_SET(error, NO_MEMORY, "Memory allocation failed");
-    return false;
+  if (is_key_ && contains(datum)) {
+    throw "Key already exists";  // TODO
+  }
+  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, Int::na());
   }
-  has_key_attribute_ = true;
-  return true;
+  // 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<Int>::unset_key_attribute(Error *error) {
-  if (!has_key_attribute_) {
-    GRNXX_ERROR_SET(error, INVALID_OPERATION,
-                    "This column is not a key column");
-    return false;
+void Column<Int>::get(Int row_id, Datum *datum) const {
+  size_t value_id = row_id.value();
+  if (value_id >= values_.size()) {
+    *datum = Int::na();
+  } else {
+    *datum = values_[value_id];
   }
-  has_key_attribute_ = false;
-  return true;
 }
 
-bool Column<Int>::set_initial_key(Error *error,
-                                  Int row_id,
-                                  const Datum &key) {
-  if (!has_key_attribute_) {
-    GRNXX_ERROR_SET(error, INVALID_OPERATION,
-                    "This column is not a key column");
-    return false;
-  }
-  if (has_key_attribute_ && contains(key)) {
-    GRNXX_ERROR_SET(error, ALREADY_EXISTS, "Key duplicate");
-    return false;
-  }
-  if (row_id >= values_.size()) {
-    if (!values_.resize(error, row_id + 1, TypeTraits<Int>::default_value())) {
-      return false;
+bool Column<Int>::contains(const Datum &datum) const {
+  // TODO: Use an index if exists.
+  Int 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;
+      }
     }
-  }
-  Int value = key.force_int();
-  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 true;
       }
-      return false;
     }
   }
-  values_.set(row_id, value);
-  return true;
+  return false;
 }
 
-bool Column<Int>::set_default_value(Error *error, Int row_id) {
-  if (has_key_attribute_) {
-    GRNXX_ERROR_SET(error, INVALID_OPERATION,
-                    "This column is a key column");
-    return false;
-  }
-  if (row_id >= values_.size()) {
-    if (!values_.resize(error, row_id + 1, TypeTraits<Int>::default_value())) {
-      return false;
+Int Column<Int>::find_one(const Datum &datum) const {
+  // TODO: Use an index if exists.
+  Int 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);
+      }
     }
-  }
-  Int value = TypeTraits<Int>::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();
+
+//  // TODO: Cursor should not be used because it takes time.
+//  //       Also, cursor operations can fail due to memory allocation.
+//  Int value = datum.force_int();
+//  if (indexes_.size() != 0) {
+//    return indexes_[0]->find_one(datum);
+//  } else {
+//    // TODO: A full scan takes time.
+//    //       An index should be required for a key column.
+
+//    // TODO: Functor-based inline callback may be better in this case,
+//    //       because it does not require memory allocation.
+
+//    // Scan the column to find "value".
+//    auto cursor = table_->create_cursor(nullptr);
+//    if (!cursor) {
+//      return NULL_ROW_ID;
+//    }
+//    Array<Record> records;
+//    for ( ; ; ) {
+//      auto result = cursor->read(nullptr, 1024, &records);
+//      if (!result.is_ok || result.count == 0) {
+//        return NULL_ROW_ID;
+//      }
+//      for (Int i = 0; i < result.count; ++i) {
+//        if (values_[records.get_row_id(i)] == value) {
+//          return records.get_row_id(i);
+//        }
+//      }
+//      records.clear();
+//    }
+//  }
+//  return NULL_ROW_ID;
 }
 
-void Column<Int>::unset(Int row_id) {
-  for (Int i = 0; i < num_indexes(); ++i) {
-    indexes_[i]->remove(nullptr, row_id, get(row_id));
+void Column<Int>::set_key_attribute() {
+  if (is_key_) {
+    throw "Key column";  // TODO
   }
-  values_.set(row_id, TypeTraits<Int>::default_value());
+  throw "Not supported yet";  // TODO
+
+//  // TODO: An index should be used if possible.
+//  try {
+//    std::unordered_set<Int> set;
+//    // TODO: Functor-based inline callback may be better in this case,
+//    //       because it does not require memory allocation.
+//    auto cursor = table_->create_cursor(nullptr);
+//    if (!cursor) {
+//      return false;
+//    }
+//    Array<Record> records;
+//    for ( ; ; ) {
+//      auto result = cursor->read(nullptr, 1024, &records);
+//      if (!result.is_ok) {
+//        return false;
+//      } else {
+//        break;
+//      }
+//      for (Int i = 0; i < result.count; ++i) {
+//        if (!set.insert(values_[records.get_row_id(i)]).second) {
+//          GRNXX_ERROR_SET(error, INVALID_OPERATION, "Key duplicate");
+//          return false;
+//        }
+//      }
+//      records.clear();
+//    }
+//  } catch (...) {
+//    GRNXX_ERROR_SET(error, NO_MEMORY, "Memory allocation failed");
+//    return false;
+//  }
+//  has_key_attribute_ = true;
+//  return true;
 }
 
-Int Column<Int>::find_one(const Datum &datum) const {
-  // TODO: Cursor should not be used because it takes time.
-  //       Also, cursor operations can fail due to memory allocation.
-  Int value = datum.force_int();
-  if (indexes_.size() != 0) {
-    return indexes_[0]->find_one(datum);
-  } else {
-    // TODO: A full scan takes time.
-    //       An index should be required for a key column.
+void Column<Int>::unset_key_attribute() {
+  if (!is_key_) {
+    throw "Not key column";  // TODO
+  }
+  is_key_ = true;
+}
 
-    // TODO: Functor-based inline callback may be better in this case,
-    //       because it does not require memory allocation.
+void Column<Int>::set_key(Int row_id, const Datum &key) {
+  if (!is_key_) {
+    throw "Not key column";  // TODO
+  }
+  if (contains(key)) {
+    throw "Key already exists";  // TODO
+  }
+  size_t value_id = row_id.value();
+  if (value_id >= values_.size()) {
+    values_.resize(value_id + 1, Int::na());
+  }
+  Int value = parse_datum(key);
+  // TODO: Update indexes if exist.
+//  for (size_t i = 0; i < num_indexes(); ++i) try {
+//    indexes_[i]->insert(row_id, value);
+//  } catch (...) {
+//    for (size_t j = 0; j < i; ++j) {
+//      indexes_[j]->remove(row_id, value);
+//    }
+//    throw;
+//  }
+  values_[value_id] = value;
+}
 
-    // Scan the column to find "value".
-    auto cursor = table_->create_cursor(nullptr);
-    if (!cursor) {
-      return NULL_ROW_ID;
-    }
-    Array<Record> records;
-    for ( ; ; ) {
-      auto result = cursor->read(nullptr, 1024, &records);
-      if (!result.is_ok || result.count == 0) {
-        return NULL_ROW_ID;
-      }
-      for (Int i = 0; i < result.count; ++i) {
-        if (values_[records.get_row_id(i)] == value) {
-          return records.get_row_id(i);
-        }
-      }
-      records.clear();
-    }
+void Column<Int>::unset(Int row_id) {
+  Int 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()] = Int::na();
   }
-  return NULL_ROW_ID;
 }
 
-void Column<Int>::clear_references(Int row_id) {
-  // TODO: Cursor should not be used to avoid errors.
-  if (indexes_.size() != 0) {
-    auto cursor = indexes_[0]->find(nullptr, Int(0));
-    if (!cursor) {
-      // Error.
-      return;
-    }
-    Array<Record> records;
-    for ( ; ; ) {
-      auto result = cursor->read(nullptr, 1024, &records);
-      if (!result.is_ok) {
-        // Error.
-        return;
-      } else if (result.count == 0) {
-        return;
-      }
-      for (Int i = 0; i < records.size(); ++i) {
-        set(nullptr, row_id, NULL_ROW_ID);
-      }
-      records.clear();
+//void Column<Int>::clear_references(Int row_id) {
+//  // TODO: Cursor should not be used to avoid errors.
+//  if (indexes_.size() != 0) {
+//    auto cursor = indexes_[0]->find(nullptr, Int(0));
+//    if (!cursor) {
+//      // Error.
+//      return;
+//    }
+//    Array<Record> records;
+//    for ( ; ; ) {
+//      auto result = cursor->read(nullptr, 1024, &records);
+//      if (!result.is_ok) {
+//        // Error.
+//        return;
+//      } else if (result.count == 0) {
+//        return;
+//      }
+//      for (Int i = 0; i < records.size(); ++i) {
+//        set(nullptr, row_id, NULL_ROW_ID);
+//      }
+//      records.clear();
+//    }
+//  } else {
+//    auto cursor = table_->create_cursor(nullptr);
+//    if (!cursor) {
+//      // Error.
+//      return;
+//    }
+//    Array<Record> records;
+//    for ( ; ; ) {
+//      auto result = cursor->read(nullptr, 1024, &records);
+//      if (!result.is_ok) {
+//        // Error.
+//        return;
+//      } else if (result.count == 0) {
+//        return;
+//      }
+//      for (Int i = 0; i < records.size(); ++i) {
+//        if (values_[records.get_row_id(i)] == row_id) {
+//          values_[records.get_row_id(i)] = NULL_ROW_ID;
+//        }
+//      }
+//      records.clear();
+//    }
+//  }
+//}
+
+Int Column<Int>::parse_datum(const Datum &datum) {
+  switch (datum.type()) {
+    case NA_DATA: {
+      return Int::na();
     }
-  } else {
-    auto cursor = table_->create_cursor(nullptr);
-    if (!cursor) {
-      // Error.
-      return;
+    case INT_DATA: {
+      return datum.as_int();
     }
-    Array<Record> records;
-    for ( ; ; ) {
-      auto result = cursor->read(nullptr, 1024, &records);
-      if (!result.is_ok) {
-        // Error.
-        return;
-      } else if (result.count == 0) {
-        return;
-      }
-      for (Int i = 0; i < records.size(); ++i) {
-        if (values_[records.get_row_id(i)] == row_id) {
-          values_[records.get_row_id(i)] = NULL_ROW_ID;
-        }
-      }
-      records.clear();
+    default: {
+      throw "Wrong data type";  // TODO
     }
   }
 }
 
-Column<Int>::Column() : ColumnBase(), values_() {}
-
 }  // namespace impl
 }  // namespace grnxx

  Modified: lib/grnxx/impl/column/scalar/int.hpp (+28 -32)
===================================================================
--- lib/grnxx/impl/column/scalar/int.hpp    2014-11-06 19:47:48 +0900 (5046b64)
+++ lib/grnxx/impl/column/scalar/int.hpp    2014-11-06 19:51:13 +0900 (d8cff6e)
@@ -1,62 +1,58 @@
 #ifndef GRNXX_IMPL_COLUMN_SCALAR_INT_HPP
 #define GRNXX_IMPL_COLUMN_SCALAR_INT_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<Int> : public ColumnBase {
  public:
-  // -- Public API --
+  // -- 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 --
+  void set(Int row_id, const Datum &datum);
+  void get(Int row_id, Datum *datum) const;
 
-  // 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);
+  bool contains(const Datum &datum) const;
+  Int find_one(const Datum &datum) const;
 
-  ~Column();
+  // -- Internal API (grnxx/impl/column/base.hpp) --
 
-  bool set_key_attribute(Error *error);
-  bool unset_key_attribute(Error *error);
+  void set_key_attribute();
+  void unset_key_attribute();
 
-  bool set_initial_key(Error *error, Int row_id, const Datum &key);
-  bool set_default_value(Error *error, Int row_id);
+  void set_key(Int row_id, const Datum &key);
   void unset(Int row_id);
-
-  Int find_one(const Datum &datum) const;
-
   void clear_references(Int row_id);
 
-  // Return a value identified by "row_id".
+  // -- Internal API --
+
+  // 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.
   Int get(Int row_id) const {
-    return values_[row_id];
-  }
-
-  // Read values.
-  void read(ArrayCRef<Record> records, ArrayRef<Int> 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 Int::na();
     }
+    return values_[value_id];
   }
+  // Read values.
+  //
+  // On failure, throws an exception.
+  void read(ArrayCRef<Record> records, ArrayRef<Bool> values) const;
 
  private:
   Array<Int> values_;
 
-  Column();
+  static Int parse_datum(const Datum &datum);
 };
 
 }  // namespace impl

  Modified: lib/grnxx/impl/table.cpp (+8 -4)
===================================================================
--- lib/grnxx/impl/table.cpp    2014-11-06 19:47:48 +0900 (5a26a42)
+++ lib/grnxx/impl/table.cpp    2014-11-06 19:51:13 +0900 (8c1f585)
@@ -235,6 +235,9 @@ ColumnBase *Table::create_column(const String &name,
   columns_.reserve(columns_.size() + 1);
   std::unique_ptr<ColumnBase> new_column =
       ColumnBase::create(this, name, data_type, options);
+  if (new_column->_reference_table()) {
+    new_column->_reference_table()->append_referrer_column(new_column.get());
+  }
   columns_.push_back(std::move(new_column));
   return columns_.back().get();
 }
@@ -398,10 +401,11 @@ void Table::remove_row(Int row_id) {
     columns_[i]->unset(row_id);
   }
   invalidate_row(row_id);
-  // Clear referrers.
-  for (size_t i = 0; i < referrer_columns_.size(); ++i) {
-    referrer_columns_[i]->clear_references(row_id);
-  }
+
+  // TODO: Clear referrers.
+//  for (size_t i = 0; i < referrer_columns_.size(); ++i) {
+//    referrer_columns_[i]->clear_references(row_id);
+//  }
 }
 
 Int Table::find_row(const Datum &key) const {
-------------- next part --------------
HTML����������������������������...
下載 



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