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