#pragma once
#include <cstdint>
#include <functional>
#include <optional>
#include <shared_mutex>
#include <unordered_map>
#include <unordered_set>
#include "attached_database.h"
#include "common/copy_constructors.h"
#include "storage/partition_storage_registry.h"
namespace lbug {
namespace catalog {
class Catalog;
class GraphCatalogEntry;
}
namespace storage {
class MemoryManager;
class StorageManager;
class PartitionStorageRegistry;
}
namespace main {
struct GraphWALReplayRequest;
class DatabaseManager {
public:
DatabaseManager();
~DatabaseManager();
void registerAttachedDatabase(std::unique_ptr<AttachedDatabase> attachedDatabase);
LBUG_API bool hasAttachedDatabase(const std::string& name);
LBUG_API AttachedDatabase* getAttachedDatabase(const std::string& name);
void detachDatabase(const std::string& databaseName);
std::string getDefaultDatabase() const { return defaultDatabase; }
bool hasDefaultDatabase() const { return defaultDatabase != ""; }
void setDefaultDatabase(const std::string& databaseName);
LBUG_API std::vector<AttachedDatabase*> getAttachedDatabases() const;
void createGraph(const std::string& graphName, storage::MemoryManager* memoryManager,
main::ClientContext* clientContext, bool isAnyGraph = false);
void dropGraph(const std::string& graphName, main::ClientContext* clientContext);
void loadGraphsFromCatalog(storage::MemoryManager* memoryManager,
main::ClientContext* clientContext);
void loadGraphsFromCatalog(storage::MemoryManager* memoryManager,
main::ClientContext* clientContext, bool mainCheckpointCommitted, bool checkpointBundle,
std::optional<common::uuid> legacyCheckpointDatabaseID = std::nullopt);
bool loadGraphFromCatalog(storage::MemoryManager* memoryManager,
main::ClientContext* clientContext, const std::string& graphName);
bool replayPendingGraphWALs(main::ClientContext* clientContext);
void setDefaultGraph(const std::string& graphName);
void clearDefaultGraph();
bool hasGraph(const std::string& graphName);
catalog::Catalog* getGraphCatalog(const std::string& graphName);
std::unique_ptr<catalog::Catalog> unloadGraphCatalog(const std::string& graphName);
void withGraphCatalog(const std::string& graphName,
const std::function<void(catalog::Catalog*)>& action);
bool withGraphCatalogIfAlive(catalog::Catalog* catalog,
const std::function<void()>& action) const;
catalog::Catalog* getDefaultGraphCatalog() const;
LBUG_API bool isDefaultGraphAny(const ClientContext& context) const;
catalog::Catalog* getReplayOwnerCatalog() const { return replayOwnerCatalog; }
void setReplayOwnerCatalog(catalog::Catalog* catalog) { replayOwnerCatalog = catalog; }
bool hasDefaultGraph() const { return defaultGraph != "" && defaultGraph != "main"; }
std::string getDefaultGraphName() const { return defaultGraph; }
std::vector<catalog::Catalog*> getGraphs() const;
void bumpGraphCatalogVersions(const std::unordered_set<catalog::Catalog*>& catalogs);
storage::StorageManager* getDefaultGraphStorageManager() const;
LBUG_API void invalidateCache();
static std::pair<catalog::Catalog*, storage::StorageManager*> resolveTableStorage(
const ClientContext& context, common::table_id_t tableID, const std::string& dbName = {});
LBUG_API static DatabaseManager* Get(const ClientContext& context);
private:
bool loadGraph(main::ClientContext* clientContext, storage::MemoryManager* memoryManager,
catalog::GraphCatalogEntry* graphEntry, bool mainCheckpointCommitted, bool checkpointBundle,
std::optional<common::uuid> legacyCheckpointDatabaseID);
std::vector<std::unique_ptr<AttachedDatabase>> attachedDatabases;
std::string defaultDatabase;
std::vector<std::unique_ptr<catalog::Catalog>> graphs;
std::unordered_set<const catalog::Catalog*> graphIdentities;
mutable std::shared_mutex graphsMutex;
inline static thread_local std::unordered_map<const DatabaseManager*, uint64_t>
graphsSharedHolds;
void acquireGraphsShared() const;
void releaseGraphsShared() const;
class GraphsSharedLock {
public:
explicit GraphsSharedLock(const DatabaseManager& dbManager) : dbManager(dbManager) {
dbManager.acquireGraphsShared();
}
DELETE_COPY_AND_MOVE(GraphsSharedLock);
~GraphsSharedLock() { dbManager.releaseGraphsShared(); }
private:
const DatabaseManager& dbManager;
};
storage::PartitionStorageRegistry partitionStorageRegistry;
catalog::Catalog* replayOwnerCatalog = nullptr;
std::vector<std::unique_ptr<GraphWALReplayRequest>> pendingGraphWALReplays;
public:
storage::PartitionStorageRegistry* getPartitionStorageRegistry() {
return &partitionStorageRegistry;
}
std::string defaultGraph;
};
} }