[Groonga-commit] groonga/grnxx at 8fa63b8 [master] Add Column<Vector<Bool>>. (#110)

Back to archive index

susumu.yata null+****@clear*****
Tue Dec 16 10:54:29 JST 2014


susumu.yata	2014-11-17 17:13:49 +0900 (Mon, 17 Nov 2014)

  New Revision: 8fa63b869f78608d28a6178f0c469af6a867324a
  https://github.com/groonga/grnxx/commit/8fa63b869f78608d28a6178f0c469af6a867324a

  Message:
    Add Column<Vector<Bool>>. (#110)

  Modified files:
    lib/grnxx/impl/column/base.cpp
    lib/grnxx/impl/column/vector.hpp
    lib/grnxx/impl/column/vector/Makefile.am
    lib/grnxx/impl/column/vector/bool.cpp
    lib/grnxx/impl/column/vector/bool.hpp

  Modified: lib/grnxx/impl/column/base.cpp (+4 -4)
===================================================================
--- lib/grnxx/impl/column/base.cpp    2014-11-17 16:25:48 +0900 (797c86f)
+++ lib/grnxx/impl/column/base.cpp    2014-11-17 17:13:49 +0900 (97d4f55)
@@ -199,10 +199,10 @@ std::unique_ptr<ColumnBase> ColumnBase::create(
       column.reset(new impl::Column<Text>(table, name, options));
       break;
     }
-//    case BOOL_VECTOR_DATA: {
-//      column.reset(new impl::Column<Vector<Bool>>(table, name, options));
-//      break;
-//    }
+    case BOOL_VECTOR_DATA: {
+      column.reset(new impl::Column<Vector<Bool>>(table, name, options));
+      break;
+    }
 //    case INT_VECTOR_DATA: {
 //      column.reset(new impl::Column<Vector<Int>>(table, name, options));
 //      break;

  Modified: lib/grnxx/impl/column/vector.hpp (+1 -1)
===================================================================
--- lib/grnxx/impl/column/vector.hpp    2014-11-17 16:25:48 +0900 (1e2876c)
+++ lib/grnxx/impl/column/vector.hpp    2014-11-17 17:13:49 +0900 (1721cf5)
@@ -1,7 +1,7 @@
 #ifndef GRNXX_IMPL_COLUMN_VECTOR_HPP
 #define GRNXX_IMPL_COLUMN_VECTOR_HPP
 
-//#include "grnxx/impl/column/vector/bool.hpp"
+#include "grnxx/impl/column/vector/bool.hpp"
 //#include "grnxx/impl/column/vector/float.hpp"
 //#include "grnxx/impl/column/vector/geo_point.hpp"
 //#include "grnxx/impl/column/vector/int.hpp"

  Modified: lib/grnxx/impl/column/vector/Makefile.am (+2 -2)
===================================================================
--- lib/grnxx/impl/column/vector/Makefile.am    2014-11-17 16:25:48 +0900 (4c68d73)
+++ lib/grnxx/impl/column/vector/Makefile.am    2014-11-17 17:13:49 +0900 (01b77d1)
@@ -8,9 +8,9 @@ lib_LTLIBRARIES = libgrnxx_impl_column_vector.la
 
 libgrnxx_impl_column_vector_la_LDFLAGS = @AM_LTLDFLAGS@
 
-libgrnxx_impl_column_vector_la_SOURCES =
+libgrnxx_impl_column_vector_la_SOURCES =	\
+	bool.cpp
 
-#	bool.cpp				\
 #	float.cpp				\
 #	geo_point.cpp				\
 #	int.cpp					\

  Modified: lib/grnxx/impl/column/vector/bool.cpp (+160 -0)
===================================================================
--- lib/grnxx/impl/column/vector/bool.cpp    2014-11-17 16:25:48 +0900 (e69de29)
+++ lib/grnxx/impl/column/vector/bool.cpp    2014-11-17 17:13:49 +0900 (80ffd9f)
@@ -0,0 +1,160 @@
+#include "grnxx/impl/column/vector/bool.hpp"
+
+#include <cstring>
+
+#include "grnxx/impl/db.hpp"
+#include "grnxx/impl/table.hpp"
+//#include "grnxx/impl/index.hpp"
+
+namespace grnxx {
+namespace impl {
+
+Column<Vector<Bool>>::Column(Table *table,
+                             const String &name,
+                             const ColumnOptions &)
+    : ColumnBase(table, name, BOOL_VECTOR_DATA),
+      headers_(),
+      bodies_() {}
+
+Column<Vector<Bool>>::~Column() {}
+
+void Column<Vector<Bool>>::set(Int row_id, const Datum &datum) {
+  Vector<Bool> 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;
+  }
+  Vector<Bool> old_value = get(row_id);
+  if ((old_value == new_value).is_true()) {
+    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 >= headers_.size()) {
+    headers_.resize(value_id + 1, na_header());
+  }
+  // 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;
+//  }
+  // TODO: Error handling.
+  size_t offset = bodies_.size();
+  size_t size = new_value.size().value();
+  uint64_t header;
+  if (size < 0xFFFF) {
+    bodies_.resize(offset + size);
+    std::memcpy(&bodies_[offset], new_value.data(), size);
+    header = (offset << 16) | size;
+  } else {
+    // The size of a long vector is stored in front of the body.
+    if ((offset % sizeof(uint64_t)) != 0) {
+      offset += sizeof(uint64_t) - (offset % sizeof(uint64_t));
+    }
+    bodies_.resize(offset + sizeof(uint64_t) + size);
+    *reinterpret_cast<uint64_t *>(&bodies_[offset]) = size;
+    std::memcpy(&bodies_[offset + sizeof(uint64_t)], new_value.data(), size);
+    header = (offset << 16) | 0xFFFF;
+  }
+  headers_[value_id] = header;
+}
+
+void Column<Vector<Bool>>::get(Int row_id, Datum *datum) const {
+  size_t value_id = row_id.value();
+  if (value_id >= headers_.size()) {
+    *datum = Vector<Bool>::na();
+  } else {
+    // TODO
+    *datum = get(row_id);
+  }
+}
+
+bool Column<Vector<Bool>>::contains(const Datum &datum) const {
+  // TODO: Use an index if exists.
+  Vector<Bool> value = parse_datum(datum);
+  if (value.is_na()) {
+    for (size_t i = 0; i < headers_.size(); ++i) {
+      if (headers_[i] == na_header()) {
+        return true;
+      }
+    }
+  } else {
+    for (size_t i = 0; i < headers_.size(); ++i) {
+      // TODO: Improve this.
+      if ((get(Int(i)) == value).is_true()) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+Int Column<Vector<Bool>>::find_one(const Datum &datum) const {
+  // TODO: Use an index if exists.
+  Vector<Bool> value = parse_datum(datum);
+  if (value.is_na()) {
+    for (size_t i = 0; i < headers_.size(); ++i) {
+      if (headers_[i] == na_header()) {
+        return Int(i);
+      }
+    }
+  } else {
+    for (size_t i = 0; i < headers_.size(); ++i) {
+      // TODO: Improve this.
+      if ((get(Int(i)) == value).is_true()) {
+        return Int(i);
+      }
+    }
+  }
+  return Int::na();
+}
+
+void Column<Vector<Bool>>::unset(Int row_id) {
+  Vector<Bool> 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);
+//    }
+    headers_[row_id.value()] = na_header();
+  }
+}
+
+void Column<Vector<Bool>>::read(ArrayCRef<Record> records,
+                                ArrayRef<Vector<Bool>> 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));
+  }
+}
+
+Vector<Bool> Column<Vector<Bool>>::parse_datum(const Datum &datum) {
+  switch (datum.type()) {
+    case NA_DATA: {
+      return Vector<Bool>::na();
+    }
+    case BOOL_VECTOR_DATA: {
+      return datum.as_bool_vector();
+    }
+    default: {
+      throw "Wrong data type";  // TODO
+    }
+  }
+}
+
+}  // namespace impl
+}  // namespace grnxx

  Modified: lib/grnxx/impl/column/vector/bool.hpp (+68 -2)
===================================================================
--- lib/grnxx/impl/column/vector/bool.hpp    2014-11-17 16:25:48 +0900 (6aa01ac)
+++ lib/grnxx/impl/column/vector/bool.hpp    2014-11-17 17:13:49 +0900 (992a656)
@@ -1,12 +1,78 @@
 #ifndef GRNXX_IMPL_COLUMN_VECTOR_BOOL_HPP
 #define GRNXX_IMPL_COLUMN_VECTOR_BOOL_HPP
 
-#include "grnxx/impl/column/column.hpp"
+#include <limits>
+#include <cstdint>
+
+#include "grnxx/impl/column/base.hpp"
 
 namespace grnxx {
 namespace impl {
 
-// TODO
+template <typename T> class Column;
+
+template <>
+class Column<Vector<Bool>> : 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) --
+
+  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.
+  //
+  // TODO: Vector cannot reuse allocated memory because of this interface.
+  Vector<Bool> get(Int row_id) const {
+    size_t value_id = row_id.value();
+    if (value_id >= headers_.size()) {
+      return Vector<Bool>::na();
+    }
+    if (headers_[value_id] == na_header()) {
+      return Vector<Bool>::na();
+    }
+    size_t size = headers_[value_id] & 0xFFFF;
+    if (size == 0) {
+      return Vector<Bool>(nullptr, 0);
+    }
+    size_t offset = headers_[value_id] >> 16;
+    if (size < 0xFFFF) {
+      return Vector<Bool>(&bodies_[offset], size);
+    } else {
+      // The size of a long text is stored in front of the body.
+      size = *reinterpret_cast<const uint64_t *>(&bodies_[offset]);
+      return Vector<Bool>(&bodies_[offset + sizeof(uint64_t)], size);
+    }
+  }
+  // Read values.
+  //
+  // On failure, throws an exception.
+  void read(ArrayCRef<Record> records, ArrayRef<Vector<Bool>> values) const;
+
+ private:
+  Array<uint64_t> headers_;
+  Array<Bool> bodies_;
+
+  static constexpr uint64_t na_header() {
+    return std::numeric_limits<uint64_t>::max();
+  }
+
+  static Vector<Bool> parse_datum(const Datum &datum);
+};
 
 }  // namespace impl
 }  // namespace grnxx
-------------- next part --------------
HTML����������������������������...
다운로드 



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