file_reader_writer.h 5.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
//  Copyright (c) 2013, Facebook, Inc.  All rights reserved.
//  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.
//
// 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
#include "rocksdb/env.h"
11 12
#include "util/aligned_buffer.h"
#include "port/port.h"
13 14

namespace rocksdb {
15 16

class Statistics;
17
class HistogramImpl;
18

19
std::unique_ptr<RandomAccessFile> NewReadaheadRandomAccessFile(
20
  std::unique_ptr<RandomAccessFile>&& file, size_t readahead_size);
21

22 23 24 25 26 27 28
class SequentialFileReader {
 private:
  std::unique_ptr<SequentialFile> file_;

 public:
  explicit SequentialFileReader(std::unique_ptr<SequentialFile>&& _file)
      : file_(std::move(_file)) {}
29 30 31 32 33 34 35 36 37 38 39 40 41

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

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

  SequentialFileReader(SequentialFileReader&) = delete;
  SequentialFileReader& operator=(SequentialFileReader&) = delete;

42 43 44 45 46 47 48
  Status Read(size_t n, Slice* result, char* scratch);

  Status Skip(uint64_t n);

  SequentialFile* file() { return file_.get(); }
};

49
class RandomAccessFileReader {
50 51
 private:
  std::unique_ptr<RandomAccessFile> file_;
52 53 54 55
  Env*            env_;
  Statistics*     stats_;
  uint32_t        hist_type_;
  HistogramImpl*  file_read_hist_;
56 57

 public:
58 59 60
  explicit RandomAccessFileReader(std::unique_ptr<RandomAccessFile>&& raf,
                                  Env* env = nullptr,
                                  Statistics* stats = nullptr,
61 62
                                  uint32_t hist_type = 0,
                                  HistogramImpl* file_read_hist = nullptr)
63 64 65
      : file_(std::move(raf)),
        env_(env),
        stats_(stats),
66 67
        hist_type_(hist_type),
        file_read_hist_(file_read_hist) {}
68

69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
  RandomAccessFileReader(RandomAccessFileReader&& o) ROCKSDB_NOEXCEPT {
    *this = std::move(o);
  }

  RandomAccessFileReader& operator=(RandomAccessFileReader&& o) ROCKSDB_NOEXCEPT{
    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_);
    return *this;
  }

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

85 86 87 88 89 90 91 92 93
  Status Read(uint64_t offset, size_t n, Slice* result, char* scratch) const;

  RandomAccessFile* file() { return file_.get(); }
};

// Use posix write to write data to a file.
class WritableFileWriter {
 private:
  std::unique_ptr<WritableFile> writable_file_;
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
  AlignedBuffer           buf_;
  // Actually written data size can be used for truncate
  // not counting padding data
  uint64_t                filesize_;
  // 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_;
  bool                    pending_sync_;
  bool                    pending_fsync_;
  const bool              direct_io_;
  const bool              use_os_buffer_;
  uint64_t                last_sync_size_;
  uint64_t                bytes_per_sync_;
  RateLimiter*            rate_limiter_;
109 110

 public:
111 112
  WritableFileWriter(std::unique_ptr<WritableFile>&& file,
                     const EnvOptions& options)
113
      : writable_file_(std::move(file)),
114
        buf_(),
115
        filesize_(0),
116
        next_write_offset_(0),
117 118
        pending_sync_(false),
        pending_fsync_(false),
119
        direct_io_(writable_file_->UseDirectIO()),
120
        use_os_buffer_(writable_file_->UseOSBuffer()),
121 122
        last_sync_size_(0),
        bytes_per_sync_(options.bytes_per_sync),
123 124
        rate_limiter_(options.rate_limiter) {

125
    buf_.Alignment(writable_file_->GetRequiredBufferAlignment());
126 127 128 129 130 131 132 133
    buf_.AllocateNewBuffer(65536);
  }

  WritableFileWriter(const WritableFileWriter&) = delete;

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

  ~WritableFileWriter() { Close(); }
134 135 136 137 138 139 140 141 142

  Status Append(const Slice& data);

  Status Flush();

  Status Close();

  Status Sync(bool use_fsync);

143 144 145 146 147
  // 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);

148 149 150 151 152 153 154 155 156
  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(); }

 private:
157 158 159 160 161
  // Used when os buffering is OFF and we are writing
  // DMA such as in Windows unbuffered mode
  Status WriteUnbuffered();
  // Normal write
  Status WriteBuffered(const char* data, size_t size);
162
  Status RangeSync(off_t offset, off_t nbytes);
163
  size_t RequestToken(size_t bytes, bool align);
164
  Status SyncInternal(bool use_fsync);
165 166
};
}  // namespace rocksdb