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