/*------------------------------------------------------------------------------* * Architecture & Implementation of DBMS * *------------------------------------------------------------------------------* * Copyright 2022 Databases and Information Systems Group TU Dortmund * * Visit us at * * http://dbis.cs.tu-dortmund.de/cms/en/home/ * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * * OTHER DEALINGS IN THE SOFTWARE. * * * * Authors: * * Maximilian Berens * * Roland Kühn * * Jan Mühlig * *------------------------------------------------------------------------------* */ #pragma once #include #include #include #include #include #include #include #include #include namespace beedb::storage { /** * Represents a page on disk, holding a header for meta information * and raw memory for storing data. * Pages can be linked logically. All linked pages contain data for the * same table; like a linked list of storage. */ class Page { public: using id_t = std::uint32_t; using offset_t = std::uint16_t; static constexpr id_t INVALID_PAGE_ID = std::numeric_limits::max(); static constexpr id_t MEMORY_TABLE_PAGE_ID = std::numeric_limits::max() - 1; public: Page() { _data.fill(std::byte{'\0'}); this->next_page_id(INVALID_PAGE_ID); } virtual ~Page() = default; /** * @return Id of this page. */ [[nodiscard]] id_t id() const { return _id; } void id(id_t id) { _id = id; } // [[nodiscard]] std::shared_mutex& latch() // { // return _rw_latch; // } [[nodiscard]] std::uint64_t pin_count() const { return _pin_count; } void pin_count(std::uint64_t pin_count) { _pin_count = pin_count; } [[nodiscard]] bool is_pinned() const { return _pin_count > 0u; } [[nodiscard]] bool is_dirty() const { return _is_dirty; } void is_dirty(bool is_dirty) { _is_dirty = is_dirty; } /** * @return Id of the page which is logical connected to this page. */ [[nodiscard]] id_t next_page_id() const { return *reinterpret_cast(_data.data()); } /** * Updates the next page id. * @param next_page_id Id of the next page. */ void next_page_id(const id_t next_page_id) { *reinterpret_cast(_data.data()) = next_page_id; } /** * @return True, when this page has a next page. */ [[nodiscard]] bool has_next_page() const { return next_page_id() != INVALID_PAGE_ID; } /** * @return Pointer to the data stored on this page. */ [[nodiscard]] std::byte *data() { return _data.data(); } [[nodiscard]] const std::byte *data() const { return _data.data(); } /** * @return True, when this is a persisted page. */ explicit operator bool() const { return _id < INVALID_PAGE_ID; } /** * @param index Index of data. * @return Pointer to the data. */ std::byte *operator[](const offset_t index) { return &_data[index]; } private: // Metadata storage::Page::id_t _id = storage::Page::INVALID_PAGE_ID; // std::shared_mutex _rw_latch; std::uint64_t _pin_count = 0u; bool _is_dirty = false; // Page data std::array _data{std::byte{'\0'}}; }; } // namespace beedb::storage