diff options
| author | Devtools Arcadia <[email protected]> | 2022-02-07 18:08:42 +0300 |
|---|---|---|
| committer | Devtools Arcadia <[email protected]> | 2022-02-07 18:08:42 +0300 |
| commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
| tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /util/system/direct_io.h | |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'util/system/direct_io.h')
| -rw-r--r-- | util/system/direct_io.h | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/util/system/direct_io.h b/util/system/direct_io.h new file mode 100644 index 00000000000..6a3325a9608 --- /dev/null +++ b/util/system/direct_io.h @@ -0,0 +1,75 @@ +#pragma once + +#include "align.h" + +#include "file.h" +#include <util/generic/buffer.h> + +// Supports Linux Direct-IO: +// - Simple buffering logic. +// - Default buffer size of 128KB matches VM page writeback granularity, to maximize IO throughput. +// - Supports writing odd sized files by turning off direct IO for the last chunk. +class TDirectIOBufferedFile { +public: + TDirectIOBufferedFile(const TString& path, EOpenMode oMode, size_t buflen = 1 << 17); + ~TDirectIOBufferedFile(); + + void FlushData(); + void Finish(); + size_t Read(void* buffer, size_t byteCount); + void Write(const void* buffer, size_t byteCount); + size_t Pread(void* buffer, size_t byteCount, ui64 offset); + void Pwrite(const void* buffer, size_t byteCount, ui64 offset); + + inline bool IsOpen() const { + return true; + } + + inline ui64 GetWritePosition() const { + return WritePosition; + } + + inline ui64 GetLength() const { + return FlushedBytes + DataLen; + } + + inline FHANDLE GetHandle() { + return File.GetHandle(); + } + + inline void FallocateNoResize(ui64 length) { + File.FallocateNoResize(length); + } + + inline void ShrinkToFit() { + File.ShrinkToFit(); + } + +private: + inline bool IsAligned(i64 value) { + return Alignment ? value == AlignDown<i64>(value, Alignment) : true; + } + + inline bool IsAligned(const void* value) { + return Alignment ? value == AlignDown(value, Alignment) : true; + } + + size_t PreadSafe(void* buffer, size_t byteCount, ui64 offset); + size_t ReadFromFile(void* buffer, size_t byteCount, ui64 offset); + void WriteToFile(const void* buf, size_t len, ui64 position); + void WriteToBuffer(const void* buf, size_t len, ui64 position); + void SetDirectIO(bool value); + +private: + TFile File; + size_t Alignment; + size_t BufLen; + size_t DataLen; + void* Buffer; + TBuffer BufferStorage; + ui64 ReadPosition; + ui64 WritePosition; + ui64 FlushedBytes; + ui64 FlushedToDisk; + bool DirectIO; +}; |
