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