Skip to content

Commit

Permalink
Add storage version info
Browse files Browse the repository at this point in the history
  • Loading branch information
acquamarin committed Apr 2, 2023
1 parent 8a5a826 commit 2ebd3a3
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 1 deletion.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.11)

project(Kuzu VERSION 0.0.3.1 LANGUAGES CXX)
project(Kuzu VERSION 0.0.3.3 LANGUAGES CXX)

find_package(Threads REQUIRED)

Expand Down Expand Up @@ -78,6 +78,7 @@ function(add_kuzu_test TEST_NAME)
endfunction()

add_definitions(-DKUZU_ROOT_DIRECTORY="${PROJECT_SOURCE_DIR}")
add_definitions(-DKUZU_STORAGE_VERSION="${CMAKE_PROJECT_VERSION}")

set(ARROW_INSTALL ${CMAKE_CURRENT_SOURCE_DIR}/external/build/arrow/install)
find_library(ARROW_DEPS_PATH arrow_bundled_dependencies HINTS ${ARROW_INSTALL}/lib ${ARROW_INSTALL}/lib64)
Expand Down
37 changes: 37 additions & 0 deletions src/catalog/catalog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,9 @@ void CatalogContent::saveToFile(const std::string& directory, DBFileType dbFileT
auto catalogPath = StorageUtils::getCatalogFilePath(directory, dbFileType);
auto fileInfo = FileUtils::openFile(catalogPath, O_WRONLY | O_CREAT);
uint64_t offset = 0;
writeMagicBytes(fileInfo.get(), offset);
offset = SerDeser::serializeValue<uint64_t>(
StorageVersionInfo::getStorageVersion(), fileInfo.get(), offset);
offset = SerDeser::serializeValue<uint64_t>(nodeTableSchemas.size(), fileInfo.get(), offset);
offset = SerDeser::serializeValue<uint64_t>(relTableSchemas.size(), fileInfo.get(), offset);
for (auto& nodeTableSchema : nodeTableSchemas) {
Expand All @@ -316,6 +319,10 @@ void CatalogContent::readFromFile(const std::string& directory, DBFileType dbFil
logger->debug("Reading from {}.", catalogPath);
auto fileInfo = FileUtils::openFile(catalogPath, O_RDONLY);
uint64_t offset = 0;
validateMagicBytes(fileInfo.get(), offset);
storage::storage_version_t savedStorageVersion;
offset = SerDeser::deserializeValue<uint64_t>(savedStorageVersion, fileInfo.get(), offset);
validateStorageVersion(savedStorageVersion);
uint64_t numNodeTables, numRelTables;
offset = SerDeser::deserializeValue<uint64_t>(numNodeTables, fileInfo.get(), offset);
offset = SerDeser::deserializeValue<uint64_t>(numRelTables, fileInfo.get(), offset);
Expand All @@ -342,6 +349,36 @@ void CatalogContent::readFromFile(const std::string& directory, DBFileType dbFil
SerDeser::deserializeValue<table_id_t>(nextTableID, fileInfo.get(), offset);
}

void CatalogContent::validateStorageVersion(storage_version_t savedStorageVersion) const {
auto storageVersion = StorageVersionInfo::getStorageVersion();
if (savedStorageVersion != storageVersion) {
throw common::RuntimeException(StringUtils::string_format(
"Trying to read a database file with a different version. "
"Database file version: {}, Current build storage version: {}",
savedStorageVersion, storageVersion));
}
}

void CatalogContent::validateMagicBytes(FileInfo* fileInfo, offset_t& offset) const {
auto numMagicBytes = strlen(StorageVersionInfo::MAGIC_BYTES);
uint8_t magicBytes[4];
for (auto i = 0u; i < numMagicBytes; i++) {
offset = SerDeser::deserializeValue<uint8_t>(magicBytes[i], fileInfo, offset);
}
if (memcmp(magicBytes, StorageVersionInfo::MAGIC_BYTES, numMagicBytes) != 0) {
throw common::RuntimeException(
"This is not a valid Kuzu database directory for the current version of Kuzu.");
}
}

void CatalogContent::writeMagicBytes(FileInfo* fileInfo, offset_t& offset) const {
auto numMagicBytes = strlen(StorageVersionInfo::MAGIC_BYTES);
for (auto i = 0u; i < numMagicBytes; i++) {
offset =
SerDeser::serializeValue<uint8_t>(StorageVersionInfo::MAGIC_BYTES[i], fileInfo, offset);
}
}

Catalog::Catalog() : wal{nullptr} {
catalogContentForReadOnlyTrx = std::make_unique<CatalogContent>();
builtInVectorOperations = std::make_unique<function::BuiltInVectorOperations>();
Expand Down
7 changes: 7 additions & 0 deletions src/include/catalog/catalog.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "common/utils.h"
#include "function/aggregate/built_in_aggregate_functions.h"
#include "function/built_in_vector_operations.h"
#include "storage/storage_info.h"
#include "storage/wal/wal.h"

namespace spdlog {
Expand Down Expand Up @@ -133,6 +134,12 @@ class CatalogContent {
private:
inline common::table_id_t assignNextTableID() { return nextTableID++; }

void validateStorageVersion(storage::storage_version_t savedStorageVersion) const;

void validateMagicBytes(common::FileInfo* fileInfo, common::offset_t& offset) const;

void writeMagicBytes(common::FileInfo* fileInfo, common::offset_t& offset) const;

private:
std::shared_ptr<spdlog::logger> logger;
std::unordered_map<common::table_id_t, std::unique_ptr<NodeTableSchema>> nodeTableSchemas;
Expand Down
31 changes: 31 additions & 0 deletions src/include/storage/storage_info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include "exception"
#include <string>

#include "common/utils.h"

namespace kuzu {
namespace storage {

using storage_version_t = uint64_t;

struct StorageVersionInfo {
static std::unordered_map<std::string, storage_version_t> getStorageVersionInfo() {
return {{"0.0.3.2", 2}, {"0.0.3.1", 1}};
}

static storage_version_t getStorageVersion() {
auto storageVersionInfo = getStorageVersionInfo();
if (!storageVersionInfo.contains(KUZU_STORAGE_VERSION)) {
throw common::RuntimeException(common::StringUtils::string_format(
"Invalid storage version name: {}", KUZU_STORAGE_VERSION));
}
return storageVersionInfo.at(KUZU_STORAGE_VERSION);
}

static constexpr const char* MAGIC_BYTES = "KUZU";
};

} // namespace storage
} // namespace kuzu

0 comments on commit 2ebd3a3

Please sign in to comment.