#pragma once
#include "hash_index_slot.h"
namespace lbug {
namespace storage {
struct HashIndexHeaderOnDisk {
explicit HashIndexHeaderOnDisk()
: nextSplitSlotId{0}, numEntries{0},
firstFreeOverflowSlotId{SlotHeader::INVALID_OVERFLOW_SLOT_ID}, currentLevel{0} {}
slot_id_t nextSplitSlotId;
uint64_t numEntries;
slot_id_t firstFreeOverflowSlotId;
uint8_t currentLevel;
uint8_t _padding[7]{};
};
static_assert(std::has_unique_object_representations_v<HashIndexHeaderOnDisk>);
class HashIndexHeader {
public:
explicit HashIndexHeader()
: currentLevel{1}, levelHashMask{1}, higherLevelHashMask{3}, nextSplitSlotId{0},
numEntries{0}, firstFreeOverflowSlotId{SlotHeader::INVALID_OVERFLOW_SLOT_ID} {}
explicit HashIndexHeader(const HashIndexHeaderOnDisk& onDiskHeader)
: currentLevel{onDiskHeader.currentLevel}, levelHashMask{(1ull << this->currentLevel) - 1},
higherLevelHashMask{(1ull << (this->currentLevel + 1)) - 1},
nextSplitSlotId{onDiskHeader.nextSplitSlotId}, numEntries{onDiskHeader.numEntries},
firstFreeOverflowSlotId{onDiskHeader.firstFreeOverflowSlotId} {}
inline void incrementLevel() {
currentLevel++;
nextSplitSlotId = 0;
levelHashMask = (1 << currentLevel) - 1;
higherLevelHashMask = (1 << (currentLevel + 1)) - 1;
}
inline void incrementNextSplitSlotId() {
if (nextSplitSlotId < (1ull << currentLevel) - 1) {
nextSplitSlotId++;
} else {
incrementLevel();
}
}
inline void write(HashIndexHeaderOnDisk& onDiskHeader) const {
onDiskHeader.currentLevel = currentLevel;
onDiskHeader.nextSplitSlotId = nextSplitSlotId;
onDiskHeader.numEntries = numEntries;
onDiskHeader.firstFreeOverflowSlotId = firstFreeOverflowSlotId;
}
public:
uint64_t currentLevel;
uint64_t levelHashMask;
uint64_t higherLevelHashMask;
slot_id_t nextSplitSlotId;
uint64_t numEntries;
slot_id_t firstFreeOverflowSlotId;
};
} }