[Groonga-commit] groonga/grnxx at bb5908f [master] Update ColumnImpl<Text> not to use std::string. (#43)

Back to archive index

susumu.yata null+****@clear*****
Mon Aug 25 11:21:59 JST 2014


susumu.yata	2014-08-25 11:21:59 +0900 (Mon, 25 Aug 2014)

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

  Message:
    Update ColumnImpl<Text> not to use std::string. (#43)

  Modified files:
    lib/grnxx/column.cpp
    lib/grnxx/column_impl.hpp

  Modified: lib/grnxx/column.cpp (+29 -13)
===================================================================
--- lib/grnxx/column.cpp    2014-08-21 13:32:33 +0900 (0ce7ee2)
+++ lib/grnxx/column.cpp    2014-08-25 11:21:59 +0900 (38bffb7)
@@ -214,13 +214,29 @@ bool ColumnImpl<Text>::set(Error *error, Int row_id, const Datum &datum) {
   if (!table_->test_row(error, row_id)) {
     return false;
   }
-  // Note that a Bool object does not have its own address.
   Text value = datum.force_text();
-  try {
-    std::string internal_value(value.data(), value.size());
-    values_[row_id] = std::move(internal_value);
-  } catch (...) {
-    GRNXX_ERROR_SET(error, NO_MEMORY, "Memory allocation failed");
+  if (value.size() == 0) {
+    headers_[row_id] = 0;
+    return true;
+  }
+  Int offset = bodies_.size();
+  if (value.size() < 0xFFFF) {
+    if (!bodies_.resize(error, offset + value.size())) {
+      return false;
+    }
+    std::memcpy(&bodies_[offset], value.data(), value.size());
+    headers_[row_id] = (offset << 16) | value.size();
+  } else {
+    // The size of a long text is stored in front of the body.
+    if ((offset % sizeof(Int)) != 0) {
+      offset += sizeof(Int) - (offset % sizeof(Int));
+    }
+    if (!bodies_.resize(error, offset + sizeof(Int) + value.size())) {
+      return false;
+    }
+    *reinterpret_cast<Int *>(&bodies_[offset]) = value.size();
+    std::memcpy(&bodies_[offset + sizeof(Int)], value.data(), value.size());
+    headers_[row_id] = (offset << 16) | 0xFFFF;
   }
   return true;
 }
@@ -229,7 +245,7 @@ bool ColumnImpl<Text>::get(Error *error, Int row_id, Datum *datum) const {
   if (!table_->test_row(error, row_id)) {
     return false;
   }
-  *datum = Text(values_[row_id].data(), values_[row_id].size());
+  *datum = get(row_id);
   return true;
 }
 
@@ -246,7 +262,7 @@ unique_ptr<ColumnImpl<Text>> ColumnImpl<Text>::create(
   if (!column->initialize_base(error, table, name, TEXT_DATA, options)) {
     return nullptr;
   }
-  if (!column->values_.resize(error, table->max_row_id() + 1)) {
+  if (!column->headers_.resize(error, table->max_row_id() + 1, 0)) {
     return nullptr;
   }
   return column;
@@ -255,19 +271,19 @@ unique_ptr<ColumnImpl<Text>> ColumnImpl<Text>::create(
 ColumnImpl<Text>::~ColumnImpl() {}
 
 bool ColumnImpl<Text>::set_default_value(Error *error, Int row_id) {
-  if (row_id >= values_.size()) {
-    if (!values_.resize(error, row_id + 1)) {
+  if (row_id >= headers_.size()) {
+    if (!headers_.resize(error, row_id + 1)) {
       return false;
     }
   }
-  values_[row_id].clear();
+  headers_[row_id] = 0;
   return true;
 }
 
 void ColumnImpl<Text>::unset(Int row_id) {
-  values_[row_id].clear();
+  headers_[row_id] = 0;
 }
 
-ColumnImpl<Text>::ColumnImpl() : Column(), values_() {}
+ColumnImpl<Text>::ColumnImpl() : Column(), headers_(), bodies_() {}
 
 }  // namespace grnxx

  Modified: lib/grnxx/column_impl.hpp (+14 -3)
===================================================================
--- lib/grnxx/column_impl.hpp    2014-08-21 13:32:33 +0900 (111cfaf)
+++ lib/grnxx/column_impl.hpp    2014-08-25 11:21:59 +0900 (1e0b6c5)
@@ -73,12 +73,23 @@ class ColumnImpl<Text> : public Column {
   //
   // Assumes that "row_id" is valid. Otherwise, the result is undefined.
   Text get(Int row_id) const {
-    return Text(values_[row_id].data(), values_[row_id].size());
+    Int size = static_cast<Int>(headers_[row_id] & 0xFFFF);
+    if (size == 0) {
+      return Text("", 0);
+    }
+    Int offset = static_cast<Int>(headers_[row_id] >> 16);
+    if (size < 0xFFFF) {
+      return Text(&bodies_[offset], size);
+    } else {
+      // The size of a long text is stored in front of the body.
+      size = *reinterpret_cast<const Int *>(&bodies_[offset]);
+      return String(&bodies_[offset + sizeof(Int)], size);
+    }
   }
 
  protected:
-  // TODO: std::string should not be used.
-  Array<std::string> values_;
+  Array<uint64_t> headers_;
+  Array<char> bodies_;
 
   ColumnImpl();
 };
-------------- next part --------------
HTML����������������������������...
Download 



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