#pragma once
#include <cmath>
#include <filesystem>
#include <string>
#include <type_traits>
#include "common/constants.h"
#include "common/system_config.h"
#include "common/types/types.h"
#include <concepts>
#include <format>
namespace lbug {
namespace storage {
struct PageCursor {
PageCursor() : PageCursor{UINT32_MAX, UINT16_MAX} {};
PageCursor(common::page_idx_t pageIdx, uint32_t posInPage)
: pageIdx{pageIdx}, elemPosInPage{posInPage} {};
void nextPage() {
pageIdx++;
elemPosInPage = 0;
}
common::page_idx_t pageIdx;
uint32_t elemPosInPage;
};
static_assert(std::has_unique_object_representations_v<PageCursor>);
template<typename T>
concept NumericType = std::is_integral_v<T> || std::floating_point<T>;
class StorageUtils {
public:
enum class ColumnType {
DEFAULT = 0,
INDEX = 1, OFFSET = 2, DATA = 3, CSR_OFFSET = 4,
CSR_LENGTH = 5,
STRUCT_CHILD = 6,
NULL_MASK = 7,
};
template<NumericType T1, NumericType T2>
static uint64_t divideAndRoundUpTo(T1 v1, T2 v2) {
return std::ceil(static_cast<double>(v1) / static_cast<double>(v2));
}
static std::string getColumnName(const std::string& propertyName, ColumnType type,
const std::string& prefix);
static common::offset_t getStartOffsetOfNodeGroup(common::node_group_idx_t nodeGroupIdx) {
return nodeGroupIdx << common::StorageConfig::NODE_GROUP_SIZE_LOG2;
}
static common::node_group_idx_t getNodeGroupIdx(common::offset_t nodeOffset) {
return nodeOffset >> common::StorageConfig::NODE_GROUP_SIZE_LOG2;
}
static std::pair<common::node_group_idx_t, common::offset_t> getNodeGroupIdxAndOffsetInChunk(
common::offset_t nodeOffset) {
auto nodeGroupIdx = getNodeGroupIdx(nodeOffset);
auto offsetInChunk = nodeOffset - getStartOffsetOfNodeGroup(nodeGroupIdx);
return std::make_pair(nodeGroupIdx, offsetInChunk);
}
static std::string getWALFilePath(const std::string& path) {
return std::format("{}.{}", path, common::StorageConstants::WAL_FILE_SUFFIX);
}
static std::string getCheckpointWALFilePath(const std::string& path) {
return std::format("{}.{}", path, common::StorageConstants::CHECKPOINT_WAL_FILE_SUFFIX);
}
static std::string getShadowFilePath(const std::string& path) {
return std::format("{}.{}", path, common::StorageConstants::SHADOWING_SUFFIX);
}
static std::string getTmpFilePath(const std::string& path) {
return std::format("{}.{}", path, common::StorageConstants::TEMP_FILE_SUFFIX);
}
static std::string getGraphPath(const std::string& dbPath, const std::string& graphName) {
auto path = std::filesystem::path(dbPath);
auto base = path.stem().string();
auto ext = path.extension().string();
auto graphFile = std::filesystem::path(base + "." + graphName + ext);
return (path.parent_path() / graphFile).string();
}
static std::string expandPath(const main::ClientContext* context, const std::string& path);
static std::pair<uint64_t, uint64_t> getQuotientRemainder(uint64_t i, uint64_t divisor) {
return std::make_pair(i / divisor, i % divisor);
}
static uint32_t getDataTypeSize(const common::LogicalType& type);
};
} }