Skip to content

Commit ce45404

Browse files
mikewiacekcmumford
authored andcommitted
Suppress error reporting after seeking but before a valid First or Full record is encountered.
Fix a spelling mistake.
1 parent b9afa1f commit ce45404

File tree

3 files changed

+45
-7
lines changed

3 files changed

+45
-7
lines changed

db/log_reader.cc

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ Reader::Reader(SequentialFile* file, Reporter* reporter, bool checksum,
2525
eof_(false),
2626
last_record_offset_(0),
2727
end_of_buffer_offset_(0),
28-
initial_offset_(initial_offset) {
28+
initial_offset_(initial_offset),
29+
resyncing_(initial_offset > 0) {
2930
}
3031

3132
Reader::~Reader() {
@@ -74,6 +75,17 @@ bool Reader::ReadRecord(Slice* record, std::string* scratch) {
7475
while (true) {
7576
uint64_t physical_record_offset = end_of_buffer_offset_ - buffer_.size();
7677
const unsigned int record_type = ReadPhysicalRecord(&fragment);
78+
if (resyncing_) {
79+
if (record_type == kMiddleType) {
80+
continue;
81+
} else if (record_type == kLastType) {
82+
resyncing_ = false;
83+
continue;
84+
} else {
85+
resyncing_ = false;
86+
}
87+
}
88+
7789
switch (record_type) {
7890
case kFullType:
7991
if (in_fragmented_record) {

db/log_reader.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ class Reader {
7373
// Offset at which to start looking for the first record to return
7474
uint64_t const initial_offset_;
7575

76+
// True if we are resynchronizing after a seek (initial_offset_ > 0). In
77+
// particular, a run of kMiddleType and kLastType records can be silently
78+
// skipped in this mode
79+
bool resyncing_;
80+
7681
// Extend record types with the following special values
7782
enum {
7883
kEof = kMaxRecordType + 1,

db/log_test.cc

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class LogTest {
7979
virtual Status Skip(uint64_t n) {
8080
if (n > contents_.size()) {
8181
contents_.clear();
82-
return Status::NotFound("in-memory file skipepd past end");
82+
return Status::NotFound("in-memory file skipped past end");
8383
}
8484

8585
contents_.remove_prefix(n);
@@ -105,7 +105,7 @@ class LogTest {
105105
ReportCollector report_;
106106
bool reading_;
107107
Writer* writer_;
108-
Reader reader_;
108+
Reader* reader_;
109109

110110
// Record metadata for testing initial offset functionality
111111
static size_t initial_offset_record_sizes_[];
@@ -114,12 +114,13 @@ class LogTest {
114114
public:
115115
LogTest() : reading_(false),
116116
writer_(new Writer(&dest_)),
117-
reader_(&source_, &report_, true/*checksum*/,
118-
0/*initial_offset*/) {
117+
reader_(new Reader(&source_, &report_, true/*checksum*/,
118+
0/*initial_offset*/)) {
119119
}
120120

121121
~LogTest() {
122122
delete writer_;
123+
delete reader_;
123124
}
124125

125126
void ReopenForAppend() {
@@ -143,7 +144,7 @@ class LogTest {
143144
}
144145
std::string scratch;
145146
Slice record;
146-
if (reader_.ReadRecord(&record, &scratch)) {
147+
if (reader_->ReadRecord(&record, &scratch)) {
147148
return record.ToString();
148149
} else {
149150
return "EOF";
@@ -198,6 +199,11 @@ class LogTest {
198199
}
199200
}
200201

202+
void StartReadingAt(uint64_t initial_offset) {
203+
delete reader_;
204+
reader_ = new Reader(&source_, &report_, true/*checksum*/, initial_offset);
205+
}
206+
201207
void CheckOffsetPastEndReturnsNoRecords(uint64_t offset_past_end) {
202208
WriteInitialOffsetLog();
203209
reading_ = true;
@@ -227,7 +233,6 @@ class LogTest {
227233
ASSERT_EQ((char)('a' + expected_record_offset), record.data()[0]);
228234
delete offset_reader;
229235
}
230-
231236
};
232237

233238
size_t LogTest::initial_offset_record_sizes_[] =
@@ -463,6 +468,22 @@ TEST(LogTest, PartialLastIsIgnored) {
463468
ASSERT_EQ(0, DroppedBytes());
464469
}
465470

471+
TEST(LogTest, SkipIntoMultiRecord) {
472+
// Consider a fragmented record:
473+
// first(R1), middle(R1), last(R1), first(R2)
474+
// If initial_offset points to a record after first(R1) but before first(R2)
475+
// incomplete fragment errors are not actual errors, and must be suppressed
476+
// until a new first or full record is encountered.
477+
Write(BigString("foo", 3*kBlockSize));
478+
Write("correct");
479+
StartReadingAt(kBlockSize);
480+
481+
ASSERT_EQ("correct", Read());
482+
ASSERT_EQ("", ReportMessage());
483+
ASSERT_EQ(0, DroppedBytes());
484+
ASSERT_EQ("EOF", Read());
485+
}
486+
466487
TEST(LogTest, ErrorJoinsRecords) {
467488
// Consider two fragmented records:
468489
// first(R1) last(R1) first(R2) last(R2)

0 commit comments

Comments
 (0)