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 | |