| 1 | //===----------------------------------------------------------------------===// |
| 2 | // DuckDB |
| 3 | // |
| 4 | // duckdb/common/file_buffer.hpp |
| 5 | // |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #pragma once |
| 10 | |
| 11 | #include "duckdb/common/constants.hpp" |
| 12 | #include "duckdb/common/enums/debug_initialize.hpp" |
| 13 | |
| 14 | namespace duckdb { |
| 15 | class Allocator; |
| 16 | struct FileHandle; |
| 17 | |
| 18 | enum class FileBufferType : uint8_t { BLOCK = 1, MANAGED_BUFFER = 2, TINY_BUFFER = 3 }; |
| 19 | |
| 20 | //! The FileBuffer represents a buffer that can be read or written to a Direct IO FileHandle. |
| 21 | class FileBuffer { |
| 22 | public: |
| 23 | //! Allocates a buffer of the specified size, with room for additional header bytes |
| 24 | //! (typically 8 bytes). On return, this->AllocSize() >= this->size >= user_size. |
| 25 | //! Our allocation size will always be page-aligned, which is necessary to support |
| 26 | //! DIRECT_IO |
| 27 | FileBuffer(Allocator &allocator, FileBufferType type, uint64_t user_size); |
| 28 | FileBuffer(FileBuffer &source, FileBufferType type); |
| 29 | |
| 30 | virtual ~FileBuffer(); |
| 31 | |
| 32 | Allocator &allocator; |
| 33 | //! The type of the buffer |
| 34 | FileBufferType type; |
| 35 | //! The buffer that users can write to |
| 36 | data_ptr_t buffer; |
| 37 | //! The size of the portion that users can write to, this is equivalent to internal_size - BLOCK_HEADER_SIZE |
| 38 | uint64_t size; |
| 39 | |
| 40 | public: |
| 41 | //! Read into the FileBuffer from the specified location. |
| 42 | void Read(FileHandle &handle, uint64_t location); |
| 43 | //! Write the contents of the FileBuffer to the specified location. |
| 44 | void Write(FileHandle &handle, uint64_t location); |
| 45 | |
| 46 | void Clear(); |
| 47 | |
| 48 | // Same rules as the constructor. We will add room for a header, in additio to |
| 49 | // the requested user bytes. We will then sector-align the result. |
| 50 | void Resize(uint64_t user_size); |
| 51 | |
| 52 | uint64_t AllocSize() const { |
| 53 | return internal_size; |
| 54 | } |
| 55 | data_ptr_t InternalBuffer() { |
| 56 | return internal_buffer; |
| 57 | } |
| 58 | |
| 59 | struct MemoryRequirement { |
| 60 | idx_t alloc_size; |
| 61 | idx_t ; |
| 62 | }; |
| 63 | |
| 64 | MemoryRequirement CalculateMemory(uint64_t user_size); |
| 65 | |
| 66 | void Initialize(DebugInitialize info); |
| 67 | |
| 68 | protected: |
| 69 | //! The pointer to the internal buffer that will be read or written, including the buffer header |
| 70 | data_ptr_t internal_buffer; |
| 71 | //! The aligned size as passed to the constructor. This is the size that is read or written to disk. |
| 72 | uint64_t internal_size; |
| 73 | |
| 74 | void ReallocBuffer(size_t malloc_size); |
| 75 | void Init(); |
| 76 | }; |
| 77 | |
| 78 | } // namespace duckdb |
| 79 | |