diff --git a/Userland/Libraries/LibSQL/Heap.cpp b/Userland/Libraries/LibSQL/Heap.cpp index 8ba5f3745a..e70a41e933 100644 --- a/Userland/Libraries/LibSQL/Heap.cpp +++ b/Userland/Libraries/LibSQL/Heap.cpp @@ -46,12 +46,9 @@ ErrorOr Heap::open() if (file_size > 0) m_next_block = m_end_of_file = file_size / BLOCKSIZE; - auto file_or_error = Core::File::open(name(), Core::OpenMode::ReadWrite); - if (file_or_error.is_error()) { - warnln("Heap::open({}): could not open: {}"sv, name(), file_or_error.error()); - return Error::from_string_literal("Heap::open(): could not open file"); - } - m_file = file_or_error.value(); + auto file = TRY(Core::Stream::File::open(name(), Core::Stream::OpenMode::ReadWrite)); + m_file = TRY(Core::Stream::BufferedFile::create(move(file))); + if (file_size > 0) { if (auto error_maybe = read_zero_block(); error_maybe.is_error()) { m_file = nullptr; @@ -60,42 +57,41 @@ ErrorOr Heap::open() } else { initialize_zero_block(); } + dbgln_if(SQL_DEBUG, "Heap file {} opened. Size = {}", name(), size()); return {}; } ErrorOr Heap::read_block(u32 block) { - if (m_file.is_null()) { + if (!m_file) { warnln("Heap({})::read_block({}): Heap file not opened"sv, name(), block); return Error::from_string_literal("Heap()::read_block(): Heap file not opened"); } - auto buffer_or_empty = m_write_ahead_log.get(block); - if (buffer_or_empty.has_value()) - return buffer_or_empty.release_value(); + + if (auto buffer = m_write_ahead_log.get(block); buffer.has_value()) + return TRY(ByteBuffer::copy(*buffer)); if (block >= m_next_block) { warnln("Heap({})::read_block({}): block # out of range (>= {})"sv, name(), block, m_next_block); return Error::from_string_literal("Heap()::read_block(): block # out of range"); } + dbgln_if(SQL_DEBUG, "Read heap block {}", block); TRY(seek_block(block)); - auto ret = m_file->read(BLOCKSIZE); - if (ret.is_empty()) { - warnln("Heap({})::read_block({}): Could not read block"sv, name(), block); - return Error::from_string_literal("Heap()::read_block(): Could not read block"); - } - dbgln_if(SQL_DEBUG, "{:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x}", - *ret.offset_pointer(0), *ret.offset_pointer(1), - *ret.offset_pointer(2), *ret.offset_pointer(3), - *ret.offset_pointer(4), *ret.offset_pointer(5), - *ret.offset_pointer(6), *ret.offset_pointer(7)); - return ret; + + auto buffer = TRY(ByteBuffer::create_uninitialized(BLOCKSIZE)); + auto bytes = TRY(m_file->read(buffer)); + + dbgln_if(SQL_DEBUG, "{:hex-dump}", bytes.trim(8)); + TRY(buffer.try_resize(bytes.size())); + + return buffer; } ErrorOr Heap::write_block(u32 block, ByteBuffer& buffer) { - if (m_file.is_null()) { + if (!m_file) { warnln("Heap({})::write_block({}): Heap file not opened"sv, name(), block); return Error::from_string_literal("Heap()::write_block(): Heap file not opened"); } @@ -103,61 +99,49 @@ ErrorOr Heap::write_block(u32 block, ByteBuffer& buffer) warnln("Heap({})::write_block({}): block # out of range (> {})"sv, name(), block, m_next_block); return Error::from_string_literal("Heap()::write_block(): block # out of range"); } - TRY(seek_block(block)); - dbgln_if(SQL_DEBUG, "Write heap block {} size {}", block, buffer.size()); if (buffer.size() > BLOCKSIZE) { warnln("Heap({})::write_block({}): Oversized block ({} > {})"sv, name(), block, buffer.size(), BLOCKSIZE); return Error::from_string_literal("Heap()::write_block(): Oversized block"); } - auto sz = buffer.size(); - if (sz < BLOCKSIZE) { - if (buffer.try_resize(BLOCKSIZE).is_error()) { - warnln("Heap({})::write_block({}): Could not align block of size {} to {}"sv, name(), block, buffer.size(), BLOCKSIZE); - return Error::from_string_literal("Heap()::write_block(): Could not align block"); - } - memset(buffer.offset_pointer((int)sz), 0, BLOCKSIZE - sz); + + dbgln_if(SQL_DEBUG, "Write heap block {} size {}", block, buffer.size()); + TRY(seek_block(block)); + + if (auto current_size = buffer.size(); current_size < BLOCKSIZE) { + TRY(buffer.try_resize(BLOCKSIZE)); + memset(buffer.offset_pointer((int)current_size), 0, BLOCKSIZE - current_size); } - dbgln_if(SQL_DEBUG, "{:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x}", - *buffer.offset_pointer(0), *buffer.offset_pointer(1), - *buffer.offset_pointer(2), *buffer.offset_pointer(3), - *buffer.offset_pointer(4), *buffer.offset_pointer(5), - *buffer.offset_pointer(6), *buffer.offset_pointer(7)); - if (m_file->write(buffer.data(), (int)buffer.size())) { - if (block == m_end_of_file) - m_end_of_file++; - return {}; - } - warnln("Heap({})::write_block({}): Could not full write block"sv, name(), block); - return Error::from_string_literal("Heap()::write_block(): Could not full write block"); + + dbgln_if(SQL_DEBUG, "{:hex-dump}", buffer.bytes().trim(8)); + TRY(m_file->write(buffer)); + + if (block == m_end_of_file) + m_end_of_file++; + return {}; } ErrorOr Heap::seek_block(u32 block) { - if (m_file.is_null()) { + if (!m_file) { warnln("Heap({})::seek_block({}): Heap file not opened"sv, name(), block); return Error::from_string_literal("Heap()::seek_block(): Heap file not opened"); } - if (block == m_end_of_file) { - off_t pos; - if (!m_file->seek(0, Core::SeekMode::FromEndPosition, &pos)) { - warnln("Heap({})::seek_block({}): Error seeking end of file: {}"sv, name(), block, m_file->error_string()); - return Error::from_string_literal("Heap()::seek_block(): Error seeking end of file"); - } - } else if (block > m_end_of_file) { + if (block > m_end_of_file) { warnln("Heap({})::seek_block({}): Cannot seek beyond end of file at block {}"sv, name(), block, m_end_of_file); return Error::from_string_literal("Heap()::seek_block(): Cannot seek beyond end of file"); - } else { - if (!m_file->seek(block * BLOCKSIZE)) { - warnln("Heap({})::seek_block({}): Error seeking: {}"sv, name(), block, m_file->error_string()); - return Error::from_string_literal("Heap()::seek_block(): Error seeking: {}"); - } } + + if (block == m_end_of_file) + TRY(m_file->seek(0, Core::Stream::SeekMode::FromEndPosition)); + else + TRY(m_file->seek(block * BLOCKSIZE, Core::Stream::SeekMode::SetPosition)); + return {}; } u32 Heap::new_record_pointer() { - VERIFY(!m_file.is_null()); + VERIFY(m_file); if (m_free_list) { auto block_or_error = read_block(m_free_list); if (block_or_error.is_error()) { @@ -174,7 +158,7 @@ u32 Heap::new_record_pointer() ErrorOr Heap::flush() { - VERIFY(!m_file.is_null()); + VERIFY(m_file); Vector blocks; for (auto& wal_entry : m_write_ahead_log) { blocks.append(wal_entry.key); diff --git a/Userland/Libraries/LibSQL/Heap.h b/Userland/Libraries/LibSQL/Heap.h index da0285a0e0..a51d97228d 100644 --- a/Userland/Libraries/LibSQL/Heap.h +++ b/Userland/Libraries/LibSQL/Heap.h @@ -11,8 +11,8 @@ #include #include #include -#include #include +#include namespace SQL { @@ -40,7 +40,7 @@ public: ErrorOr read_block(u32); [[nodiscard]] u32 new_record_pointer(); [[nodiscard]] bool has_block(u32 block) const { return block < size(); } - [[nodiscard]] bool valid() const { return m_file != nullptr; } + [[nodiscard]] bool valid() const { return static_cast(m_file); } u32 schemas_root() const { return m_schemas_root; } @@ -83,11 +83,7 @@ public: void add_to_wal(u32 block, ByteBuffer& buffer) { dbgln_if(SQL_DEBUG, "Adding to WAL: block #{}, size {}", block, buffer.size()); - dbgln_if(SQL_DEBUG, "{:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x}", - *buffer.offset_pointer(0), *buffer.offset_pointer(1), - *buffer.offset_pointer(2), *buffer.offset_pointer(3), - *buffer.offset_pointer(4), *buffer.offset_pointer(5), - *buffer.offset_pointer(6), *buffer.offset_pointer(7)); + dbgln_if(SQL_DEBUG, "{:hex-dump}", buffer.bytes().trim(8)); m_write_ahead_log.set(block, buffer); } @@ -102,7 +98,7 @@ private: void initialize_zero_block(); void update_zero_block(); - RefPtr m_file { nullptr }; + OwnPtr m_file; u32 m_free_list { 0 }; u32 m_next_block { 1 }; u32 m_end_of_file { 1 };