#pragma once
#include "common/types/uuid.h"
#include "storage/file_handle.h"
namespace lbug {
namespace storage {
class BufferManager;
class StorageManager;
struct ShadowPageRecord {
common::file_idx_t originalFileIdx = common::INVALID_PAGE_IDX;
common::page_idx_t originalPageIdx = common::INVALID_PAGE_IDX;
void serialize(common::Serializer& serializer) const;
static ShadowPageRecord deserialize(common::Deserializer& deserializer);
};
struct ShadowFileHeader {
common::uuid databaseID{0};
common::page_idx_t numShadowPages = 0;
};
static_assert(std::is_trivially_copyable_v<ShadowFileHeader>);
class BufferManager;
class ShadowFile {
public:
ShadowFile(BufferManager& bm, common::VirtualFileSystem* vfs, const std::string& databasePath);
bool hasShadowPage(common::file_idx_t originalFile, common::page_idx_t originalPage) const {
return shadowPagesMap.contains(originalFile) &&
shadowPagesMap.at(originalFile).contains(originalPage);
}
void clearShadowPage(common::file_idx_t originalFile, common::page_idx_t originalPage);
common::page_idx_t getShadowPage(common::file_idx_t originalFile,
common::page_idx_t originalPage) const;
common::page_idx_t getOrCreateShadowPage(common::file_idx_t originalFile,
common::page_idx_t originalPage);
FileHandle& getShadowingFH() const { return *shadowingFH; }
void applyShadowPages(StorageManager& storageManager, main::ClientContext& context) const;
void flushAll(main::ClientContext& context) const;
void clear(BufferManager& bm);
void reset();
static void replayShadowPageRecords(main::ClientContext& context);
private:
FileHandle* getOrCreateShadowingFH();
private:
BufferManager& bm;
std::string shadowFilePath;
common::VirtualFileSystem* vfs;
FileHandle* shadowingFH;
std::unordered_map<common::file_idx_t,
std::unordered_map<common::page_idx_t, common::page_idx_t>>
shadowPagesMap;
std::vector<ShadowPageRecord> shadowPageRecords;
};
} }