Heap.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * Copyright (c) 2021, Jan de Visser <jan@de-visser.net>
  3. * Copyright (c) 2023, Jelle Raaijmakers <jelle@gmta.nl>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/Array.h>
  9. #include <AK/Debug.h>
  10. #include <AK/DeprecatedString.h>
  11. #include <AK/HashMap.h>
  12. #include <LibCore/File.h>
  13. #include <LibCore/Object.h>
  14. namespace SQL {
  15. /**
  16. * A Block represents a single discrete chunk of 1024 bytes inside the Heap, and
  17. * acts as the container format for the actual data we are storing. This structure
  18. * is used for everything except block 0, the zero / super block.
  19. *
  20. * If data needs to be stored that is larger than 1016 bytes, Blocks are chained
  21. * together by setting the next block index and the data is reconstructed by
  22. * repeatedly reading blocks until the next block index is 0.
  23. */
  24. class Block {
  25. public:
  26. typedef u32 Index;
  27. static constexpr u32 SIZE = 1024;
  28. static constexpr u32 HEADER_SIZE = sizeof(u32) + sizeof(Index);
  29. static constexpr u32 DATA_SIZE = SIZE - HEADER_SIZE;
  30. Block(Index index, u32 size_in_bytes, Index next_block, ByteBuffer data)
  31. : m_index(index)
  32. , m_size_in_bytes(size_in_bytes)
  33. , m_next_block(next_block)
  34. , m_data(move(data))
  35. {
  36. }
  37. Index index() const { return m_index; }
  38. u32 size_in_bytes() const { return m_size_in_bytes; }
  39. Index next_block() const { return m_next_block; }
  40. ByteBuffer const& data() const { return m_data; }
  41. private:
  42. Index m_index;
  43. u32 m_size_in_bytes;
  44. Index m_next_block;
  45. ByteBuffer m_data;
  46. };
  47. /**
  48. * A Heap is a logical container for database (SQL) data. Conceptually a
  49. * Heap can be a database file, or a memory block, or another storage medium.
  50. * It contains datastructures, like B-Trees, hash_index tables, or tuple stores
  51. * (basically a list of data tuples).
  52. *
  53. * A Heap can be thought of the backing storage of a single database. It's
  54. * assumed that a single SQL database is backed by a single Heap.
  55. */
  56. class Heap : public Core::Object {
  57. C_OBJECT(Heap);
  58. public:
  59. static constexpr u32 VERSION = 4;
  60. virtual ~Heap() override;
  61. ErrorOr<void> open();
  62. bool has_block(Block::Index) const;
  63. [[nodiscard]] Block::Index request_new_block_index() { return m_next_block++; }
  64. Block::Index schemas_root() const { return m_schemas_root; }
  65. void set_schemas_root(Block::Index root)
  66. {
  67. m_schemas_root = root;
  68. update_zero_block().release_value_but_fixme_should_propagate_errors();
  69. }
  70. Block::Index tables_root() const { return m_tables_root; }
  71. void set_tables_root(Block::Index root)
  72. {
  73. m_tables_root = root;
  74. update_zero_block().release_value_but_fixme_should_propagate_errors();
  75. }
  76. Block::Index table_columns_root() const { return m_table_columns_root; }
  77. void set_table_columns_root(Block::Index root)
  78. {
  79. m_table_columns_root = root;
  80. update_zero_block().release_value_but_fixme_should_propagate_errors();
  81. }
  82. u32 version() const { return m_version; }
  83. u32 user_value(size_t index) const
  84. {
  85. return m_user_values[index];
  86. }
  87. void set_user_value(size_t index, u32 value)
  88. {
  89. m_user_values[index] = value;
  90. update_zero_block().release_value_but_fixme_should_propagate_errors();
  91. }
  92. ErrorOr<ByteBuffer> read_storage(Block::Index);
  93. ErrorOr<void> write_storage(Block::Index, ReadonlyBytes);
  94. ErrorOr<void> flush();
  95. private:
  96. explicit Heap(DeprecatedString);
  97. ErrorOr<ByteBuffer> read_raw_block(Block::Index);
  98. ErrorOr<void> write_raw_block(Block::Index, ReadonlyBytes);
  99. ErrorOr<void> write_raw_block_to_wal(Block::Index, ByteBuffer&&);
  100. ErrorOr<Block> read_block(Block::Index);
  101. ErrorOr<void> write_block(Block const&);
  102. ErrorOr<void> read_zero_block();
  103. ErrorOr<void> initialize_zero_block();
  104. ErrorOr<void> update_zero_block();
  105. OwnPtr<Core::BufferedFile> m_file;
  106. Block::Index m_highest_block_written { 0 };
  107. Block::Index m_next_block { 1 };
  108. Block::Index m_schemas_root { 0 };
  109. Block::Index m_tables_root { 0 };
  110. Block::Index m_table_columns_root { 0 };
  111. u32 m_version { VERSION };
  112. Array<u32, 16> m_user_values { 0 };
  113. HashMap<Block::Index, ByteBuffer> m_write_ahead_log;
  114. };
  115. }