1 //  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 //
6 #pragma once
7 
8 #include <memory>
9 
10 #include "db/blob/blob_log_format.h"
11 #include "rocksdb/slice.h"
12 
13 namespace ROCKSDB_NAMESPACE {
14 
15 class RandomAccessFileReader;
16 class Env;
17 class Statistics;
18 class Status;
19 class SystemClock;
20 
21 /**
22  * BlobLogSequentialReader is a general purpose log stream reader
23  * implementation. The actual job of reading from the device is implemented by
24  * the RandomAccessFileReader interface.
25  *
26  * Please see BlobLogWriter for details on the file and record layout.
27  */
28 
29 class BlobLogSequentialReader {
30  public:
31   enum ReadLevel {
32     kReadHeader,
33     kReadHeaderKey,
34     kReadHeaderKeyBlob,
35   };
36 
37   // Create a reader that will return log records from "*file_reader".
38   BlobLogSequentialReader(std::unique_ptr<RandomAccessFileReader>&& file_reader,
39                           SystemClock* clock, Statistics* statistics);
40 
41   // No copying allowed
42   BlobLogSequentialReader(const BlobLogSequentialReader&) = delete;
43   BlobLogSequentialReader& operator=(const BlobLogSequentialReader&) = delete;
44 
45   ~BlobLogSequentialReader();
46 
47   Status ReadHeader(BlobLogHeader* header);
48 
49   // Read the next record into *record.  Returns true if read
50   // successfully, false if we hit end of the input. The contents filled in
51   // *record will only be valid until the next mutating operation on this
52   // reader.
53   // If blob_offset is non-null, return offset of the blob through it.
54   Status ReadRecord(BlobLogRecord* record, ReadLevel level = kReadHeader,
55                     uint64_t* blob_offset = nullptr);
56 
57   Status ReadFooter(BlobLogFooter* footer);
58 
ResetNextByte()59   void ResetNextByte() { next_byte_ = 0; }
60 
GetNextByte()61   uint64_t GetNextByte() const { return next_byte_; }
62 
63  private:
64   Status ReadSlice(uint64_t size, Slice* slice, char* buf);
65 
66   const std::unique_ptr<RandomAccessFileReader> file_;
67   SystemClock* clock_;
68 
69   Statistics* statistics_;
70 
71   Slice buffer_;
72   char header_buf_[BlobLogRecord::kHeaderSize];
73 
74   // which byte to read next
75   uint64_t next_byte_;
76 };
77 
78 }  // namespace ROCKSDB_NAMESPACE
79