file_reader_writer.h 6.6 KB
Newer Older
1
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 3 4
//  This source code is licensed under the BSD-style license found in the
//  LICENSE file in the root directory of this source tree. An additional grant
//  of patent rights can be found in the PATENTS file in the same directory.
5 6
//  This source code is also licensed under the GPLv2 license found in the
//  COPYING file in the root directory of this source tree.
7 8 9 10 11
//
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#pragma once
A
Aaron Gao 已提交
12
#include <atomic>
S
sdong 已提交
13
#include <string>
A
Aaron Gao 已提交
14
#include "port/port.h"
15
#include "rocksdb/env.h"
16
#include "rocksdb/rate_limiter.h"
17
#include "util/aligned_buffer.h"
18 19

namespace rocksdb {
20 21

class Statistics;
22
class HistogramImpl;
23

24
std::unique_ptr<RandomAccessFile> NewReadaheadRandomAccessFile(
25
  std::unique_ptr<RandomAccessFile>&& file, size_t readahead_size);
26

27 28 29
class SequentialFileReader {
 private:
  std::unique_ptr<SequentialFile> file_;
A
Aaron Gao 已提交
30
  std::atomic<size_t> offset_;  // read offset
31 32 33

 public:
  explicit SequentialFileReader(std::unique_ptr<SequentialFile>&& _file)
A
Aaron Gao 已提交
34
      : file_(std::move(_file)), offset_(0) {}
35 36 37 38 39 40 41 42 43 44

  SequentialFileReader(SequentialFileReader&& o) ROCKSDB_NOEXCEPT {
    *this = std::move(o);
  }

  SequentialFileReader& operator=(SequentialFileReader&& o) ROCKSDB_NOEXCEPT {
    file_ = std::move(o.file_);
    return *this;
  }

S
sdong 已提交
45 46
  SequentialFileReader(const SequentialFileReader&) = delete;
  SequentialFileReader& operator=(const SequentialFileReader&) = delete;
47

48 49 50 51
  Status Read(size_t n, Slice* result, char* scratch);

  Status Skip(uint64_t n);

A
Anirban Rahut 已提交
52 53
  void Rewind();

54
  SequentialFile* file() { return file_.get(); }
A
Aaron Gao 已提交
55

56
  bool use_direct_io() const { return file_->use_direct_io(); }
57 58
};

59
class RandomAccessFileReader {
60 61
 private:
  std::unique_ptr<RandomAccessFile> file_;
62
  std::string     file_name_;
63 64 65 66
  Env*            env_;
  Statistics*     stats_;
  uint32_t        hist_type_;
  HistogramImpl*  file_read_hist_;
67 68
  RateLimiter* rate_limiter_;
  bool for_compaction_;
69 70

 public:
71
  explicit RandomAccessFileReader(std::unique_ptr<RandomAccessFile>&& raf,
72
                                  std::string _file_name,
73 74
                                  Env* env = nullptr,
                                  Statistics* stats = nullptr,
75
                                  uint32_t hist_type = 0,
76 77 78
                                  HistogramImpl* file_read_hist = nullptr,
                                  RateLimiter* rate_limiter = nullptr,
                                  bool for_compaction = false)
79
      : file_(std::move(raf)),
80
        file_name_(std::move(_file_name)),
81 82
        env_(env),
        stats_(stats),
83
        hist_type_(hist_type),
84 85 86
        file_read_hist_(file_read_hist),
        rate_limiter_(rate_limiter),
        for_compaction_(for_compaction) {}
87

88 89 90 91
  RandomAccessFileReader(RandomAccessFileReader&& o) ROCKSDB_NOEXCEPT {
    *this = std::move(o);
  }

92 93
  RandomAccessFileReader& operator=(RandomAccessFileReader&& o)
      ROCKSDB_NOEXCEPT {
94 95 96 97 98
    file_ = std::move(o.file_);
    env_ = std::move(o.env_);
    stats_ = std::move(o.stats_);
    hist_type_ = std::move(o.hist_type_);
    file_read_hist_ = std::move(o.file_read_hist_);
99 100
    rate_limiter_ = std::move(o.rate_limiter_);
    for_compaction_ = std::move(o.for_compaction_);
101 102 103 104 105 106
    return *this;
  }

  RandomAccessFileReader(const RandomAccessFileReader&) = delete;
  RandomAccessFileReader& operator=(const RandomAccessFileReader&) = delete;

107 108
  Status Read(uint64_t offset, size_t n, Slice* result, char* scratch) const;

A
Aaron Gao 已提交
109 110 111 112
  Status Prefetch(uint64_t offset, size_t n) const {
    return file_->Prefetch(offset, n);
  }

113
  RandomAccessFile* file() { return file_.get(); }
A
Aaron Gao 已提交
114

115 116
  std::string file_name() const { return file_name_; }

117
  bool use_direct_io() const { return file_->use_direct_io(); }
118 119 120 121 122 123
};

// Use posix write to write data to a file.
class WritableFileWriter {
 private:
  std::unique_ptr<WritableFile> writable_file_;
124
  AlignedBuffer           buf_;
125
  size_t                  max_buffer_size_;
126 127 128
  // Actually written data size can be used for truncate
  // not counting padding data
  uint64_t                filesize_;
S
Siying Dong 已提交
129
#ifndef ROCKSDB_LITE
130 131 132 133
  // This is necessary when we use unbuffered access
  // and writes must happen on aligned offsets
  // so we need to go back and write that page again
  uint64_t                next_write_offset_;
S
Siying Dong 已提交
134
#endif  // ROCKSDB_LITE
135 136 137 138
  bool                    pending_sync_;
  uint64_t                last_sync_size_;
  uint64_t                bytes_per_sync_;
  RateLimiter*            rate_limiter_;
139
  Statistics* stats_;
140 141

 public:
142
  WritableFileWriter(std::unique_ptr<WritableFile>&& file,
143
                     const EnvOptions& options, Statistics* stats = nullptr)
144
      : writable_file_(std::move(file)),
145
        buf_(),
146
        max_buffer_size_(options.writable_file_max_buffer_size),
147
        filesize_(0),
S
Siying Dong 已提交
148
#ifndef ROCKSDB_LITE
149
        next_write_offset_(0),
S
Siying Dong 已提交
150
#endif  // ROCKSDB_LITE
151 152 153
        pending_sync_(false),
        last_sync_size_(0),
        bytes_per_sync_(options.bytes_per_sync),
154 155
        rate_limiter_(options.rate_limiter),
        stats_(stats) {
156
    buf_.Alignment(writable_file_->GetRequiredBufferAlignment());
157
    buf_.AllocateNewBuffer(std::min((size_t)65536, max_buffer_size_));
158 159 160 161 162 163 164
  }

  WritableFileWriter(const WritableFileWriter&) = delete;

  WritableFileWriter& operator=(const WritableFileWriter&) = delete;

  ~WritableFileWriter() { Close(); }
165 166 167 168 169 170 171 172 173

  Status Append(const Slice& data);

  Status Flush();

  Status Close();

  Status Sync(bool use_fsync);

174 175 176 177 178
  // Sync only the data that was already Flush()ed. Safe to call concurrently
  // with Append() and Flush(). If !writable_file_->IsSyncThreadSafe(),
  // returns NotSupported status.
  Status SyncWithoutFlush(bool use_fsync);

179 180 181 182 183 184 185 186
  uint64_t GetFileSize() { return filesize_; }

  Status InvalidateCache(size_t offset, size_t length) {
    return writable_file_->InvalidateCache(offset, length);
  }

  WritableFile* writable_file() const { return writable_file_.get(); }

187
  bool use_direct_io() { return writable_file_->use_direct_io(); }
A
Aaron Gao 已提交
188

189
 private:
190
  // Used when os buffering is OFF and we are writing
A
Aaron Gao 已提交
191
  // DMA such as in Direct I/O mode
A
Aaron Gao 已提交
192
#ifndef ROCKSDB_LITE
A
Aaron Gao 已提交
193
  Status WriteDirect();
A
Aaron Gao 已提交
194
#endif  // !ROCKSDB_LITE
195 196
  // Normal write
  Status WriteBuffered(const char* data, size_t size);
197
  Status RangeSync(uint64_t offset, uint64_t nbytes);
198
  Status SyncInternal(bool use_fsync);
199
};
S
sdong 已提交
200 201 202 203

extern Status NewWritableFile(Env* env, const std::string& fname,
                              unique_ptr<WritableFile>* result,
                              const EnvOptions& options);
204
}  // namespace rocksdb