log_reader.h raw

   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 <stdint.h>
   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