[Groonga-commit] groonga/grnxx at bb74f3c [master] Remove referrers in Table::remove_row(). (#71)

Back to archive index

susumu.yata null+****@clear*****
Thu Oct 2 18:31:09 JST 2014


susumu.yata	2014-10-02 18:31:09 +0900 (Thu, 02 Oct 2014)

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

  Message:
    Remove referrers in Table::remove_row(). (#71)

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

  Modified: include/grnxx/column.hpp (+5 -0)
===================================================================
--- include/grnxx/column.hpp    2014-10-02 17:50:39 +0900 (723450a)
+++ include/grnxx/column.hpp    2014-10-02 18:31:09 +0900 (e51d251)
@@ -126,6 +126,11 @@ class Column {
   // Otherwise, returns NULL_ROW_ID.
   virtual Int find_one(const Datum &datum) const;
 
+  // TODO: This function should be hidden.
+  //
+  // Replace references to "row_id" with NULL.
+  virtual void clear_references(Int row_id);
+
  protected:
   Table *table_;
   Name name_;

  Modified: lib/grnxx/column.cpp (+97 -0)
===================================================================
--- lib/grnxx/column.cpp    2014-10-02 17:50:39 +0900 (5f19004)
+++ lib/grnxx/column.cpp    2014-10-02 18:31:09 +0900 (e1bbc84)
@@ -126,6 +126,9 @@ Int Column::find_one(const Datum &) const {
   return NULL_ROW_ID;
 }
 
+void Column::clear_references(Int) {
+}
+
 unique_ptr<Column> Column::create(Error *error,
                                   Table *table,
                                   const StringCRef &name,
@@ -555,6 +558,53 @@ Int ColumnImpl<Int>::find_one(const Datum &datum) const {
   return NULL_ROW_ID;
 }
 
+void ColumnImpl<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, grnxx::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) {
+        values_[records.get_row_id(i)] = 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();
+    }
+  }
+}
+
 ColumnImpl<Int>::ColumnImpl() : Column(), values_() {}
 
 // -- ColumnImpl<Text> --
@@ -908,6 +958,53 @@ void ColumnImpl<Vector<Int>>::unset(Int row_id) {
   headers_[row_id] = 0;
 }
 
+void ColumnImpl<Vector<Int>>::clear_references(Int row_id) {
+  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) {
+      Int value_row_id = records.get_row_id(i);
+      Int value_size = static_cast<Int>(headers_[value_row_id] & 0xFFFF);
+      if (value_size == 0) {
+        continue;
+      }
+      Int value_offset = static_cast<Int>(headers_[value_row_id] >> 16);
+      if (value_size >= 0xFFFF) {
+        value_size = bodies_[value_offset];
+        ++value_offset;
+      }
+      Int count = 0;
+      for (Int j = 0; j < value_size; ++j) {
+        if (bodies_[value_offset + j] != row_id) {
+          bodies_[value_offset + count] = bodies_[value_offset + j];
+          ++count;
+        }
+      }
+      if (count < value_size) {
+        if (count == 0) {
+          headers_[value_row_id] = 0;
+        } else if (count < 0xFFFF) {
+          headers_[value_row_id] = count | (value_offset << 16);
+        } else {
+          bodies_[value_offset - 1] = count;
+        }
+      }
+    }
+    records.clear();
+  }
+}
+
 ColumnImpl<Vector<Int>>::ColumnImpl() : Column(), headers_(), bodies_() {}
 
 // -- ColumnImpl<Vector<Float>> --

  Modified: lib/grnxx/column_impl.hpp (+4 -0)
===================================================================
--- lib/grnxx/column_impl.hpp    2014-10-02 17:50:39 +0900 (735fa41)
+++ lib/grnxx/column_impl.hpp    2014-10-02 18:31:09 +0900 (11567e7)
@@ -80,6 +80,8 @@ class ColumnImpl<Int> : public Column {
   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".
   //
   // Assumes that "row_id" is valid. Otherwise, the result is undefined.
@@ -187,6 +189,8 @@ class ColumnImpl<Vector<Int>> : public Column {
   bool set_default_value(Error *error, Int row_id);
   void unset(Int row_id);
 
+  void clear_references(Int row_id);
+
   // Return a value identified by "row_id".
   //
   // Assumes that "row_id" is valid. Otherwise, the result is undefined.

  Modified: lib/grnxx/table.cpp (+4 -0)
===================================================================
--- lib/grnxx/table.cpp    2014-10-02 17:50:39 +0900 (234f18b)
+++ lib/grnxx/table.cpp    2014-10-02 18:31:09 +0900 (726d135)
@@ -437,6 +437,10 @@ bool Table::remove_row(Error *error, Int row_id) {
     }
     max_row_id_ = (block_id * 64) + 63 - ::__builtin_clzll(bitmap_[block_id]);
   }
+  // Clear referrers.
+  for (Int i = 0; i < referrer_columns_.size(); ++i) {
+    referrer_columns_[i]->clear_references(row_id);
+  }
   return true;
 }
 
-------------- next part --------------
HTML����������������������������...
Download 



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