|
|
|
@ -8,17 +8,16 @@ |
|
|
|
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
|
|
|
|
#pragma once |
|
|
|
|
|
|
|
|
|
#include <rocksdb/Status.h> |
|
|
|
|
#include <rocksdb/env.h> |
|
|
|
|
#include <stdint.h> |
|
|
|
|
#include <mutex> |
|
|
|
|
#include <string> |
|
|
|
|
|
|
|
|
|
#include "rocksdb/Status.h" |
|
|
|
|
#include "rocksdb/env.h" |
|
|
|
|
#include "util/aligned_buffer.h" |
|
|
|
|
|
|
|
|
|
#include <string> |
|
|
|
|
#include <stdint.h> |
|
|
|
|
|
|
|
|
|
#include <Windows.h> |
|
|
|
|
|
|
|
|
|
#include <mutex> |
|
|
|
|
|
|
|
|
|
namespace rocksdb { |
|
|
|
|
namespace port { |
|
|
|
@ -26,9 +25,9 @@ namespace port { |
|
|
|
|
std::string GetWindowsErrSz(DWORD err); |
|
|
|
|
|
|
|
|
|
inline Status IOErrorFromWindowsError(const std::string& context, DWORD err) { |
|
|
|
|
return ((err == ERROR_HANDLE_DISK_FULL) || (err == ERROR_DISK_FULL)) ? |
|
|
|
|
Status::NoSpace(context, GetWindowsErrSz(err)) : |
|
|
|
|
Status::IOError(context, GetWindowsErrSz(err)); |
|
|
|
|
return ((err == ERROR_HANDLE_DISK_FULL) || (err == ERROR_DISK_FULL)) |
|
|
|
|
? Status::NoSpace(context, GetWindowsErrSz(err)) |
|
|
|
|
: Status::IOError(context, GetWindowsErrSz(err)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline Status IOErrorFromLastWindowsError(const std::string& context) { |
|
|
|
@ -36,9 +35,9 @@ inline Status IOErrorFromLastWindowsError(const std::string& context) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline Status IOError(const std::string& context, int err_number) { |
|
|
|
|
return (err_number == ENOSPC) ? |
|
|
|
|
Status::NoSpace(context, strerror(err_number)) :
|
|
|
|
|
Status::IOError(context, strerror(err_number)); |
|
|
|
|
return (err_number == ENOSPC) |
|
|
|
|
? Status::NoSpace(context, strerror(err_number)) |
|
|
|
|
: Status::IOError(context, strerror(err_number)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Note the below two do not set errno because they are used only here in this
|
|
|
|
@ -54,49 +53,34 @@ inline int fsync(HANDLE hFile) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SSIZE_T pwrite(HANDLE hFile, const char* src, size_t numBytes, |
|
|
|
|
uint64_t offset); |
|
|
|
|
SSIZE_T pwrite(HANDLE hFile, const char* src, size_t numBytes, uint64_t offset); |
|
|
|
|
|
|
|
|
|
SSIZE_T pread(HANDLE hFile, char* src, size_t numBytes, uint64_t offset); |
|
|
|
|
|
|
|
|
|
Status fallocate(const std::string& filename, HANDLE hFile, |
|
|
|
|
uint64_t to_size); |
|
|
|
|
|
|
|
|
|
Status ftruncate(const std::string& filename, HANDLE hFile, |
|
|
|
|
uint64_t toSize); |
|
|
|
|
Status fallocate(const std::string& filename, HANDLE hFile, uint64_t to_size); |
|
|
|
|
|
|
|
|
|
Status ftruncate(const std::string& filename, HANDLE hFile, uint64_t toSize); |
|
|
|
|
|
|
|
|
|
size_t GetUniqueIdFromFile(HANDLE hFile, char* id, size_t max_size); |
|
|
|
|
|
|
|
|
|
class WinFileData { |
|
|
|
|
protected: |
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
|
const std::string filename_; |
|
|
|
|
HANDLE hFile_; |
|
|
|
|
// There is no equivalent of advising away buffered pages as in posix.
|
|
|
|
|
// To implement this flag we would need to do unbuffered reads which
|
|
|
|
|
// If ture, the I/O issued would be direct I/O which the buffer
|
|
|
|
|
// will need to be aligned (not sure there is a guarantee that the buffer
|
|
|
|
|
// passed in is aligned).
|
|
|
|
|
// Hence we currently ignore this flag. It is used only in a few cases
|
|
|
|
|
// which should not be perf critical.
|
|
|
|
|
// If perf evaluation finds this to be a problem, we can look into
|
|
|
|
|
// implementing this.
|
|
|
|
|
const bool use_os_buffer_; |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
const bool use_direct_io_; |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
// We want this class be usable both for inheritance (prive
|
|
|
|
|
// or protected) and for containment so __ctor and __dtor public
|
|
|
|
|
WinFileData(const std::string& filename, HANDLE hFile, bool use_os_buffer) : |
|
|
|
|
filename_(filename), hFile_(hFile), use_os_buffer_(use_os_buffer) |
|
|
|
|
{} |
|
|
|
|
WinFileData(const std::string& filename, HANDLE hFile, bool use_direct_io) |
|
|
|
|
: filename_(filename), hFile_(hFile), use_direct_io_(use_direct_io) {} |
|
|
|
|
|
|
|
|
|
virtual ~WinFileData() { |
|
|
|
|
this->CloseFile(); |
|
|
|
|
} |
|
|
|
|
virtual ~WinFileData() { this->CloseFile(); } |
|
|
|
|
|
|
|
|
|
bool CloseFile() { |
|
|
|
|
|
|
|
|
|
bool result = true; |
|
|
|
|
|
|
|
|
|
if (hFile_ != NULL && hFile_ != INVALID_HANDLE_VALUE) { |
|
|
|
@ -111,13 +95,12 @@ public: |
|
|
|
|
|
|
|
|
|
HANDLE GetFileHandle() const { return hFile_; } |
|
|
|
|
|
|
|
|
|
bool UseOSBuffer() const { return use_os_buffer_; } |
|
|
|
|
bool UseDirectIO() const { return use_direct_io_; } |
|
|
|
|
|
|
|
|
|
WinFileData(const WinFileData&) = delete; |
|
|
|
|
WinFileData& operator=(const WinFileData&) = delete; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// mmap() based random-access
|
|
|
|
|
class WinMmapReadableFile : private WinFileData, public RandomAccessFile { |
|
|
|
|
HANDLE hMap_; |
|
|
|
@ -125,10 +108,10 @@ class WinMmapReadableFile : private WinFileData, public RandomAccessFile { |
|
|
|
|
const void* mapped_region_; |
|
|
|
|
const size_t length_; |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
public: |
|
|
|
|
// mapped_region_[0,length-1] contains the mmapped contents of the file.
|
|
|
|
|
WinMmapReadableFile(const std::string& fileName, HANDLE hFile, HANDLE hMap, |
|
|
|
|
const void* mapped_region, size_t length); |
|
|
|
|
const void* mapped_region, size_t length); |
|
|
|
|
|
|
|
|
|
~WinMmapReadableFile(); |
|
|
|
|
|
|
|
|
@ -136,7 +119,7 @@ public: |
|
|
|
|
WinMmapReadableFile& operator=(const WinMmapReadableFile&) = delete; |
|
|
|
|
|
|
|
|
|
virtual Status Read(uint64_t offset, size_t n, Slice* result, |
|
|
|
|
char* scratch) const override; |
|
|
|
|
char* scratch) const override; |
|
|
|
|
|
|
|
|
|
virtual Status InvalidateCache(size_t offset, size_t length) override; |
|
|
|
|
|
|
|
|
@ -148,20 +131,20 @@ public: |
|
|
|
|
// file before reading from it, or for log files, the reading code
|
|
|
|
|
// knows enough to skip zero suffixes.
|
|
|
|
|
class WinMmapFile : private WinFileData, public WritableFile { |
|
|
|
|
private: |
|
|
|
|
private: |
|
|
|
|
HANDLE hMap_; |
|
|
|
|
|
|
|
|
|
const size_t page_size_; // We flush the mapping view in page_size
|
|
|
|
|
// increments. We may decide if this is a memory
|
|
|
|
|
// page size or SSD page size
|
|
|
|
|
const size_t |
|
|
|
|
allocation_granularity_; // View must start at such a granularity
|
|
|
|
|
allocation_granularity_; // View must start at such a granularity
|
|
|
|
|
|
|
|
|
|
size_t reserved_size_; // Preallocated size
|
|
|
|
|
size_t reserved_size_; // Preallocated size
|
|
|
|
|
|
|
|
|
|
size_t mapping_size_; // The max size of the mapping object
|
|
|
|
|
size_t mapping_size_; // The max size of the mapping object
|
|
|
|
|
// we want to guess the final file size to minimize the remapping
|
|
|
|
|
size_t view_size_; // How much memory to map into a view at a time
|
|
|
|
|
size_t view_size_; // How much memory to map into a view at a time
|
|
|
|
|
|
|
|
|
|
char* mapped_begin_; // Must begin at the file offset that is aligned with
|
|
|
|
|
// allocation_granularity_
|
|
|
|
@ -184,10 +167,9 @@ private: |
|
|
|
|
|
|
|
|
|
virtual Status PreallocateInternal(uint64_t spaceToReserve); |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
WinMmapFile(const std::string& fname, HANDLE hFile, size_t page_size, |
|
|
|
|
size_t allocation_granularity, const EnvOptions& options); |
|
|
|
|
size_t allocation_granularity, const EnvOptions& options); |
|
|
|
|
|
|
|
|
|
~WinMmapFile(); |
|
|
|
|
|
|
|
|
@ -227,9 +209,9 @@ public: |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class WinSequentialFile : private WinFileData, public SequentialFile { |
|
|
|
|
public: |
|
|
|
|
public: |
|
|
|
|
WinSequentialFile(const std::string& fname, HANDLE f, |
|
|
|
|
const EnvOptions& options); |
|
|
|
|
const EnvOptions& options); |
|
|
|
|
|
|
|
|
|
~WinSequentialFile(); |
|
|
|
|
|
|
|
|
@ -244,89 +226,87 @@ public: |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class WinRandomAccessImpl { |
|
|
|
|
protected: |
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
|
WinFileData* file_base_; |
|
|
|
|
bool read_ahead_; |
|
|
|
|
bool read_ahead_; |
|
|
|
|
const size_t compaction_readahead_size_; |
|
|
|
|
const size_t random_access_max_buffer_size_; |
|
|
|
|
mutable std::mutex buffer_mut_; |
|
|
|
|
mutable std::mutex buffer_mut_; |
|
|
|
|
mutable AlignedBuffer buffer_; |
|
|
|
|
mutable uint64_t |
|
|
|
|
buffered_start_; // file offset set that is currently buffered
|
|
|
|
|
buffered_start_; // file offset set that is currently buffered
|
|
|
|
|
|
|
|
|
|
// Override for behavior change when creating a custom env
|
|
|
|
|
virtual SSIZE_T PositionedReadInternal(char* src, size_t numBytes, |
|
|
|
|
uint64_t offset) const; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The function reads a requested amount of bytes into the specified aligned |
|
|
|
|
* buffer Upon success the function sets the length of the buffer to the |
|
|
|
|
* amount of bytes actually read even though it might be less than actually |
|
|
|
|
* requested. It then copies the amount of bytes requested by the user (left) |
|
|
|
|
* to the user supplied buffer (dest) and reduces left by the amount of bytes |
|
|
|
|
* copied to the user buffer |
|
|
|
|
* |
|
|
|
|
* @user_offset [in] - offset on disk where the read was requested by the user |
|
|
|
|
* @first_page_start [in] - actual page aligned disk offset that we want to |
|
|
|
|
* read from |
|
|
|
|
* @bytes_to_read [in] - total amount of bytes that will be read from disk |
|
|
|
|
* which is generally greater or equal to the amount |
|
|
|
|
* that the user has requested due to the |
|
|
|
|
* either alignment requirements or read_ahead in |
|
|
|
|
* effect. |
|
|
|
|
* @left [in/out] total amount of bytes that needs to be copied to the user |
|
|
|
|
* buffer. It is reduced by the amount of bytes that actually |
|
|
|
|
* copied |
|
|
|
|
* @buffer - buffer to use |
|
|
|
|
* @dest - user supplied buffer |
|
|
|
|
*/ |
|
|
|
|
uint64_t offset) const; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The function reads a requested amount of bytes into the specified aligned |
|
|
|
|
* buffer Upon success the function sets the length of the buffer to the |
|
|
|
|
* amount of bytes actually read even though it might be less than actually |
|
|
|
|
* requested. It then copies the amount of bytes requested by the user (left) |
|
|
|
|
* to the user supplied buffer (dest) and reduces left by the amount of bytes |
|
|
|
|
* copied to the user buffer |
|
|
|
|
* |
|
|
|
|
* @user_offset [in] - offset on disk where the read was requested by the user |
|
|
|
|
* @first_page_start [in] - actual page aligned disk offset that we want to |
|
|
|
|
* read from |
|
|
|
|
* @bytes_to_read [in] - total amount of bytes that will be read from disk |
|
|
|
|
* which is generally greater or equal to the amount |
|
|
|
|
* that the user has requested due to the |
|
|
|
|
* either alignment requirements or read_ahead in |
|
|
|
|
* effect. |
|
|
|
|
* @left [in/out] total amount of bytes that needs to be copied to the user |
|
|
|
|
* buffer. It is reduced by the amount of bytes that actually |
|
|
|
|
* copied |
|
|
|
|
* @buffer - buffer to use |
|
|
|
|
* @dest - user supplied buffer |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
SSIZE_T ReadIntoBuffer(uint64_t user_offset, uint64_t first_page_start, |
|
|
|
|
size_t bytes_to_read, size_t& left, |
|
|
|
|
AlignedBuffer& buffer, char* dest) const; |
|
|
|
|
size_t bytes_to_read, size_t& left, |
|
|
|
|
AlignedBuffer& buffer, char* dest) const; |
|
|
|
|
|
|
|
|
|
SSIZE_T ReadIntoOneShotBuffer(uint64_t user_offset, uint64_t first_page_start, |
|
|
|
|
size_t bytes_to_read, size_t& left, |
|
|
|
|
char* dest) const; |
|
|
|
|
size_t bytes_to_read, size_t& left, |
|
|
|
|
char* dest) const; |
|
|
|
|
|
|
|
|
|
SSIZE_T ReadIntoInstanceBuffer(uint64_t user_offset, |
|
|
|
|
uint64_t first_page_start, |
|
|
|
|
size_t bytes_to_read, size_t& left, |
|
|
|
|
char* dest) const; |
|
|
|
|
uint64_t first_page_start, |
|
|
|
|
size_t bytes_to_read, size_t& left, |
|
|
|
|
char* dest) const; |
|
|
|
|
|
|
|
|
|
WinRandomAccessImpl(WinFileData* file_base, size_t alignment, |
|
|
|
|
const EnvOptions& options); |
|
|
|
|
const EnvOptions& options); |
|
|
|
|
|
|
|
|
|
virtual ~WinRandomAccessImpl() {} |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
WinRandomAccessImpl(const WinRandomAccessImpl&) = delete; |
|
|
|
|
WinRandomAccessImpl& operator=(const WinRandomAccessImpl&) = delete; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Status ReadImpl(uint64_t offset, size_t n, Slice* result, |
|
|
|
|
char* scratch) const; |
|
|
|
|
char* scratch) const; |
|
|
|
|
|
|
|
|
|
void HintImpl(RandomAccessFile::AccessPattern pattern); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// pread() based random-access
|
|
|
|
|
class WinRandomAccessFile : private WinFileData,
|
|
|
|
|
protected WinRandomAccessImpl, // Want to be able to override PositionedReadInternal
|
|
|
|
|
public RandomAccessFile { |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
class WinRandomAccessFile |
|
|
|
|
: private WinFileData, |
|
|
|
|
protected WinRandomAccessImpl, // Want to be able to override
|
|
|
|
|
// PositionedReadInternal
|
|
|
|
|
public RandomAccessFile { |
|
|
|
|
public: |
|
|
|
|
WinRandomAccessFile(const std::string& fname, HANDLE hFile, size_t alignment, |
|
|
|
|
const EnvOptions& options); |
|
|
|
|
const EnvOptions& options); |
|
|
|
|
|
|
|
|
|
~WinRandomAccessFile(); |
|
|
|
|
|
|
|
|
|
virtual void EnableReadAhead() override; |
|
|
|
|
|
|
|
|
|
virtual Status Read(uint64_t offset, size_t n, Slice* result, |
|
|
|
|
char* scratch) const override; |
|
|
|
|
char* scratch) const override; |
|
|
|
|
|
|
|
|
|
virtual bool ShouldForwardRawRequest() const override; |
|
|
|
|
|
|
|
|
@ -337,7 +317,6 @@ public: |
|
|
|
|
virtual size_t GetUniqueId(char* id, size_t max_size) const override; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This is a sequential write class. It has been mimicked (as others) after
|
|
|
|
|
// the original Posix class. We add support for unbuffered I/O on windows as
|
|
|
|
|
// well
|
|
|
|
@ -351,12 +330,11 @@ public: |
|
|
|
|
// No padding is required for
|
|
|
|
|
// buffered access.
|
|
|
|
|
class WinWritableImpl { |
|
|
|
|
protected: |
|
|
|
|
|
|
|
|
|
WinFileData* file_data_; |
|
|
|
|
const uint64_t alignment_; |
|
|
|
|
uint64_t filesize_; // How much data is actually written disk
|
|
|
|
|
uint64_t reservedsize_; // how far we have reserved space
|
|
|
|
|
protected: |
|
|
|
|
WinFileData* file_data_; |
|
|
|
|
const uint64_t alignment_; |
|
|
|
|
uint64_t filesize_; // How much data is actually written disk
|
|
|
|
|
uint64_t reservedsize_; // how far we have reserved space
|
|
|
|
|
|
|
|
|
|
virtual Status PreallocateInternal(uint64_t spaceToReserve); |
|
|
|
|
|
|
|
|
@ -368,7 +346,8 @@ protected: |
|
|
|
|
|
|
|
|
|
Status AppendImpl(const Slice& data); |
|
|
|
|
|
|
|
|
|
// Requires that the data is aligned as specified by GetRequiredBufferAlignment()
|
|
|
|
|
// Requires that the data is aligned as specified by
|
|
|
|
|
// GetRequiredBufferAlignment()
|
|
|
|
|
Status PositionedAppendImpl(const Slice& data, uint64_t offset); |
|
|
|
|
|
|
|
|
|
Status TruncateImpl(uint64_t size); |
|
|
|
@ -380,7 +359,8 @@ protected: |
|
|
|
|
uint64_t GetFileSizeImpl() { |
|
|
|
|
// Double accounting now here with WritableFileWriter
|
|
|
|
|
// and this size will be wrong when unbuffered access is used
|
|
|
|
|
// but tests implement their own writable files and do not use WritableFileWrapper
|
|
|
|
|
// but tests implement their own writable files and do not use
|
|
|
|
|
// WritableFileWrapper
|
|
|
|
|
// so we need to squeeze a square peg through
|
|
|
|
|
// a round hole here.
|
|
|
|
|
return filesize_; |
|
|
|
@ -388,32 +368,30 @@ protected: |
|
|
|
|
|
|
|
|
|
Status AllocateImpl(uint64_t offset, uint64_t len); |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
WinWritableImpl(const WinWritableImpl&) = delete; |
|
|
|
|
WinWritableImpl& operator=(const WinWritableImpl&) = delete; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class WinWritableFile : private WinFileData, |
|
|
|
|
protected WinWritableImpl, |
|
|
|
|
public WritableFile { |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
protected WinWritableImpl, |
|
|
|
|
public WritableFile { |
|
|
|
|
public: |
|
|
|
|
WinWritableFile(const std::string& fname, HANDLE hFile, size_t alignment, |
|
|
|
|
size_t capacity, const EnvOptions& options); |
|
|
|
|
size_t capacity, const EnvOptions& options); |
|
|
|
|
|
|
|
|
|
~WinWritableFile(); |
|
|
|
|
|
|
|
|
|
// Indicates if the class makes use of unbuffered I/O
|
|
|
|
|
// Indicates if the class makes use of direct I/O
|
|
|
|
|
// Use PositionedAppend
|
|
|
|
|
virtual bool UseOSBuffer() const override; |
|
|
|
|
virtual bool UseDirectIO() const override; |
|
|
|
|
|
|
|
|
|
virtual size_t GetRequiredBufferAlignment() const override; |
|
|
|
|
|
|
|
|
|
virtual Status Append(const Slice& data) override; |
|
|
|
|
|
|
|
|
|
// Requires that the data is aligned as specified by GetRequiredBufferAlignment()
|
|
|
|
|
// Requires that the data is aligned as specified by
|
|
|
|
|
// GetRequiredBufferAlignment()
|
|
|
|
|
virtual Status PositionedAppend(const Slice& data, uint64_t offset) override; |
|
|
|
|
|
|
|
|
|
// Need to implement this so the file is truncated correctly
|
|
|
|
@ -437,30 +415,27 @@ public: |
|
|
|
|
virtual size_t GetUniqueId(char* id, size_t max_size) const override; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class WinRandomRWFile : private WinFileData, |
|
|
|
|
protected WinRandomAccessImpl, |
|
|
|
|
protected WinWritableImpl, |
|
|
|
|
public RandomRWFile { |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
|
|
protected WinRandomAccessImpl, |
|
|
|
|
protected WinWritableImpl, |
|
|
|
|
public RandomRWFile { |
|
|
|
|
public: |
|
|
|
|
WinRandomRWFile(const std::string& fname, HANDLE hFile, size_t alignment, |
|
|
|
|
const EnvOptions& options); |
|
|
|
|
const EnvOptions& options); |
|
|
|
|
|
|
|
|
|
~WinRandomRWFile() {} |
|
|
|
|
|
|
|
|
|
// Indicates if the class makes use of unbuffered I/O
|
|
|
|
|
// Indicates if the class makes use of direct I/O
|
|
|
|
|
// If false you must pass aligned buffer to Write()
|
|
|
|
|
virtual bool UseOSBuffer() const override; |
|
|
|
|
virtual bool UseDirectIO() const override; |
|
|
|
|
|
|
|
|
|
// Use the returned alignment value to allocate
|
|
|
|
|
// aligned buffer for Write() when UseOSBuffer()
|
|
|
|
|
// returns false
|
|
|
|
|
// Use the returned alignment value to allocate aligned
|
|
|
|
|
// buffer for Write() when UseDirectIO() returns true
|
|
|
|
|
virtual size_t GetRequiredBufferAlignment() const override; |
|
|
|
|
|
|
|
|
|
// Used by the file_reader_writer to decide if the ReadAhead wrapper
|
|
|
|
|
// should simply forward the call and do not enact read_ahead buffering or locking.
|
|
|
|
|
// should simply forward the call and do not enact read_ahead buffering or
|
|
|
|
|
// locking.
|
|
|
|
|
// The implementation below takes care of reading ahead
|
|
|
|
|
virtual bool ShouldForwardRawRequest() const override; |
|
|
|
|
|
|
|
|
@ -469,14 +444,14 @@ public: |
|
|
|
|
virtual void EnableReadAhead() override; |
|
|
|
|
|
|
|
|
|
// Write bytes in `data` at offset `offset`, Returns Status::OK() on success.
|
|
|
|
|
// Pass aligned buffer when UseOSBuffer() returns false.
|
|
|
|
|
// Pass aligned buffer when UseDirectIO() returns true.
|
|
|
|
|
virtual Status Write(uint64_t offset, const Slice& data) override; |
|
|
|
|
|
|
|
|
|
// Read up to `n` bytes starting from offset `offset` and store them in
|
|
|
|
|
// result, provided `scratch` size should be at least `n`.
|
|
|
|
|
// Returns Status::OK() on success.
|
|
|
|
|
virtual Status Read(uint64_t offset, size_t n, Slice* result, |
|
|
|
|
char* scratch) const override; |
|
|
|
|
char* scratch) const override; |
|
|
|
|
|
|
|
|
|
virtual Status Flush() override; |
|
|
|
|
|
|
|
|
@ -487,16 +462,15 @@ public: |
|
|
|
|
virtual Status Close() override; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class WinDirectory : public Directory { |
|
|
|
|
public: |
|
|
|
|
public: |
|
|
|
|
WinDirectory() {} |
|
|
|
|
|
|
|
|
|
virtual Status Fsync() override; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class WinFileLock : public FileLock { |
|
|
|
|
public: |
|
|
|
|
public: |
|
|
|
|
explicit WinFileLock(HANDLE hFile) : hFile_(hFile) { |
|
|
|
|
assert(hFile != NULL); |
|
|
|
|
assert(hFile != INVALID_HANDLE_VALUE); |
|
|
|
@ -504,9 +478,8 @@ public: |
|
|
|
|
|
|
|
|
|
~WinFileLock(); |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
private: |
|
|
|
|
HANDLE hFile_; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|