108 lines
3.5 KiB

  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. #ifndef STORAGE_LEVELDB_DB_LOG_READER_H_
  5. #define STORAGE_LEVELDB_DB_LOG_READER_H_
  6. #include <stdint.h>
  7. #include "db/log_format.h"
  8. #include "leveldb/slice.h"
  9. #include "leveldb/status.h"
  10. namespace leveldb {
  11. class SequentialFile;
  12. namespace log {
  13. class Reader {
  14. public:
  15. // Interface for reporting errors.
  16. class Reporter {
  17. public:
  18. virtual ~Reporter();
  19. // Some corruption was detected. "size" is the approximate number
  20. // of bytes dropped due to the corruption.
  21. virtual void Corruption(size_t bytes, const Status& status) = 0;
  22. };
  23. // Create a reader that will return log records from "*file".
  24. // "*file" must remain live while this Reader is in use.
  25. //
  26. // If "reporter" is non-NULL, it is notified whenever some data is
  27. // dropped due to a detected corruption. "*reporter" must remain
  28. // live while this Reader is in use.
  29. //
  30. // If "checksum" is true, verify checksums if available.
  31. //
  32. // The Reader will start reading at the first record located at physical
  33. // position >= initial_offset within the file.
  34. Reader(SequentialFile* file, Reporter* reporter, bool checksum,
  35. uint64_t initial_offset);
  36. ~Reader();
  37. // Read the next record into *record. Returns true if read
  38. // successfully, false if we hit end of the input. May use
  39. // "*scratch" as temporary storage. The contents filled in *record
  40. // will only be valid until the next mutating operation on this
  41. // reader or the next mutation to *scratch.
  42. bool ReadRecord(Slice* record, std::string* scratch);
  43. // Returns the physical offset of the last record returned by ReadRecord.
  44. //
  45. // Undefined before the first call to ReadRecord.
  46. uint64_t LastRecordOffset();
  47. private:
  48. SequentialFile* const file_;
  49. Reporter* const reporter_;
  50. bool const checksum_;
  51. char* const backing_store_;
  52. Slice buffer_;
  53. bool eof_; // Last Read() indicated EOF by returning < kBlockSize
  54. // Offset of the last record returned by ReadRecord.
  55. uint64_t last_record_offset_;
  56. // Offset of the first location past the end of buffer_.
  57. uint64_t end_of_buffer_offset_;
  58. // Offset at which to start looking for the first record to return
  59. uint64_t const initial_offset_;
  60. // Extend record types with the following special values
  61. enum {
  62. kEof = kMaxRecordType + 1,
  63. // Returned whenever we find an invalid physical record.
  64. // Currently there are three situations in which this happens:
  65. // * The record has an invalid CRC (ReadPhysicalRecord reports a drop)
  66. // * The record is a 0-length record (No drop is reported)
  67. // * The record is below constructor's initial_offset (No drop is reported)
  68. kBadRecord = kMaxRecordType + 2
  69. };
  70. // Skips all blocks that are completely before "initial_offset_".
  71. //
  72. // Returns true on success. Handles reporting.
  73. bool SkipToInitialBlock();
  74. // Return type, or one of the preceding special values
  75. unsigned int ReadPhysicalRecord(Slice* result);
  76. // Reports dropped bytes to the reporter.
  77. // buffer_ must be updated to remove the dropped bytes prior to invocation.
  78. void ReportCorruption(size_t bytes, const char* reason);
  79. void ReportDrop(size_t bytes, const Status& reason);
  80. // No copying allowed
  81. Reader(const Reader&);
  82. void operator=(const Reader&);
  83. };
  84. } // namespace log
  85. } // namespace leveldb
  86. #endif // STORAGE_LEVELDB_DB_LOG_READER_H_