susumu.yata
null+****@clear*****
Wed Jul 16 16:34:16 JST 2014
susumu.yata 2014-07-16 16:34:16 +0900 (Wed, 16 Jul 2014) New Revision: bf62677ca10ff82929b657d2a0c2ea8ef2cdec5b https://github.com/groonga/grnxx/commit/bf62677ca10ff82929b657d2a0c2ea8ef2cdec5b Message: Skip bit checks in TableCursor if the bitmap has no false bit. Modified files: lib/grnxx/table.cpp test/test_grnxx.cpp Modified: lib/grnxx/table.cpp (+100 -28) =================================================================== --- lib/grnxx/table.cpp 2014-07-16 11:42:30 +0900 (551c637) +++ lib/grnxx/table.cpp 2014-07-16 16:34:16 +0900 (31f2527) @@ -6,6 +6,8 @@ #include "grnxx/error.hpp" #include "grnxx/record.hpp" +#include <iostream> // For debug. + namespace grnxx { // -- TableCursor -- @@ -101,26 +103,61 @@ TableCursor::TableCursor(const Table *table) Int TableCursor::regular_read(Error *error, Int max_count, RecordSet *record_set) { + // TODO: If possible, the buffer should be expanded outside the loop in order + // to remove size check and buffer expansion inside the loop. + // However, note that max_count can be extremely large for reading all + // the remaining records. Int count = 0; - while (next_row_id_ <= table_->max_row_id()) { - // TODO: This check should be skipped if there are no deleted rows. - if (!table_->get_bit(next_row_id_)) { - ++next_row_id_; - continue; - } + bool has_false_bit = + table_->num_rows() != (table_->max_row_id() - MIN_ROW_ID + 1); + if (!has_false_bit) { + // There are no false bits in the bitmap and bit checks are not required. + Int num_remaining_records = table_->max_row_id() - next_row_id_ + 1; if (offset_left_ > 0) { - --offset_left_; - ++next_row_id_; - } else { - // TODO: Resize the buffer outside the loop and set records in the loop. + if (offset_left_ >= num_remaining_records) { + next_row_id_ += num_remaining_records; + offset_left_ -= num_remaining_records; + return 0; + } + num_remaining_records -= offset_left_; + next_row_id_ += offset_left_; + offset_left_ = 0; + } + // Calculate the number of records to be read. + count = max_count; + if (count > num_remaining_records) { + count = num_remaining_records; + } + if (count > limit_left_) { + count = limit_left_; + } + for (Int i = 0; i < count; ++i) { if (!record_set->append(error, Record(next_row_id_, 0.0))) { return -1; } - --limit_left_; - ++count; ++next_row_id_; - if ((limit_left_ <= 0) || (count >= max_count)) { - break; + --limit_left_; + } + } else { + // There exist false bits in the bitmap and bit checks are required. + while (next_row_id_ <= table_->max_row_id()) { + if (!table_->get_bit(next_row_id_)) { + ++next_row_id_; + continue; + } + if (offset_left_ > 0) { + --offset_left_; + ++next_row_id_; + } else { + if (!record_set->append(error, Record(next_row_id_, 0.0))) { + return -1; + } + --limit_left_; + ++count; + ++next_row_id_; + if ((limit_left_ <= 0) || (count >= max_count)) { + break; + } } } } @@ -130,26 +167,61 @@ Int TableCursor::regular_read(Error *error, Int TableCursor::reverse_read(Error *error, Int max_count, RecordSet *record_set) { + // TODO: If possible, the buffer should be expanded outside the loop in order + // to remove size check and buffer expansion inside the loop. + // However, note that max_count can be extremely large for reading all + // the remaining records. Int count = 0; - while (next_row_id_ >= MIN_ROW_ID) { - // TODO: This check should be skipped if there are no deleted rows. - if (!table_->get_bit(next_row_id_)) { - --next_row_id_; - continue; - } + bool has_false_bit = + table_->num_rows() != (table_->max_row_id() - MIN_ROW_ID + 1); + if (!has_false_bit) { + // There are no false bits in the bitmap and bit checks are not required. + Int num_remaining_records = next_row_id_ - MIN_ROW_ID + 1; if (offset_left_ > 0) { - --offset_left_; - --next_row_id_; - } else { - // TODO: Resize the buffer outside the loop and set records in the loop. + if (offset_left_ >= num_remaining_records) { + next_row_id_ -= num_remaining_records; + offset_left_ -= num_remaining_records; + return 0; + } + num_remaining_records -= offset_left_; + next_row_id_ -= offset_left_; + offset_left_ = 0; + } + // Calculate the number of records to be read. + count = max_count; + if (count > num_remaining_records) { + count = num_remaining_records; + } + if (count > limit_left_) { + count = limit_left_; + } + for (Int i = 0; i < count; ++i) { if (!record_set->append(error, Record(next_row_id_, 0.0))) { return -1; } - --limit_left_; - ++count; --next_row_id_; - if ((limit_left_ <= 0) || (count >= max_count)) { - break; + --limit_left_; + } + } else { + while (next_row_id_ >= MIN_ROW_ID) { + // There exist false bits in the bitmap and bit checks are required. + if (!table_->get_bit(next_row_id_)) { + --next_row_id_; + continue; + } + if (offset_left_ > 0) { + --offset_left_; + --next_row_id_; + } else { + if (!record_set->append(error, Record(next_row_id_, 0.0))) { + return -1; + } + --limit_left_; + ++count; + --next_row_id_; + if ((limit_left_ <= 0) || (count >= max_count)) { + break; + } } } } Modified: test/test_grnxx.cpp (+14 -0) =================================================================== --- test/test_grnxx.cpp 2014-07-16 11:42:30 +0900 (6f3897b) +++ test/test_grnxx.cpp 2014-07-16 16:34:16 +0900 (e36fa3d) @@ -211,6 +211,20 @@ void test_table() { assert(record_set.size() == 2); assert(record_set.get(0).row_id == 3); assert(record_set.get(1).row_id == 1); + + record_set.clear(); + + cursor = table->create_cursor(&error, cursor_options); + assert(cursor); + + assert(cursor->read(&error, 1, &record_set) == 1); + assert(record_set.size() == 1); + assert(record_set.get(0).row_id == 3); + + assert(cursor->read(&error, 2, &record_set) == 1); + assert(record_set.size() == 2); + assert(record_set.get(0).row_id == 3); + assert(record_set.get(1).row_id == 1); } void test_column() { -------------- next part -------------- HTML����������������������������... Download