]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
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 | #include "utilities/trace/file_trace_reader_writer.h" | |
7 | ||
f67539c2 TL |
8 | #include "env/composite_env_wrapper.h" |
9 | #include "file/random_access_file_reader.h" | |
10 | #include "file/writable_file_writer.h" | |
11 | #include "trace_replay/trace_replay.h" | |
11fdf7f2 | 12 | #include "util/coding.h" |
11fdf7f2 | 13 | |
f67539c2 | 14 | namespace ROCKSDB_NAMESPACE { |
11fdf7f2 TL |
15 | |
16 | const unsigned int FileTraceReader::kBufferSize = 1024; // 1KB | |
17 | ||
18 | FileTraceReader::FileTraceReader( | |
19 | std::unique_ptr<RandomAccessFileReader>&& reader) | |
20 | : file_reader_(std::move(reader)), | |
21 | offset_(0), | |
22 | buffer_(new char[kBufferSize]) {} | |
23 | ||
24 | FileTraceReader::~FileTraceReader() { | |
20effc67 | 25 | Close().PermitUncheckedError(); |
11fdf7f2 TL |
26 | delete[] buffer_; |
27 | } | |
28 | ||
29 | Status FileTraceReader::Close() { | |
30 | file_reader_.reset(); | |
31 | return Status::OK(); | |
32 | } | |
33 | ||
1e59de90 TL |
34 | Status FileTraceReader::Reset() { |
35 | if (file_reader_ == nullptr) { | |
36 | return Status::IOError("TraceReader is closed."); | |
37 | } | |
38 | offset_ = 0; | |
39 | return Status::OK(); | |
40 | } | |
41 | ||
11fdf7f2 TL |
42 | Status FileTraceReader::Read(std::string* data) { |
43 | assert(file_reader_ != nullptr); | |
20effc67 | 44 | Status s = file_reader_->Read(IOOptions(), offset_, kTraceMetadataSize, |
1e59de90 TL |
45 | &result_, buffer_, nullptr, |
46 | Env::IO_TOTAL /* rate_limiter_priority */); | |
11fdf7f2 TL |
47 | if (!s.ok()) { |
48 | return s; | |
49 | } | |
50 | if (result_.size() == 0) { | |
51 | // No more data to read | |
52 | // Todo: Come up with a better way to indicate end of data. May be this | |
53 | // could be avoided once footer is introduced. | |
54 | return Status::Incomplete(); | |
55 | } | |
56 | if (result_.size() < kTraceMetadataSize) { | |
57 | return Status::Corruption("Corrupted trace file."); | |
58 | } | |
59 | *data = result_.ToString(); | |
60 | offset_ += kTraceMetadataSize; | |
61 | ||
62 | uint32_t payload_len = | |
63 | DecodeFixed32(&buffer_[kTraceTimestampSize + kTraceTypeSize]); | |
64 | ||
65 | // Read Payload | |
66 | unsigned int bytes_to_read = payload_len; | |
67 | unsigned int to_read = | |
68 | bytes_to_read > kBufferSize ? kBufferSize : bytes_to_read; | |
69 | while (to_read > 0) { | |
20effc67 | 70 | s = file_reader_->Read(IOOptions(), offset_, to_read, &result_, buffer_, |
1e59de90 | 71 | nullptr, Env::IO_TOTAL /* rate_limiter_priority */); |
11fdf7f2 TL |
72 | if (!s.ok()) { |
73 | return s; | |
74 | } | |
75 | if (result_.size() < to_read) { | |
76 | return Status::Corruption("Corrupted trace file."); | |
77 | } | |
78 | data->append(result_.data(), result_.size()); | |
79 | ||
80 | offset_ += to_read; | |
81 | bytes_to_read -= to_read; | |
82 | to_read = bytes_to_read > kBufferSize ? kBufferSize : bytes_to_read; | |
83 | } | |
84 | ||
85 | return s; | |
86 | } | |
87 | ||
1e59de90 TL |
88 | FileTraceWriter::FileTraceWriter( |
89 | std::unique_ptr<WritableFileWriter>&& file_writer) | |
90 | : file_writer_(std::move(file_writer)) {} | |
91 | ||
20effc67 | 92 | FileTraceWriter::~FileTraceWriter() { Close().PermitUncheckedError(); } |
11fdf7f2 TL |
93 | |
94 | Status FileTraceWriter::Close() { | |
95 | file_writer_.reset(); | |
96 | return Status::OK(); | |
97 | } | |
98 | ||
99 | Status FileTraceWriter::Write(const Slice& data) { | |
100 | return file_writer_->Append(data); | |
101 | } | |
102 | ||
494da23a TL |
103 | uint64_t FileTraceWriter::GetFileSize() { return file_writer_->GetFileSize(); } |
104 | ||
11fdf7f2 TL |
105 | Status NewFileTraceReader(Env* env, const EnvOptions& env_options, |
106 | const std::string& trace_filename, | |
107 | std::unique_ptr<TraceReader>* trace_reader) { | |
1e59de90 TL |
108 | std::unique_ptr<RandomAccessFileReader> file_reader; |
109 | Status s = RandomAccessFileReader::Create( | |
110 | env->GetFileSystem(), trace_filename, FileOptions(env_options), | |
111 | &file_reader, nullptr); | |
11fdf7f2 TL |
112 | if (!s.ok()) { |
113 | return s; | |
114 | } | |
11fdf7f2 TL |
115 | trace_reader->reset(new FileTraceReader(std::move(file_reader))); |
116 | return s; | |
117 | } | |
118 | ||
119 | Status NewFileTraceWriter(Env* env, const EnvOptions& env_options, | |
120 | const std::string& trace_filename, | |
121 | std::unique_ptr<TraceWriter>* trace_writer) { | |
1e59de90 TL |
122 | std::unique_ptr<WritableFileWriter> file_writer; |
123 | Status s = WritableFileWriter::Create(env->GetFileSystem(), trace_filename, | |
124 | FileOptions(env_options), &file_writer, | |
125 | nullptr); | |
11fdf7f2 TL |
126 | if (!s.ok()) { |
127 | return s; | |
128 | } | |
11fdf7f2 TL |
129 | trace_writer->reset(new FileTraceWriter(std::move(file_writer))); |
130 | return s; | |
131 | } | |
132 | ||
f67539c2 | 133 | } // namespace ROCKSDB_NAMESPACE |