11 #include "exceptions/insufficient_space_exception.h"
12 #include "exceptions/invalid_record_exception.h"
13 #include "exceptions/invalid_slot_exception.h"
14 #include "exceptions/slot_in_use_exception.h"
15 #include "page_iterator.h"
25 void Page::initialize() {
41 const SlotId slot_number = getAvailableSlot();
42 insertRecordInSlot(slot_number, record_data);
47 validateRecordId(record_id);
55 const std::string& record_data) {
56 validateRecordId(record_id);
58 const std::size_t free_space_after_delete =
60 if (record_data.length() > free_space_after_delete) {
62 page_number(), record_data.length(), free_space_after_delete);
68 insertRecordInSlot(record_id.
slot_number, record_data);
76 const bool allow_slot_compaction) {
77 validateRecordId(record_id);
87 std::size_t move_bytes = 0;
101 if (move_bytes > 0) {
102 const std::string& data_to_move = std::string(data_,
DATA_SIZE).substr(move_offset, move_bytes);
104 for(std::uint16_t i = 0; i < move_bytes; i++)
105 data_[i + move_offset + slot->
item_length] = data_to_move[i];
120 int num_slots_to_delete = 1;
123 const PageSlot* other_slot = getSlot(header_.
num_slots - i);
124 if (!other_slot->used) {
125 ++num_slots_to_delete;
132 header_.
num_slots -= num_slots_to_delete;
139 std::size_t record_size = record_data.length();
147 return reinterpret_cast<PageSlot*
>(&data_[(slot_number - 1) *
sizeof(
PageSlot)]);
150 const PageSlot& Page::getSlot(
const SlotId slot_number)
const {
151 return *
reinterpret_cast<const PageSlot*
>(&data_[(slot_number - 1) *
sizeof(PageSlot)]);
154 SlotId Page::getAvailableSlot() {
159 const PageSlot* slot = getSlot(i);
175 return static_cast<SlotId>(slot_number);
178 void Page::insertRecordInSlot(
const SlotId slot_number,
179 const std::string& record_data) {
182 throw InvalidSlotException(
page_number(), slot_number);
184 PageSlot* slot = getSlot(slot_number);
186 throw SlotInUseException(
page_number(), slot_number);
188 const int record_length = record_data.length();
190 slot->item_length = record_length;
195 for(
int i = 0; i < slot->item_length; i++)
196 data_[i + slot->item_offset] = record_data[i];
201 void Page::validateRecordId(
const RecordId& record_id)
const {
203 throw InvalidRecordException(record_id,
page_number());
205 const PageSlot& slot = getSlot(record_id.slot_number);
207 throw InvalidRecordException(record_id,
page_number());
std::uint16_t item_offset
void updateRecord(const RecordId &record_id, const std::string &record_data)
std::string getRecord(const RecordId &record_id) const
Iterator for iterating over the records in a page.
static const std::size_t DATA_SIZE
std::uint16_t item_length
PageId page_number() const
Slot metadata that tracks where a record is in the data space.
Identifier for a record in a page.
static const SlotId INVALID_SLOT
std::uint16_t getFreeSpace() const
static const PageId INVALID_NUMBER
An exception that is thrown when a record is attempted to be inserted into a page that doesn't have s...
std::uint16_t SlotId
Identifier for a slot in a page.
bool hasSpaceForRecord(const std::string &record_data) const
void deleteRecord(const RecordId &record_id)
RecordId insertRecord(const std::string &record_data)