]>
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() { | |
25 | Close(); | |
26 | delete[] buffer_; | |
27 | } | |
28 | ||
29 | Status FileTraceReader::Close() { | |
30 | file_reader_.reset(); | |
31 | return Status::OK(); | |
32 | } | |
33 | ||
34 | Status FileTraceReader::Read(std::string* data) { | |
35 | assert(file_reader_ != nullptr); | |
36 | Status s = file_reader_->Read(offset_, kTraceMetadataSize, &result_, buffer_); | |
37 | if (!s.ok()) { | |
38 | return s; | |
39 | } | |
40 | if (result_.size() == 0) { | |
41 | // No more data to read | |
42 | // Todo: Come up with a better way to indicate end of data. May be this | |
43 | // could be avoided once footer is introduced. | |
44 | return Status::Incomplete(); | |
45 | } | |
46 | if (result_.size() < kTraceMetadataSize) { | |
47 | return Status::Corruption("Corrupted trace file."); | |
48 | } | |
49 | *data = result_.ToString(); | |
50 | offset_ += kTraceMetadataSize; | |
51 | ||
52 | uint32_t payload_len = | |
53 | DecodeFixed32(&buffer_[kTraceTimestampSize + kTraceTypeSize]); | |
54 | ||
55 | // Read Payload | |
56 | unsigned int bytes_to_read = payload_len; | |
57 | unsigned int to_read = | |
58 | bytes_to_read > kBufferSize ? kBufferSize : bytes_to_read; | |
59 | while (to_read > 0) { | |
60 | s = file_reader_->Read(offset_, to_read, &result_, buffer_); | |
61 | if (!s.ok()) { | |
62 | return s; | |
63 | } | |
64 | if (result_.size() < to_read) { | |
65 | return Status::Corruption("Corrupted trace file."); | |
66 | } | |
67 | data->append(result_.data(), result_.size()); | |
68 | ||
69 | offset_ += to_read; | |
70 | bytes_to_read -= to_read; | |
71 | to_read = bytes_to_read > kBufferSize ? kBufferSize : bytes_to_read; | |
72 | } | |
73 | ||
74 | return s; | |
75 | } | |
76 | ||
77 | FileTraceWriter::~FileTraceWriter() { Close(); } | |
78 | ||
79 | Status FileTraceWriter::Close() { | |
80 | file_writer_.reset(); | |
81 | return Status::OK(); | |
82 | } | |
83 | ||
84 | Status FileTraceWriter::Write(const Slice& data) { | |
85 | return file_writer_->Append(data); | |
86 | } | |
87 | ||
494da23a TL |
88 | uint64_t FileTraceWriter::GetFileSize() { return file_writer_->GetFileSize(); } |
89 | ||
11fdf7f2 TL |
90 | Status NewFileTraceReader(Env* env, const EnvOptions& env_options, |
91 | const std::string& trace_filename, | |
92 | std::unique_ptr<TraceReader>* trace_reader) { | |
494da23a | 93 | std::unique_ptr<RandomAccessFile> trace_file; |
11fdf7f2 TL |
94 | Status s = env->NewRandomAccessFile(trace_filename, &trace_file, env_options); |
95 | if (!s.ok()) { | |
96 | return s; | |
97 | } | |
98 | ||
494da23a | 99 | std::unique_ptr<RandomAccessFileReader> file_reader; |
f67539c2 TL |
100 | file_reader.reset(new RandomAccessFileReader( |
101 | NewLegacyRandomAccessFileWrapper(trace_file), trace_filename)); | |
11fdf7f2 TL |
102 | trace_reader->reset(new FileTraceReader(std::move(file_reader))); |
103 | return s; | |
104 | } | |
105 | ||
106 | Status NewFileTraceWriter(Env* env, const EnvOptions& env_options, | |
107 | const std::string& trace_filename, | |
108 | std::unique_ptr<TraceWriter>* trace_writer) { | |
494da23a | 109 | std::unique_ptr<WritableFile> trace_file; |
11fdf7f2 TL |
110 | Status s = env->NewWritableFile(trace_filename, &trace_file, env_options); |
111 | if (!s.ok()) { | |
112 | return s; | |
113 | } | |
114 | ||
494da23a | 115 | std::unique_ptr<WritableFileWriter> file_writer; |
f67539c2 TL |
116 | file_writer.reset(new WritableFileWriter( |
117 | NewLegacyWritableFileWrapper(std::move(trace_file)), trace_filename, | |
118 | env_options)); | |
11fdf7f2 TL |
119 | trace_writer->reset(new FileTraceWriter(std::move(file_writer))); |
120 | return s; | |
121 | } | |
122 | ||
f67539c2 | 123 | } // namespace ROCKSDB_NAMESPACE |