#pragma once
#include <unordered_map>
#include <vector>
#include "common/types/types.h"
#include "storage/database_header.h"
#include "storage/page_range.h"
namespace lbug {
namespace transaction {
class Transaction;
}
namespace catalog {
class Catalog;
}
namespace common {
class VirtualFileSystem;
} namespace testing {
struct FSMLeakChecker;
}
namespace main {
class AttachedLbugDatabase;
class DatabaseManager;
}
namespace storage {
class StorageManager;
class Checkpointer {
friend class main::AttachedLbugDatabase;
friend class main::DatabaseManager;
friend struct testing::FSMLeakChecker;
public:
explicit Checkpointer(main::ClientContext& clientContext);
virtual ~Checkpointer();
void writeCheckpoint();
void beginCheckpoint(common::transaction_t snapshotTS);
void checkpointStoragePhase();
void finishCheckpoint();
void postCheckpointCleanup();
void rollback();
bool wasWalRotated() const { return walRotated; }
void readCheckpoint();
static bool canAutoCheckpoint(const main::ClientContext& clientContext,
const transaction::Transaction& transaction);
protected:
virtual bool checkpointStorage();
virtual void serializeCatalogAndMetadata(DatabaseHeader& databaseHeader,
bool hasStorageChanges);
virtual void writeDatabaseHeader(const DatabaseHeader& header);
virtual void logCheckpointAndApplyShadowPages(bool walRotated = false);
private:
struct CheckpointTarget {
catalog::Catalog* catalog;
StorageManager* storageManager;
};
std::vector<CheckpointTarget> collectCheckpointTargets() const;
static void readCheckpoint(main::ClientContext* context, catalog::Catalog* catalog,
StorageManager* storageManager);
PageRange serializeCatalog(const catalog::Catalog& catalog, StorageManager& storageManager);
PageRange serializeCatalogSnapshot(const catalog::Catalog& catalog,
StorageManager& storageManager);
PageRange serializeMetadata(const catalog::Catalog& catalog, StorageManager& storageManager);
PageRange serializeMetadataSnapshot(const catalog::Catalog& catalog,
StorageManager& storageManager);
protected:
main::ClientContext& clientContext;
bool isInMemory;
StorageManager* mainStorageManager;
bool walRotated = false;
common::transaction_t snapshotTS = 0;
DatabaseHeader checkpointHeader{};
bool hasStorageChanges = false;
bool hasStorageVersionUpgrade = false;
uint64_t catalogVersionAtCheckpoint = 0;
uint64_t pageManagerVersionAtCheckpoint = 0;
std::unordered_map<common::table_id_t, uint64_t> tableEpochWatermarks;
std::unordered_map<StorageManager*, bool> storageChangesByManager;
std::unordered_map<StorageManager*, bool> walRotatedByManager;
std::vector<CheckpointTarget> checkpointTargets;
std::unordered_map<StorageManager*, std::unordered_map<common::table_id_t, uint64_t>>
tableEpochWatermarksByManager;
std::unordered_map<catalog::Catalog*, uint64_t> catalogVersionAtCheckpointByCatalog;
std::unordered_map<StorageManager*, uint64_t> pageManagerVersionAtCheckpointByManager;
};
} }