1 | // Licensed under the Apache License 2.0 (see LICENSE file). |
2 | |
3 | #pragma once |
4 | |
5 | #include "common.h" |
6 | #include "compiler.h" |
7 | #include <gsl.h> |
8 | |
9 | namespace cheesebase { |
10 | |
11 | enum class BlockType { |
12 | pg = 'P', // 1 page (4k) |
13 | t1 = '1', // 1/2 page (2k) |
14 | t2 = '2', // 1/4 page (1k) |
15 | t3 = '3', // 1/8 page (512) |
16 | t4 = '4' // 1/16 page (256) |
17 | }; |
18 | |
19 | constexpr size_t toBlockSize(BlockType t) { |
20 | return t == BlockType::pg |
21 | ? k_page_size |
22 | : t == BlockType::t1 |
23 | ? k_page_size / 2 |
24 | : t == BlockType::t2 |
25 | ? k_page_size / 4 |
26 | : t == BlockType::t3 |
27 | ? k_page_size / 8 |
28 | : t == BlockType::t4 ? k_page_size / 16 |
29 | : throw ConsistencyError( |
30 | "Invalid block type"); |
31 | } |
32 | |
33 | CB_PACKED(struct DskBlockHdr { |
34 | DskBlockHdr() = default; |
35 | DskBlockHdr(BlockType type, Addr next) { |
36 | auto type_value = static_cast<uint64_t>(type); |
37 | Expects(type_value <= 0xff); |
38 | Expects(next < ((uint64_t)1 << 56)); |
39 | data = (type_value << 56) + (next & (((uint64_t)1 << 56) - 1)); |
40 | }; |
41 | |
42 | PageNr next() const noexcept { return (data & (((uint64_t)1 << 56) - 1)); } |
43 | |
44 | BlockType type() const noexcept { |
45 | return gsl::narrow_cast<BlockType>(data >> 56); |
46 | } |
47 | |
48 | uint64_t data; |
49 | }); |
50 | |
51 | const uint64_t magic = *((uint64_t const*)"CHSBSE01"); |
52 | |
53 | CB_PACKED(struct DskDatabaseHdr { |
54 | uint64_t magic; |
55 | uint64_t end_of_file; |
56 | uint64_t free_alloc_pg; |
57 | uint64_t free_alloc_t1; |
58 | uint64_t free_alloc_t2; |
59 | uint64_t free_alloc_t3; |
60 | uint64_t free_alloc_t4; |
61 | }); |
62 | static_assert(sizeof(DskDatabaseHdr) <= k_page_size / 2, |
63 | "Database header should be smaller than half of the page size"); |
64 | |
65 | using Key = uint64_t; |
66 | |
67 | CB_PACKED(struct DskKey { |
68 | DskKey() = default; |
69 | DskKey(uint32_t h, uint16_t i) : hash(h), index(i) {} |
70 | DskKey(Key k) { |
71 | k >>= 16; |
72 | index = gsl::narrow_cast<uint16_t>(k); |
73 | hash = gsl::narrow_cast<uint32_t>(k >> 16); |
74 | } |
75 | Key key() const { |
76 | return ((static_cast<uint64_t>(hash) << 16) + index) << 16; |
77 | } |
78 | uint32_t hash; |
79 | uint16_t index; |
80 | |
81 | bool operator!=(const DskKey& o) { |
82 | return this->hash != o.hash || this->index != o.index; |
83 | } |
84 | bool operator==(const DskKey& o) { return !(*this != o); } |
85 | }); |
86 | static_assert(sizeof(DskKey) == 6, "Invalid disk key size"); |
87 | |
88 | CB_PACKED(using DskKeyCacheSize = uint16_t); |
89 | static_assert(sizeof(DskKeyCacheSize) == 2, "Invalid disk key cache size size"); |
90 | |
91 | CB_PACKED(struct DskValueHdr { |
92 | uint8_t magic_byte; |
93 | uint8_t type; |
94 | }); |
95 | static_assert(sizeof(DskValueHdr) == 2, "Invalid disk value header size"); |
96 | |
97 | CB_PACKED(struct DskPair { |
98 | DskKey key; |
99 | DskValueHdr value; |
100 | }); |
101 | static_assert(sizeof(DskPair) == 8, "invalid disk pair size"); |
102 | |
103 | } // namespace cheesebase |
(C++ example code for TinyBrain)
Travelled to 12 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1002114 |
Snippet name: | structs.h from cheesebase |
Eternal ID of this version: | #1002114/1 |
Text MD5: | 51038af73c2e17202b4c23eea9206537 |
Author: | stefan |
Category: | C++ |
Type: | Document |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2015-12-19 00:55:05 |
Source code size: | 2949 bytes / 103 lines |
Pitched / IR pitched: | No / Yes |
Views / Downloads: | 650 / 544 |
Referenced in: | [show references] |