[Groonga-commit] groonga/grnxx at f695f78 [master] Add Vector<Text>.

Back to archive index

susumu.yata null+****@clear*****
Tue Sep 2 17:49:01 JST 2014


susumu.yata	2014-09-02 17:49:01 +0900 (Tue, 02 Sep 2014)

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

  Message:
    Add Vector<Text>.

  Modified files:
    include/grnxx/datum.hpp
    include/grnxx/types.hpp
    lib/grnxx/column.cpp
    lib/grnxx/column_impl.hpp
    lib/grnxx/expression.cpp

  Modified: include/grnxx/datum.hpp (+12 -2)
===================================================================
--- include/grnxx/datum.hpp    2014-09-02 11:32:50 +0900 (5ea8174)
+++ include/grnxx/datum.hpp    2014-09-02 17:49:01 +0900 (dd52e38)
@@ -22,7 +22,7 @@ class Datum {
   Datum(GeoPoint value)
       : type_(GEO_POINT_DATA),
         geo_point_(value) {}
-  Datum(String value)
+  Datum(Text value)
       : type_(TEXT_DATA),
         text_(value) {}
   Datum(Vector<Bool> value)
@@ -37,6 +37,9 @@ class Datum {
   Datum(Vector<GeoPoint> value)
       : type_(GEO_POINT_VECTOR_DATA),
         geo_point_vector_(value) {}
+  Datum(Vector<Text> value)
+      : type_(TEXT_VECTOR_DATA),
+        text_vector_(value) {}
 
   // Return the data type.
   DataType type() const {
@@ -71,6 +74,9 @@ class Datum {
   Vector<GeoPoint> force_geo_point_vector() const {
     return geo_point_vector_;
   }
+  Vector<Text> force_text_vector() const {
+    return text_vector_;
+  }
 
   // Force the specified interpretation.
   void force(Bool *value) const {
@@ -100,6 +106,9 @@ class Datum {
   void force(Vector<GeoPoint> *value) const {
     *value = geo_point_vector_;
   }
+  void force(Vector<Text> *value) const {
+    *value = text_vector_;
+  }
 
  private:
   DataType type_;
@@ -108,11 +117,12 @@ class Datum {
     Int int_;
     Float float_;
     GeoPoint geo_point_;
-    String text_;
+    Text text_;
     Vector<Bool> bool_vector_;
     Vector<Int> int_vector_;
     Vector<Float> float_vector_;
     Vector<GeoPoint> geo_point_vector_;
+    Vector<Text> text_vector_;
   };
 };
 

  Modified: include/grnxx/types.hpp (+88 -0)
===================================================================
--- include/grnxx/types.hpp    2014-09-02 11:32:50 +0900 (08059e7)
+++ include/grnxx/types.hpp    2014-09-02 17:49:01 +0900 (22eec0c)
@@ -454,10 +454,90 @@ inline Bool operator!=(Vector<GeoPoint> lhs, Vector<GeoPoint> rhs) {
   return false;
 }
 
+// TODO: Improve the implementation of Vector<Text>.
+template <>
+class Vector<Text> {
+ public:
+  Vector() = default;
+  Vector(const Text *data, Int size)
+      : is_direct_(1),
+        size_(size),
+        data_(data) {}
+  Vector(const void *headers, const char *bodies, Int size)
+      : is_direct_(0),
+        size_(size),
+        headers_(static_cast<const Header *>(headers)),
+        bodies_(bodies) {}
+  Vector(const Vector &) = default;
+
+  Vector &operator=(const Vector &) = default;
+
+  // Return the number of Text values.
+  Int size() const {
+    return static_cast<Int>(size_);
+  }
+  // Return the "i"-th Text value.
+  //
+  // If "i" is invalid, the result is undefined.
+  Text get(Int i) const {
+    if (is_direct_) {
+      return data_[i];
+    } else {
+      return Text(&bodies_[headers_[i].offset], headers_[i].size);
+    }
+  }
+
+  // Return the "i"-th Text value.
+  //
+  // If "i" is invalid, the result is undefined.
+  Text operator[](Int i) const {
+    return get(i);
+  }
+
+ private:
+  struct Header {
+    Int offset;
+    Int size;
+  };
+  bool is_direct_;
+  Int size_;
+  union {
+    const Text *data_;
+    struct {
+      const Header *headers_;
+      const char *bodies_;
+    };
+  };
+};
+
+inline Bool operator==(Vector<Text> lhs, Vector<Text> rhs) {
+  if (lhs.size() != rhs.size()) {
+    return false;
+  }
+  for (Int i = 0; i < lhs.size(); ++i) {
+    if (lhs[i] != rhs[i]) {
+      return false;
+    }
+  }
+  return true;
+}
+inline Bool operator!=(Vector<Text> lhs, Vector<Text> rhs) {
+  if (lhs.size() != rhs.size()) {
+    return true;
+  }
+  for (Int i = 0; i < lhs.size(); ++i) {
+    if (lhs[i] != rhs[i]) {
+      return true;
+    }
+  }
+  return false;
+}
+
 using BoolVector     = Vector<Bool>;
 using IntVector      = Vector<Int>;
 using FloatVector    = Vector<Float>;
 using GeoPointVector = Vector<GeoPoint>;
+using TextVector     = Vector<Text>;
 
 // Type information.
 template <typename T> struct TypeTraits;
@@ -533,6 +613,14 @@ template <> struct TypeTraits <Vector<GeoPoint>> {
     return Vector<GeoPoint>(nullptr, 0);
   }
 };
+template <> struct TypeTraits <Vector<Text>> {
+  static DataType data_type() {
+    return TEXT_VECTOR_DATA;
+  }
+  static Vector<Text> default_value() {
+    return Vector<Text>(nullptr, 0);
+  }
+};
 
 // Zero is reserved for representing a null reference.
 constexpr Int NULL_ROW_ID = 0;

  Modified: lib/grnxx/column.cpp (+95 -1)
===================================================================
--- lib/grnxx/column.cpp    2014-09-02 11:32:50 +0900 (78a2036)
+++ lib/grnxx/column.cpp    2014-09-02 17:49:01 +0900 (a0de861)
@@ -101,6 +101,9 @@ unique_ptr<Column> Column::create(Error *error,
     case GEO_POINT_VECTOR_DATA: {
       return ColumnImpl<Vector<GeoPoint>>::create(error, table, name, options);
     }
+    case TEXT_VECTOR_DATA: {
+      return ColumnImpl<Vector<Text>>::create(error, table, name, options);
+    }
     default: {
       // TODO: Other data types are not supported yet.
       GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not suported yet");
@@ -546,7 +549,7 @@ ColumnImpl<Vector<Float>>::ColumnImpl() : Column(), headers_(), bodies_() {}
 // -- ColumnImpl<Vector<GeoPoint>> --
 
 bool ColumnImpl<Vector<GeoPoint>>::set(Error *error, Int row_id,
-                                    const Datum &datum) {
+                                       const Datum &datum) {
   if (datum.type() != GEO_POINT_VECTOR_DATA) {
     GRNXX_ERROR_SET(error, INVALID_ARGUMENT, "Wrong data type");
     return false;
@@ -631,4 +634,95 @@ void ColumnImpl<Vector<GeoPoint>>::unset(Int row_id) {
 
 ColumnImpl<Vector<GeoPoint>>::ColumnImpl() : Column(), headers_(), bodies_() {}
 
+// -- ColumnImpl<Vector<Text>> --
+
+bool ColumnImpl<Vector<Text>>::set(Error *error, Int row_id,
+                                   const Datum &datum) {
+  if (datum.type() != TEXT_VECTOR_DATA) {
+    GRNXX_ERROR_SET(error, INVALID_ARGUMENT, "Wrong data type");
+    return false;
+  }
+  if (!table_->test_row(error, row_id)) {
+    return false;
+  }
+  Vector<Text> value = datum.force_text_vector();
+  if (value.size() == 0) {
+    headers_[row_id] = Header{ 0, 0 };
+    return true;
+  }
+  Int text_headers_offset = text_headers_.size();
+  if (!text_headers_.resize(error, text_headers_offset + value.size())) {
+    return false;
+  }
+  Int total_size = 0;
+  for (Int i = 0; i < value.size(); ++i) {
+    total_size += value[i].size();
+  }
+  Int bodies_offset = bodies_.size();
+  if (!bodies_.resize(error, bodies_offset + total_size)) {
+    return false;
+  }
+  headers_[row_id] = Header{ text_headers_offset, value.size() };
+  for (Int i = 0; i < value.size(); ++i) {
+    text_headers_[text_headers_offset + i].offset = bodies_offset;
+    text_headers_[text_headers_offset + i].size = value[i].size();
+    std::memcpy(&bodies_[bodies_offset], value[i].data(), value[i].size());
+    bodies_offset += value[i].size();
+  }
+  return true;
+}
+
+bool ColumnImpl<Vector<Text>>::get(Error *error, Int row_id,
+                                   Datum *datum) const {
+  if (!table_->test_row(error, row_id)) {
+    return false;
+  }
+  *datum = get(row_id);
+  return true;
+}
+
+unique_ptr<ColumnImpl<Vector<Text>>> ColumnImpl<Vector<Text>>::create(
+    Error *error,
+    Table *table,
+    String name,
+    const ColumnOptions &options) {
+  unique_ptr<ColumnImpl> column(new (nothrow) ColumnImpl);
+  if (!column) {
+    GRNXX_ERROR_SET(error, NO_MEMORY, "Memory allocation failed");
+    return nullptr;
+  }
+  if (!column->initialize_base(error, table, name,
+                               TEXT_VECTOR_DATA, options)) {
+    return nullptr;
+  }
+  if (!column->headers_.resize(error, table->max_row_id() + 1,
+                               Header{ 0, 0 })) {
+    return nullptr;
+  }
+  return column;
+}
+
+ColumnImpl<Vector<Text>>::~ColumnImpl() {}
+
+bool ColumnImpl<Vector<Text>>::set_default_value(Error *error,
+                                                     Int row_id) {
+  if (row_id >= headers_.size()) {
+    if (!headers_.resize(error, row_id + 1)) {
+      return false;
+    }
+  }
+  headers_[row_id] = Header{ 0, 0 };
+  return true;
+}
+
+void ColumnImpl<Vector<Text>>::unset(Int row_id) {
+  headers_[row_id] = Header{ 0, 0 };
+}
+
+ColumnImpl<Vector<Text>>::ColumnImpl()
+    : Column(),
+      headers_(),
+      text_headers_(),
+      bodies_() {}
+
 }  // namespace grnxx

  Modified: lib/grnxx/column_impl.hpp (+46 -0)
===================================================================
--- lib/grnxx/column_impl.hpp    2014-09-02 11:32:50 +0900 (77b3aa9)
+++ lib/grnxx/column_impl.hpp    2014-09-02 17:49:01 +0900 (bd31aed)
@@ -282,6 +282,52 @@ class ColumnImpl<Vector<GeoPoint>> : public Column {
   ColumnImpl();
 };
 
+// TODO: Improve the implementation.
+template <>
+class ColumnImpl<Vector<Text>> : public Column {
+ public:
+  // -- Public API --
+
+  bool set(Error *error, Int row_id, const Datum &datum);
+  bool get(Error *error, Int row_id, Datum *datum) const;
+
+  // -- 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<ColumnImpl> create(Error *error,
+                                       Table *table,
+                                       String name,
+                                       const ColumnOptions &options);
+
+  ~ColumnImpl();
+
+  bool set_default_value(Error *error, Int row_id);
+  void unset(Int row_id);
+
+  // Return a value identified by "row_id".
+  //
+  // Assumes that "row_id" is valid. Otherwise, the result is undefined.
+  Vector<Text> get(Int row_id) const {
+    return Vector<Text>(&text_headers_[headers_[row_id].offset],
+                        bodies_.data(), headers_[row_id].size);
+  }
+
+ protected:
+  struct Header {
+    Int offset;
+    Int size;
+  };
+  Array<Header> headers_;
+  Array<Header> text_headers_;
+  Array<char> bodies_;
+
+  ColumnImpl();
+};
+
 }  // namespace grnxx
 
 #endif  // GRNXX_COLUMN_IMPL_HPP

  Modified: lib/grnxx/expression.cpp (+17 -0)
===================================================================
--- lib/grnxx/expression.cpp    2014-09-02 11:32:50 +0900 (b09a278)
+++ lib/grnxx/expression.cpp    2014-09-02 17:49:01 +0900 (def886e)
@@ -2487,6 +2487,7 @@ GRNXX_INSTANTIATE_EXPRESSION_EVALUATE(Vector<Bool>);
 GRNXX_INSTANTIATE_EXPRESSION_EVALUATE(Vector<Int>);
 GRNXX_INSTANTIATE_EXPRESSION_EVALUATE(Vector<Float>);
 GRNXX_INSTANTIATE_EXPRESSION_EVALUATE(Vector<GeoPoint>);
+GRNXX_INSTANTIATE_EXPRESSION_EVALUATE(Vector<Text>);
 #undef GRNXX_INSTANTIATE_EXPRESSION_EVALUATE
 
 template <typename T>
@@ -2672,6 +2673,10 @@ unique_ptr<Node> ExpressionBuilder::create_datum_node(
       return DatumNode<Vector<Float>>::create(error,
                                               datum.force_float_vector());
     }
+    case TEXT_VECTOR_DATA: {
+      return DatumNode<Vector<Text>>::create(error,
+                                             datum.force_text_vector());
+    }
     case GEO_POINT_VECTOR_DATA: {
       return DatumNode<Vector<GeoPoint>>::create(
           error, datum.force_geo_point_vector());
@@ -2740,6 +2745,9 @@ unique_ptr<Node> ExpressionBuilder::create_column_node(
     case GEO_POINT_VECTOR_DATA: {
       return ColumnNode<Vector<GeoPoint>>::create(error, column);
     }
+    case TEXT_VECTOR_DATA: {
+      return ColumnNode<Vector<Text>>::create(error, column);
+    }
     default: {
       // TODO: Other types are not supported yet.
       GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not supported yet");
@@ -3005,6 +3013,11 @@ unique_ptr<Node> ExpressionBuilder::create_equality_test_node(
       return ComparisonNode<Functor>::create(
           error, std::move(arg1), std::move(arg2));
     }
+    case TEXT_VECTOR_DATA: {
+      typedef typename T:: template Comparer<Vector<Text>> Functor;
+      return ComparisonNode<Functor>::create(
+          error, std::move(arg1), std::move(arg2));
+    }
     // TODO: Support other types.
     default: {
       GRNXX_ERROR_SET(error, NOT_SUPPORTED_YET, "Not supported yet");
@@ -3131,6 +3144,10 @@ unique_ptr<Node> ExpressionBuilder::create_subscript_node(
       return SubscriptNode<GeoPoint>::create(
           error, std::move(arg1), std::move(arg2));
     }
+    case TEXT_VECTOR_DATA: {
+      return SubscriptNode<Text>::create(
+          error, std::move(arg1), std::move(arg2));
+    }
     default: {
       GRNXX_ERROR_SET(error, INVALID_OPERAND, "Invalid data type");
       return nullptr;
-------------- next part --------------
HTML����������������������������...
다운로드 



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