1179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Use of this source code is governed by a BSD-style license that can be 3179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// found in the LICENSE file. See the AUTHORS file for names of contributors. 4179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 5179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#ifndef STORAGE_LEVELDB_DB_LOG_READER_H_ 6179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#define STORAGE_LEVELDB_DB_LOG_READER_H_ 7179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 8a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org#include <stdint.h> 9a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org 10179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "db/log_format.h" 11fbd97aa4c5325eace57d24b89845b9581bac9324jorlow@chromium.org#include "leveldb/slice.h" 12fbd97aa4c5325eace57d24b89845b9581bac9324jorlow@chromium.org#include "leveldb/status.h" 13179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 14179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgnamespace leveldb { 15179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 16179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgclass SequentialFile; 17179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 18179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgnamespace log { 19179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 20179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgclass Reader { 21179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org public: 22179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Interface for reporting errors. 23179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org class Reporter { 24179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org public: 25179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual ~Reporter(); 26179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 27179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Some corruption was detected. "size" is the approximate number 28179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // of bytes dropped due to the corruption. 29179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org virtual void Corruption(size_t bytes, const Status& status) = 0; 30179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org }; 31179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 32179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Create a reader that will return log records from "*file". 33179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // "*file" must remain live while this Reader is in use. 34179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // 35179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // If "reporter" is non-NULL, it is notified whenever some data is 36179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // dropped due to a detected corruption. "*reporter" must remain 37179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // live while this Reader is in use. 38179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // 39179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // If "checksum" is true, verify checksums if available. 40a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // 41a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // The Reader will start reading at the first record located at physical 42a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // position >= initial_offset within the file. 43a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org Reader(SequentialFile* file, Reporter* reporter, bool checksum, 44a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org uint64_t initial_offset); 45179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 46179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ~Reader(); 47179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 48179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Read the next record into *record. Returns true if read 49179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // successfully, false if we hit end of the input. May use 50179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // "*scratch" as temporary storage. The contents filled in *record 51179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // will only be valid until the next mutating operation on this 52179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // reader or the next mutation to *scratch. 53179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org bool ReadRecord(Slice* record, std::string* scratch); 54179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 55a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // Returns the physical offset of the last record returned by ReadRecord. 56a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // 57a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // Undefined before the first call to ReadRecord. 58a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org uint64_t LastRecordOffset(); 59a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org 60179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org private: 61179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org SequentialFile* const file_; 62179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Reporter* const reporter_; 63179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org bool const checksum_; 64179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org char* const backing_store_; 65179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Slice buffer_; 66179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org bool eof_; // Last Read() indicated EOF by returning < kBlockSize 67179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 68a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // Offset of the last record returned by ReadRecord. 69a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org uint64_t last_record_offset_; 70a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // Offset of the first location past the end of buffer_. 71a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org uint64_t end_of_buffer_offset_; 72a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org 73a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // Offset at which to start looking for the first record to return 74a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org uint64_t const initial_offset_; 75a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org 76179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Extend record types with the following special values 77179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org enum { 78179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org kEof = kMaxRecordType + 1, 79a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // Returned whenever we find an invalid physical record. 80a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // Currently there are three situations in which this happens: 81a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // * The record has an invalid CRC (ReadPhysicalRecord reports a drop) 82a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // * The record is a 0-length record (No drop is reported) 83a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // * The record is below constructor's initial_offset (No drop is reported) 84179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org kBadRecord = kMaxRecordType + 2 85179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org }; 86179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 87a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // Skips all blocks that are completely before "initial_offset_". 88a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // 89a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // Returns true on success. Handles reporting. 90a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org bool SkipToInitialBlock(); 91a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org 92179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Return type, or one of the preceding special values 93179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org unsigned int ReadPhysicalRecord(Slice* result); 94a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org 95a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // Reports dropped bytes to the reporter. 96a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org // buffer_ must be updated to remove the dropped bytes prior to invocation. 97a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org void ReportCorruption(size_t bytes, const char* reason); 98a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org void ReportDrop(size_t bytes, const Status& reason); 99179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 100179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // No copying allowed 101179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Reader(const Reader&); 102179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org void operator=(const Reader&); 103179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}; 104179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 10545b9940be332834440bd5299419f396e38085ebehans@chromium.org} // namespace log 10645b9940be332834440bd5299419f396e38085ebehans@chromium.org} // namespace leveldb 107179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 108179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#endif // STORAGE_LEVELDB_DB_LOG_READER_H_ 109