36a5f8ed7f
- Replace raw slice comparison with a call to user comparator. Added test for custom comparators. - Fix end of namespace comments. - Fixed bug in picking inputs for a level-0 compaction. When finding overlapping files, the covered range may expand as files are added to the input set. We now correctly expand the range when this happens instead of continuing to use the old range. For example, suppose L0 contains files with the following ranges: F1: a .. d F2: c .. g F3: f .. j and the initial compaction target is F3. We used to search for range f..j which yielded {F2,F3}. However we now expand the range as soon as another file is added. In this case, when F2 is added, we expand the range to c..j and restart the search. That picks up file F1 as well. This change fixes a bug related to deleted keys showing up incorrectly after a compaction as described in Issue 44. (Sync with upstream @25072954)
109 lines
3.5 KiB
C++
109 lines
3.5 KiB
C++
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
|
|
|
#ifndef STORAGE_LEVELDB_DB_LOG_READER_H_
|
|
#define STORAGE_LEVELDB_DB_LOG_READER_H_
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "db/log_format.h"
|
|
#include "leveldb/slice.h"
|
|
#include "leveldb/status.h"
|
|
|
|
namespace leveldb {
|
|
|
|
class SequentialFile;
|
|
|
|
namespace log {
|
|
|
|
class Reader {
|
|
public:
|
|
// Interface for reporting errors.
|
|
class Reporter {
|
|
public:
|
|
virtual ~Reporter();
|
|
|
|
// Some corruption was detected. "size" is the approximate number
|
|
// of bytes dropped due to the corruption.
|
|
virtual void Corruption(size_t bytes, const Status& status) = 0;
|
|
};
|
|
|
|
// Create a reader that will return log records from "*file".
|
|
// "*file" must remain live while this Reader is in use.
|
|
//
|
|
// If "reporter" is non-NULL, it is notified whenever some data is
|
|
// dropped due to a detected corruption. "*reporter" must remain
|
|
// live while this Reader is in use.
|
|
//
|
|
// If "checksum" is true, verify checksums if available.
|
|
//
|
|
// The Reader will start reading at the first record located at physical
|
|
// position >= initial_offset within the file.
|
|
Reader(SequentialFile* file, Reporter* reporter, bool checksum,
|
|
uint64_t initial_offset);
|
|
|
|
~Reader();
|
|
|
|
// Read the next record into *record. Returns true if read
|
|
// successfully, false if we hit end of the input. May use
|
|
// "*scratch" as temporary storage. The contents filled in *record
|
|
// will only be valid until the next mutating operation on this
|
|
// reader or the next mutation to *scratch.
|
|
bool ReadRecord(Slice* record, std::string* scratch);
|
|
|
|
// Returns the physical offset of the last record returned by ReadRecord.
|
|
//
|
|
// Undefined before the first call to ReadRecord.
|
|
uint64_t LastRecordOffset();
|
|
|
|
private:
|
|
SequentialFile* const file_;
|
|
Reporter* const reporter_;
|
|
bool const checksum_;
|
|
char* const backing_store_;
|
|
Slice buffer_;
|
|
bool eof_; // Last Read() indicated EOF by returning < kBlockSize
|
|
|
|
// Offset of the last record returned by ReadRecord.
|
|
uint64_t last_record_offset_;
|
|
// Offset of the first location past the end of buffer_.
|
|
uint64_t end_of_buffer_offset_;
|
|
|
|
// Offset at which to start looking for the first record to return
|
|
uint64_t const initial_offset_;
|
|
|
|
// Extend record types with the following special values
|
|
enum {
|
|
kEof = kMaxRecordType + 1,
|
|
// Returned whenever we find an invalid physical record.
|
|
// Currently there are three situations in which this happens:
|
|
// * The record has an invalid CRC (ReadPhysicalRecord reports a drop)
|
|
// * The record is a 0-length record (No drop is reported)
|
|
// * The record is below constructor's initial_offset (No drop is reported)
|
|
kBadRecord = kMaxRecordType + 2
|
|
};
|
|
|
|
// Skips all blocks that are completely before "initial_offset_".
|
|
//
|
|
// Returns true on success. Handles reporting.
|
|
bool SkipToInitialBlock();
|
|
|
|
// Return type, or one of the preceding special values
|
|
unsigned int ReadPhysicalRecord(Slice* result);
|
|
|
|
// Reports dropped bytes to the reporter.
|
|
// buffer_ must be updated to remove the dropped bytes prior to invocation.
|
|
void ReportCorruption(size_t bytes, const char* reason);
|
|
void ReportDrop(size_t bytes, const Status& reason);
|
|
|
|
// No copying allowed
|
|
Reader(const Reader&);
|
|
void operator=(const Reader&);
|
|
};
|
|
|
|
} // namespace log
|
|
} // namespace leveldb
|
|
|
|
#endif // STORAGE_LEVELDB_DB_LOG_READER_H_
|