Line data Source code
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 359 : 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();
47 :
48 : // Read the next record into *record. Returns true if read
49 : // successfully, false if we hit end of the input. May use
50 : // "*scratch" as temporary storage. The contents filled in *record
51 : // will only be valid until the next mutating operation on this
52 : // reader or the next mutation to *scratch.
53 : bool ReadRecord(Slice* record, std::string* scratch);
54 :
55 : // Returns the physical offset of the last record returned by ReadRecord.
56 : //
57 : // Undefined before the first call to ReadRecord.
58 : uint64_t LastRecordOffset();
59 :
60 : private:
61 : SequentialFile* const file_;
62 : Reporter* const reporter_;
63 : bool const checksum_;
64 : char* const backing_store_;
65 : Slice buffer_;
66 : bool eof_; // Last Read() indicated EOF by returning < kBlockSize
67 :
68 : // Offset of the last record returned by ReadRecord.
69 : uint64_t last_record_offset_;
70 : // Offset of the first location past the end of buffer_.
71 : uint64_t end_of_buffer_offset_;
72 :
73 : // Offset at which to start looking for the first record to return
74 : uint64_t const initial_offset_;
75 :
76 : // Extend record types with the following special values
77 : enum {
78 : kEof = kMaxRecordType + 1,
79 : // Returned whenever we find an invalid physical record.
80 : // Currently there are three situations in which this happens:
81 : // * The record has an invalid CRC (ReadPhysicalRecord reports a drop)
82 : // * The record is a 0-length record (No drop is reported)
83 : // * The record is below constructor's initial_offset (No drop is reported)
84 : kBadRecord = kMaxRecordType + 2
85 : };
86 :
87 : // Skips all blocks that are completely before "initial_offset_".
88 : //
89 : // Returns true on success. Handles reporting.
90 : bool SkipToInitialBlock();
91 :
92 : // Return type, or one of the preceding special values
93 : unsigned int ReadPhysicalRecord(Slice* result);
94 :
95 : // Reports dropped bytes to the reporter.
96 : // buffer_ must be updated to remove the dropped bytes prior to invocation.
97 : void ReportCorruption(uint64_t bytes, const char* reason);
98 : void ReportDrop(uint64_t bytes, const Status& reason);
99 :
100 : // No copying allowed
101 : Reader(const Reader&);
102 : void operator=(const Reader&);
103 : };
104 :
105 : } // namespace log
106 : } // namespace leveldb
107 :
108 : #endif // STORAGE_LEVELDB_DB_LOG_READER_H_
|