1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. See the AUTHORS file for names of contributors. 4 5 #ifndef STORAGE_LEVELDB_DB_LOG_READER_H_ 6 #define STORAGE_LEVELDB_DB_LOG_READER_H_ 7 8 #include <cstdint> 9 10 #include "db/log_format.h" 11 #include "leveldb/slice.h" 12 #include "leveldb/status.h" 13 14 namespace leveldb { 15 16 class SequentialFile; 17 18 namespace log { 19 20 class Reader { 21 public: 22 // Interface for reporting errors. 23 class Reporter { 24 public: 25 virtual ~Reporter(); 26 27 // Some corruption was detected. "size" is the approximate number 28 // of bytes dropped due to the corruption. 29 virtual void Corruption(size_t bytes, const Status& status) = 0; 30 }; 31 32 // Create a reader that will return log records from "*file". 33 // "*file" must remain live while this Reader is in use. 34 // 35 // If "reporter" is non-null, it is notified whenever some data is 36 // dropped due to a detected corruption. "*reporter" must remain 37 // live while this Reader is in use. 38 // 39 // If "checksum" is true, verify checksums if available. 40 // 41 // The Reader will start reading at the first record located at physical 42 // position >= initial_offset within the file. 43 Reader(SequentialFile* file, Reporter* reporter, bool checksum, 44 uint64_t initial_offset); 45 46 Reader(const Reader&) = delete; 47 Reader& operator=(const Reader&) = delete; 48 49 ~Reader(); 50 51 // Read the next record into *record. Returns true if read 52 // successfully, false if we hit end of the input. May use 53 // "*scratch" as temporary storage. The contents filled in *record 54 // will only be valid until the next mutating operation on this 55 // reader or the next mutation to *scratch. 56 bool ReadRecord(Slice* record, std::string* scratch); 57 58 // Returns the physical offset of the last record returned by ReadRecord. 59 // 60 // Undefined before the first call to ReadRecord. 61 uint64_t LastRecordOffset(); 62 63 private: 64 // Extend record types with the following special values 65 enum { 66 kEof = kMaxRecordType + 1, 67 // Returned whenever we find an invalid physical record. 68 // Currently there are three situations in which this happens: 69 // * The record has an invalid CRC (ReadPhysicalRecord reports a drop) 70 // * The record is a 0-length record (No drop is reported) 71 // * The record is below constructor's initial_offset (No drop is reported) 72 kBadRecord = kMaxRecordType + 2 73 }; 74 75 // Skips all blocks that are completely before "initial_offset_". 76 // 77 // Returns true on success. Handles reporting. 78 bool SkipToInitialBlock(); 79 80 // Return type, or one of the preceding special values 81 unsigned int ReadPhysicalRecord(Slice* result); 82 83 // Reports dropped bytes to the reporter. 84 // buffer_ must be updated to remove the dropped bytes prior to invocation. 85 void ReportCorruption(uint64_t bytes, const char* reason); 86 void ReportDrop(uint64_t bytes, const Status& reason); 87 88 SequentialFile* const file_; 89 Reporter* const reporter_; 90 bool const checksum_; 91 char* const backing_store_; 92 Slice buffer_; 93 bool eof_; // Last Read() indicated EOF by returning < kBlockSize 94 95 // Offset of the last record returned by ReadRecord. 96 uint64_t last_record_offset_; 97 // Offset of the first location past the end of buffer_. 98 uint64_t end_of_buffer_offset_; 99 100 // Offset at which to start looking for the first record to return 101 uint64_t const initial_offset_; 102 103 // True if we are resynchronizing after a seek (initial_offset_ > 0). In 104 // particular, a run of kMiddleType and kLastType records can be silently 105 // skipped in this mode 106 bool resyncing_; 107 }; 108 109 } // namespace log 110 } // namespace leveldb 111 112 #endif // STORAGE_LEVELDB_DB_LOG_READER_H_ 113