| 1 | //===----------------------------------------------------------------------===// |
| 2 | // DuckDB |
| 3 | // |
| 4 | // duckdb/storage/storage_info.hpp |
| 5 | // |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #pragma once |
| 10 | |
| 11 | #include "duckdb/common/constants.hpp" |
| 12 | #include "duckdb/common/vector_size.hpp" |
| 13 | |
| 14 | namespace duckdb { |
| 15 | class Serializer; |
| 16 | class Deserializer; |
| 17 | struct FileHandle; |
| 18 | |
| 19 | #define STANDARD_ROW_GROUPS_SIZE 122880 |
| 20 | #if STANDARD_ROW_GROUPS_SIZE < STANDARD_VECTOR_SIZE |
| 21 | #error Row groups should be able to hold at least one vector |
| 22 | #endif |
| 23 | |
| 24 | #if ((STANDARD_ROW_GROUPS_SIZE % STANDARD_VECTOR_SIZE) != 0) |
| 25 | #error Row group size should be cleanly divisible by vector size |
| 26 | #endif |
| 27 | |
| 28 | //! The version number of the database storage format |
| 29 | extern const uint64_t VERSION_NUMBER; |
| 30 | |
| 31 | const char *GetDuckDBVersion(idx_t version_number); |
| 32 | |
| 33 | using block_id_t = int64_t; |
| 34 | |
| 35 | #define INVALID_BLOCK (-1) |
| 36 | |
| 37 | // maximum block id, 2^62 |
| 38 | #define MAXIMUM_BLOCK 4611686018427388000LL |
| 39 | |
| 40 | //! The MainHeader is the first header in the storage file. The MainHeader is typically written only once for a database |
| 41 | //! file. |
| 42 | struct MainHeader { |
| 43 | static constexpr idx_t MAGIC_BYTE_SIZE = 4; |
| 44 | static constexpr idx_t MAGIC_BYTE_OFFSET = Storage::BLOCK_HEADER_SIZE; |
| 45 | static constexpr idx_t FLAG_COUNT = 4; |
| 46 | // the magic bytes in front of the file |
| 47 | // should be "DUCK" |
| 48 | static const char MAGIC_BYTES[]; |
| 49 | //! The version of the database |
| 50 | uint64_t version_number; |
| 51 | //! The set of flags used by the database |
| 52 | uint64_t flags[FLAG_COUNT]; |
| 53 | |
| 54 | static void CheckMagicBytes(FileHandle &handle); |
| 55 | |
| 56 | void Serialize(Serializer &ser); |
| 57 | static MainHeader Deserialize(Deserializer &source); |
| 58 | }; |
| 59 | |
| 60 | //! The DatabaseHeader contains information about the current state of the database. Every storage file has two |
| 61 | //! DatabaseHeaders. On startup, the DatabaseHeader with the highest iteration count is used as the active header. When |
| 62 | //! a checkpoint is performed, the active DatabaseHeader is switched by increasing the iteration count of the |
| 63 | //! DatabaseHeader. |
| 64 | struct { |
| 65 | //! The iteration count, increases by 1 every time the storage is checkpointed. |
| 66 | uint64_t ; |
| 67 | //! A pointer to the initial meta block |
| 68 | block_id_t ; |
| 69 | //! A pointer to the block containing the free list |
| 70 | block_id_t ; |
| 71 | //! The number of blocks that is in the file as of this database header. If the file is larger than BLOCK_SIZE * |
| 72 | //! block_count any blocks appearing AFTER block_count are implicitly part of the free_list. |
| 73 | uint64_t ; |
| 74 | |
| 75 | void (Serializer &ser); |
| 76 | static DatabaseHeader (Deserializer &source); |
| 77 | }; |
| 78 | |
| 79 | } // namespace duckdb |
| 80 | |