123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- // Copyright 2019 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef SQL_RECOVER_MODULE_PAYLOAD_H_
- #define SQL_RECOVER_MODULE_PAYLOAD_H_
- #include <cstdint>
- #include <ostream>
- #include <vector>
- #include "base/check_op.h"
- #include "base/memory/raw_ptr.h"
- #include "base/sequence_checker.h"
- #include "sql/recover_module/pager.h"
- namespace sql {
- namespace recover {
- class DatabasePageReader;
- // Reads payloads (records) across B-tree pages and overflow pages.
- //
- // Instances are designed to be reused for reading multiple payloads. Instances
- // are not thread-safe.
- //
- // Reading a payload is started by calling Initialize() with the information
- // from LeafPageDecoder. If the call succeeds, ReadPayload() can be called
- // repeatedly.
- class LeafPayloadReader {
- public:
- // Number of payload bytes guaranteed to be on the B-tree page.
- //
- // The value is derived from the minimum SQLite usable page size, which is
- // 380 bytes, and the formula for the minimum payload size given a usable page
- // size.
- static constexpr int kMinInlineSize = ((380 - 12) * 32) / 255 - 23;
- explicit LeafPayloadReader(DatabasePageReader* db_reader);
- ~LeafPayloadReader();
- LeafPayloadReader(const LeafPayloadReader&) = delete;
- LeafPayloadReader& operator=(const LeafPayloadReader&) = delete;
- // Sets up the reader for a new payload.
- //
- // The DatabasePageReader passed to the constructor must be focused on the
- // page containing the payload.
- //
- // This method must complete successfully before any other method on this
- // class can be called.
- bool Initialize(int64_t payload_size, int payload_offset);
- // The number of payload bytes that are stored on the B-tree page.
- //
- // The return value is guaranteed to be non-negative and at most
- // payload_size().
- int inline_payload_size() const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(page_id_ != DatabasePageReader::kInvalidPageId)
- << "Initialize() not called, or last call did not succeed";
- DCHECK_LE(inline_payload_size_, payload_size_);
- return inline_payload_size_;
- }
- // Total payload size, in bytes.
- //
- // This includes the bytes stored in the B-tree page, as well as any bytes
- // stored in overflow pages.
- //
- // The return value is guaranteed to be at least inline_payload_size().
- int payload_size() const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(page_id_ != DatabasePageReader::kInvalidPageId)
- << "Initialize() not called, or last call did not succeed";
- DCHECK_LE(inline_payload_size_, payload_size_);
- return payload_size_;
- }
- // Copies a subset of the payload into a given buffer.
- //
- // Returns true if the read succeeds.
- //
- // May only be called after a previous call to Initialize() that returns true.
- bool ReadPayload(int64_t offset, int64_t size, uint8_t* buffer);
- // Pulls the B-tree containing the payload into the database reader's cache.
- //
- // Returns a pointer to the beginning of the payload bytes. The pointer is
- // inside the database reader's buffer, and may get invalidated if the
- // database reader is used.
- //
- // Returns null if the read operation fails.
- //
- // May only be called after a previous call to Initialize() that returns true.
- const uint8_t* ReadInlinePayload();
- private:
- // Extends the cached list of overflow page IDs by one page.
- //
- // Returns false if the operation failed. Failures are due to read errors or
- // database corruption.
- bool PopulateNextOverflowPageId();
- // Used to read the pages containing the payload.
- //
- // Raw pointer usage is acceptable because this instance's owner is expected
- // to ensure that the DatabasePageReader outlives this.
- const raw_ptr<DatabasePageReader> db_reader_;
- // Total size of the current payload.
- int64_t payload_size_;
- // The ID of the B-tree page containing the current payload's inline bytes.
- //
- // Set to kInvalidPageId if the reader wasn't successfully initialized.
- int page_id_;
- // The start of the current payload's inline bytes on the B-tree page.
- //
- // Large payloads extend past the B-tree page containing the payload, via
- // overflow pages.
- int inline_payload_offset_;
- // Number of bytes in the current payload stored in its B-tree page.
- //
- // The rest of the payload is stored on overflow pages.
- int inline_payload_size_;
- // Number of overflow pages used by the payload.
- int overflow_page_count_;
- // Number of bytes in each overflow page that stores the payload.
- int max_overflow_payload_size_;
- // Page IDs for all the payload's overflow pages, in order.
- //
- // This list is populated on-demand.
- std::vector<int> overflow_page_ids_;
- SEQUENCE_CHECKER(sequence_checker_);
- };
- } // namespace recover
- } // namespace sql
- #endif // SQL_RECOVER_MODULE_PAYLOAD_H_
|