Serenity Operating System
at master 114 lines 3.0 kB view raw
1/* 2 * Copyright (c) 2021, Jan de Visser <jan@de-visser.net> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/Array.h> 10#include <AK/Debug.h> 11#include <AK/DeprecatedString.h> 12#include <AK/HashMap.h> 13#include <AK/Vector.h> 14#include <LibCore/File.h> 15#include <LibCore/Object.h> 16 17namespace SQL { 18 19constexpr static u32 BLOCKSIZE = 1024; 20 21/** 22 * A Heap is a logical container for database (SQL) data. Conceptually a 23 * Heap can be a database file, or a memory block, or another storage medium. 24 * It contains datastructures, like B-Trees, hash_index tables, or tuple stores 25 * (basically a list of data tuples). 26 * 27 * A Heap can be thought of the backing storage of a single database. It's 28 * assumed that a single SQL database is backed by a single Heap. 29 * 30 * Currently only B-Trees and tuple stores are implemented. 31 */ 32class Heap : public Core::Object { 33 C_OBJECT(Heap); 34 35public: 36 static constexpr inline u32 current_version = 3; 37 38 virtual ~Heap() override; 39 40 ErrorOr<void> open(); 41 u32 size() const { return m_end_of_file; } 42 ErrorOr<ByteBuffer> read_block(u32); 43 [[nodiscard]] u32 new_record_pointer(); 44 [[nodiscard]] bool valid() const { return static_cast<bool>(m_file); } 45 46 u32 schemas_root() const { return m_schemas_root; } 47 48 void set_schemas_root(u32 root) 49 { 50 m_schemas_root = root; 51 update_zero_block(); 52 } 53 54 u32 tables_root() const { return m_tables_root; } 55 56 void set_tables_root(u32 root) 57 { 58 m_tables_root = root; 59 update_zero_block(); 60 } 61 62 u32 table_columns_root() const { return m_table_columns_root; } 63 64 void set_table_columns_root(u32 root) 65 { 66 m_table_columns_root = root; 67 update_zero_block(); 68 } 69 u32 version() const { return m_version; } 70 71 u32 user_value(size_t index) const 72 { 73 VERIFY(index < m_user_values.size()); 74 return m_user_values[index]; 75 } 76 77 void set_user_value(size_t index, u32 value) 78 { 79 VERIFY(index < m_user_values.size()); 80 m_user_values[index] = value; 81 update_zero_block(); 82 } 83 84 void add_to_wal(u32 block, ByteBuffer& buffer) 85 { 86 dbgln_if(SQL_DEBUG, "Adding to WAL: block #{}, size {}", block, buffer.size()); 87 dbgln_if(SQL_DEBUG, "{:hex-dump}", buffer.bytes().trim(8)); 88 m_write_ahead_log.set(block, buffer); 89 } 90 91 ErrorOr<void> flush(); 92 93private: 94 explicit Heap(DeprecatedString); 95 96 ErrorOr<void> write_block(u32, ByteBuffer&); 97 ErrorOr<void> seek_block(u32); 98 ErrorOr<void> read_zero_block(); 99 void initialize_zero_block(); 100 void update_zero_block(); 101 102 OwnPtr<Core::BufferedFile> m_file; 103 u32 m_free_list { 0 }; 104 u32 m_next_block { 1 }; 105 u32 m_end_of_file { 1 }; 106 u32 m_schemas_root { 0 }; 107 u32 m_tables_root { 0 }; 108 u32 m_table_columns_root { 0 }; 109 u32 m_version { current_version }; 110 Array<u32, 16> m_user_values { 0 }; 111 HashMap<u32, ByteBuffer> m_write_ahead_log; 112}; 113 114}