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 #define MAX_HEADER_SIZE(a, b, c) (a > b ? (a > c ? a : c) : (b > c ? b : c)) 14 15 namespace ROCKSDB_NAMESPACE { 16 17 class RandomAccessFileReader; 18 class Env; 19 class Statistics; 20 class Status; 21 class SystemClock; 22 23 /** 24 * BlobLogSequentialReader is a general purpose log stream reader 25 * implementation. The actual job of reading from the device is implemented by 26 * the RandomAccessFileReader interface. 27 * 28 * Please see BlobLogWriter for details on the file and record layout. 29 */ 30 31 class BlobLogSequentialReader { 32 public: 33 enum ReadLevel { 34 kReadHeader, 35 kReadHeaderKey, 36 kReadHeaderKeyBlob, 37 }; 38 39 // Create a reader that will return log records from "*file_reader". 40 BlobLogSequentialReader(std::unique_ptr<RandomAccessFileReader>&& file_reader, 41 SystemClock* clock, Statistics* statistics); 42 43 // No copying allowed 44 BlobLogSequentialReader(const BlobLogSequentialReader&) = delete; 45 BlobLogSequentialReader& operator=(const BlobLogSequentialReader&) = delete; 46 47 ~BlobLogSequentialReader(); 48 49 Status ReadHeader(BlobLogHeader* header); 50 51 // Read the next record into *record. Returns true if read 52 // successfully, false if we hit end of the input. The contents filled in 53 // *record will only be valid until the next mutating operation on this 54 // reader. 55 // If blob_offset is non-null, return offset of the blob through it. 56 Status ReadRecord(BlobLogRecord* record, ReadLevel level = kReadHeader, 57 uint64_t* blob_offset = nullptr); 58 59 Status ReadFooter(BlobLogFooter* footer); 60 ResetNextByte()61 void ResetNextByte() { next_byte_ = 0; } 62 GetNextByte()63 uint64_t GetNextByte() const { return next_byte_; } 64 65 private: 66 Status ReadSlice(uint64_t size, Slice* slice, char* buf); 67 68 const std::unique_ptr<RandomAccessFileReader> file_; 69 SystemClock* clock_; 70 71 Statistics* statistics_; 72 73 Slice buffer_; 74 char header_buf_[MAX_HEADER_SIZE(BlobLogHeader::kSize, BlobLogFooter::kSize, 75 BlobLogRecord::kHeaderSize)]; 76 77 // which byte to read next 78 uint64_t next_byte_; 79 }; 80 81 } // namespace ROCKSDB_NAMESPACE 82 83 #undef MAX_HEADER_SIZE