Heap.h 2.9 KB

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