Skip to content

Commit

Permalink
test
Browse files Browse the repository at this point in the history
  • Loading branch information
acquamarin committed Feb 22, 2024
1 parent b61758e commit b22d112
Show file tree
Hide file tree
Showing 16 changed files with 89 additions and 32 deletions.
10 changes: 4 additions & 6 deletions src/catalog/catalog_content.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#include "catalog/catalog_content.h"

#include <fcntl.h>

#include "binder/ddl/bound_create_table_info.h"
#include "catalog/catalog_entry/node_table_catalog_entry.h"
#include "catalog/catalog_entry/rdf_graph_catalog_entry.h"
Expand Down Expand Up @@ -176,8 +174,8 @@ static void writeMagicBytes(Serializer& serializer) {

void CatalogContent::saveToFile(const std::string& directory, FileVersionType dbFileType) {
auto catalogPath = StorageUtils::getCatalogFilePath(vfs, directory, dbFileType);
Serializer serializer(
std::make_unique<BufferedFileWriter>(vfs->openFile(catalogPath, O_WRONLY | O_CREAT)));
Serializer serializer(std::make_unique<BufferedFileWriter>(vfs->openFile(
catalogPath, FileFlags::FILE_FLAGS_WRITE | FileFlags::FILE_FLAGS_FILE_CREATE)));
writeMagicBytes(serializer);
serializer.serializeValue(StorageVersionInfo::getStorageVersion());
tables->serialize(serializer);
Expand All @@ -187,8 +185,8 @@ void CatalogContent::saveToFile(const std::string& directory, FileVersionType db

void CatalogContent::readFromFile(const std::string& directory, FileVersionType dbFileType) {
auto catalogPath = StorageUtils::getCatalogFilePath(vfs, directory, dbFileType);
Deserializer deserializer(
std::make_unique<BufferedFileReader>(vfs->openFile(catalogPath, O_RDONLY)));
Deserializer deserializer(std::make_unique<BufferedFileReader>(
vfs->openFile(catalogPath, FileFlags::FILE_FLAGS_READ)));
validateMagicBytes(deserializer);
storage_version_t savedStorageVersion;
deserializer.deserializeValue(savedStorageVersion);
Expand Down
53 changes: 48 additions & 5 deletions src/common/file_system/local_file_system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ LocalFileInfo::~LocalFileInfo() {
#endif
}

static void validateFileFlags(uint8_t flags) {
bool isRead = flags & FileFlags::FILE_FLAGS_READ;
bool isWrite = flags & FileFlags::FILE_FLAGS_WRITE;
// Require either READ or WRITE (or both).
KU_ASSERT(isRead || isWrite);
// CREATE/Append flags require writing.
KU_ASSERT(isWrite || !(flags & FileFlags::FILE_FLAGS_APPEND));
KU_ASSERT(isWrite || !(flags & FileFlags::FILE_FLAGS_FILE_CREATE));
KU_ASSERT(isWrite || !(flags & FileFlags::FILE_FLAGS_FILE_CREATE_NEW));
// CREATE and CREATE_NEW flags cannot be combined.
KU_ASSERT(!(flags & FileFlags::FILE_FLAGS_FILE_CREATE &&
flags & FileFlags::FILE_FLAGS_FILE_CREATE_NEW));
}

std::unique_ptr<FileInfo> LocalFileSystem::openFile(
const std::string& path, int flags, main::ClientContext* context, FileLockType lock_type) {
auto fullPath = path;
Expand All @@ -47,15 +61,44 @@ std::unique_ptr<FileInfo> LocalFileSystem::openFile(
context->getCurrentSetting(main::HomeDirectorySetting::name).getValue<std::string>() +
fullPath.substr(1);
}
validateFileFlags(flags);

int openFlags = 0;
bool readMode = flags & FileFlags::FILE_FLAGS_READ;
bool writeMode = flags & FileFlags::FILE_FLAGS_WRITE;
if (readMode && writeMode) {
openFlags = O_RDWR;
} else if (readMode) {
openFlags = O_RDONLY;
} else if (writeMode) {
openFlags = O_WRONLY;
} else {
// LCOV_EXCL_START
throw InternalException("READ, WRITE or both should be specified when opening a file.");
// LCOV_EXCL_STOP
}
if (writeMode) {
KU_ASSERT(flags & FileFlags::FILE_FLAGS_WRITE);
openFlags |= O_CLOEXEC;
if (flags & FileFlags::FILE_FLAGS_FILE_CREATE) {
openFlags |= O_CREAT;
} else if (flags & FileFlags::FILE_FLAGS_FILE_CREATE_NEW) {
openFlags |= O_CREAT | O_TRUNC;
}
if (flags & FileFlags::FILE_FLAGS_APPEND) {
openFlags |= O_APPEND;
}
}

#if defined(_WIN32)
auto dwDesiredAccess = 0ul;
auto dwCreationDisposition = (flags & O_CREAT) ? OPEN_ALWAYS : OPEN_EXISTING;
auto dwCreationDisposition = (openFlags & O_CREAT) ? OPEN_ALWAYS : OPEN_EXISTING;
auto dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
if (flags & (O_CREAT | O_WRONLY | O_RDWR)) {
if (openFlags & (O_CREAT | O_WRONLY | O_RDWR)) {
dwDesiredAccess |= GENERIC_WRITE;
}
// O_RDONLY is 0 in practice, so flags & (O_RDONLY | O_RDWR) doesn't work.
if (!(flags & O_WRONLY)) {
// O_RDONLY is 0 in practice, so openFlags & (O_RDONLY | O_RDWR) doesn't work.
if (!(openFlags & O_WRONLY)) {
dwDesiredAccess |= GENERIC_READ;
}

Expand All @@ -78,7 +121,7 @@ std::unique_ptr<FileInfo> LocalFileSystem::openFile(
}
return std::make_unique<LocalFileInfo>(fullPath, handle, this);
#else
int fd = open(fullPath.c_str(), flags, 0644);
int fd = open(fullPath.c_str(), openFlags, 0644);
if (fd == -1) {
throw Exception(stringFormat("Cannot open file {}: {}", fullPath, posixErrMessage()));
}
Expand Down
11 changes: 11 additions & 0 deletions src/include/common/file_system/file_system.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ namespace common {

enum class FileLockType : uint8_t { NO_LOCK = 0, READ_LOCK = 1, WRITE_LOCK = 2 };

struct FileFlags {
static constexpr uint8_t FILE_FLAGS_READ = 1 << 0;
static constexpr uint8_t FILE_FLAGS_WRITE = 1 << 1;
// Create file if not exists, can only be used together with WRITE
static constexpr uint8_t FILE_FLAGS_FILE_CREATE = 1 << 3;
// Always create a new file. If a file exists, the file is truncated. Cannot be used together
// with CREATE.
static constexpr uint8_t FILE_FLAGS_FILE_CREATE_NEW = 1 << 4;
static constexpr uint8_t FILE_FLAGS_APPEND = 1 << 5;
};

class KUZU_API FileSystem {
friend struct FileInfo;

Expand Down
4 changes: 2 additions & 2 deletions src/main/database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ SystemConfig::SystemConfig(
}

static void getLockFileFlagsAndType(bool readOnly, bool createNew, int& flags, FileLockType& lock) {
flags = readOnly ? O_RDONLY : O_RDWR;
flags = readOnly ? FileFlags::FILE_FLAGS_READ : FileFlags::FILE_FLAGS_WRITE;
if (createNew && !readOnly) {
flags |= O_CREAT;
flags |= FileFlags::FILE_FLAGS_FILE_CREATE_NEW;
}
lock = readOnly ? FileLockType::READ_LOCK : FileLockType::WRITE_LOCK;
}
Expand Down
3 changes: 2 additions & 1 deletion src/processor/operator/install_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ void InstallExtension::saveExtensionToLocalFile(
if (!vfs->fileOrPathExists(extensionDir)) {
vfs->createDir(extensionDir);
}
auto fileInfo = vfs->openFile(extensionPath, O_WRONLY | O_CREAT);
auto fileInfo = vfs->openFile(
extensionPath, FileFlags::FILE_FLAGS_FILE_CREATE_NEW | FileFlags::FILE_FLAGS_WRITE);
fileInfo->writeFile(reinterpret_cast<const uint8_t*>(extensionData.c_str()),
extensionData.size(), 0 /* offset */);
}
Expand Down
4 changes: 2 additions & 2 deletions src/processor/operator/persistent/copy_to_csv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,8 @@ void CopyToCSVLocalState::writeRows(CopyToCSVInfo* copyToCsvInfo) {
}

void CopyToCSVSharedState::init(CopyToInfo* info, main::ClientContext* context) {
fileInfo =
context->getVFSUnsafe()->openFile(info->fileName, O_WRONLY | O_CREAT | O_TRUNC, context);
fileInfo = context->getVFSUnsafe()->openFile(info->fileName,
FileFlags::FILE_FLAGS_FILE_CREATE_NEW | FileFlags::FILE_FLAGS_WRITE, context);
writeHeader(info);
}

Expand Down
3 changes: 2 additions & 1 deletion src/processor/operator/persistent/export_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ using std::stringstream;

static void writeStringStreamToFile(
VirtualFileSystem* vfs, std::string ss_string, const std::string& path) {
auto fileInfo = vfs->openFile(path, O_WRONLY | O_CREAT);
auto fileInfo =
vfs->openFile(path, FileFlags::FILE_FLAGS_FILE_CREATE_NEW | FileFlags::FILE_FLAGS_WRITE);
fileInfo->writeFile(
reinterpret_cast<const uint8_t*>(ss_string.c_str()), ss_string.size(), 0 /* offset */);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ BaseCSVReader::BaseCSVReader(const std::string& filePath, common::CSVOption opti
: option{std::move(option)}, numColumns(numColumns), buffer(nullptr), bufferSize(0),
position(0), osFileOffset(0), rowEmpty(false) {
fileInfo = context->getVFSUnsafe()->openFile(filePath,
O_RDONLY
FileFlags::FILE_FLAGS_READ
#ifdef _WIN32
| _O_BINARY
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace kuzu {
namespace processor {

NpyReader::NpyReader(const std::string& filePath) : filePath{filePath} {
fd = open(filePath.c_str(), O_RDONLY);
fd = open(filePath.c_str(), FileFlags::FILE_FLAGS_READ);
if (fd == -1) {
throw CopyException("Failed to open NPY file.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ void ParquetReader::initializeScan(
state.groupIdxList = std::move(groups_to_read);
if (!state.fileInfo || state.fileInfo->path != filePath) {
state.prefetchMode = false;
state.fileInfo = vfs->openFile(filePath, O_RDONLY, context);
state.fileInfo = vfs->openFile(filePath, FileFlags::FILE_FLAGS_READ, context);
}

state.thriftFileProto = createThriftProtocol(state.fileInfo.get(), state.prefetchMode);
Expand Down Expand Up @@ -166,7 +166,8 @@ void ParquetReader::scan(processor::ParquetReaderScanState& state, DataChunk& re
}

void ParquetReader::initMetadata() {
auto fileInfo = context->getVFSUnsafe()->openFile(filePath, O_RDONLY, context);
auto fileInfo =
context->getVFSUnsafe()->openFile(filePath, FileFlags::FILE_FLAGS_READ, context);
auto proto = createThriftProtocol(fileInfo.get(), false);
auto& transport = reinterpret_cast<ThriftFileTransport&>(*proto->getTransport());
auto fileSize = transport.GetSize();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ ParquetWriter::ParquetWriter(std::string fileName,
kuzu_parquet::format::CompressionCodec::type codec, main::ClientContext* context)
: fileName{std::move(fileName)}, types{std::move(types)}, columnNames{std::move(columnNames)},
codec{codec}, fileOffset{0}, mm{context->getMemoryManager()} {
fileInfo =
context->getVFSUnsafe()->openFile(this->fileName, O_WRONLY | O_CREAT | O_TRUNC, context);
fileInfo = context->getVFSUnsafe()->openFile(this->fileName,
FileFlags::FILE_FLAGS_WRITE | FileFlags::FILE_FLAGS_FILE_CREATE_NEW, context);
// Parquet files start with the string "PAR1".
fileInfo->writeFile(reinterpret_cast<const uint8_t*>(ParquetConstants::PARQUET_MAGIC_WORDS),
strlen(ParquetConstants::PARQUET_MAGIC_WORDS), fileOffset);
Expand Down
5 changes: 3 additions & 2 deletions src/storage/file_handle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ FileHandle::FileHandle(const std::string& path, uint8_t flags, VirtualFileSystem
void FileHandle::constructExistingFileHandle(const std::string& path, VirtualFileSystem* vfs) {
int openFlags;
if (isReadOnlyFile()) {
openFlags = O_RDONLY;
openFlags = FileFlags::FILE_FLAGS_READ;
} else {
openFlags = O_RDWR | ((createFileIfNotExists()) ? O_CREAT : 0x00000000);
openFlags = FileFlags::FILE_FLAGS_WRITE | FileFlags::FILE_FLAGS_READ |
((createFileIfNotExists()) ? FileFlags::FILE_FLAGS_FILE_CREATE : 0x00000000);
}
fileInfo = vfs->openFile(path, openFlags);
auto fileLength = fileInfo->getFileSize();
Expand Down
2 changes: 1 addition & 1 deletion src/storage/index/hash_index_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ PrimaryKeyIndexBuilder::PrimaryKeyIndexBuilder(
if constexpr (std::is_same_v<T, ku_string_t>) {
auto overflowFileInfo = std::shared_ptr(vfs->openFile(
StorageUtils::getOverflowFileName(fileHandle->getFileInfo()->path),
O_CREAT | O_WRONLY));
FileFlags::FILE_FLAGS_FILE_CREATE_NEW | FileFlags::FILE_FLAGS_WRITE));
for (auto i = 0u; i < NUM_HASH_INDEXES; i++) {
auto overflowFile =
std::make_unique<InMemFile>(overflowFileInfo, overflowPageCounter);
Expand Down
8 changes: 4 additions & 4 deletions src/storage/stats/table_statistics_collection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ void TablesStatistics::readFromFile() {

void TablesStatistics::readFromFile(FileVersionType fileVersionType) {
auto filePath = getTableStatisticsFilePath(wal->getDirectory(), fileVersionType);
auto deser =
Deserializer(std::make_unique<BufferedFileReader>(vfs->openFile(filePath, O_RDONLY)));
auto deser = Deserializer(
std::make_unique<BufferedFileReader>(vfs->openFile(filePath, FileFlags::FILE_FLAGS_READ)));
deser.deserializeUnorderedMap(readOnlyVersion->tableStatisticPerTable);
}

void TablesStatistics::saveToFile(const std::string& directory, FileVersionType fileVersionType,
transaction::TransactionType transactionType) {
auto filePath = getTableStatisticsFilePath(directory, fileVersionType);
auto ser = Serializer(
std::make_unique<BufferedFileWriter>(vfs->openFile(filePath, O_WRONLY | O_CREAT)));
auto ser = Serializer(std::make_unique<BufferedFileWriter>(vfs->openFile(
filePath, FileFlags::FILE_FLAGS_WRITE | FileFlags::FILE_FLAGS_FILE_CREATE_NEW)));
auto& tablesStatisticsContent = (transactionType == transaction::TransactionType::READ_ONLY ||
readWriteVersion == nullptr) ?
readOnlyVersion :
Expand Down
2 changes: 1 addition & 1 deletion src/storage/storage_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ std::unique_ptr<FileInfo> StorageUtils::getFileInfoForReadWrite(
throw RuntimeException("Unsupported dbFileID in StorageUtils::getFileInfoForReadWrite.");
}
}
return vfs->openFile(fName, O_RDWR);
return vfs->openFile(fName, FileFlags::FILE_FLAGS_READ | FileFlags::FILE_FLAGS_WRITE);
}

uint32_t StorageUtils::getDataTypeSize(PhysicalTypeID type) {
Expand Down
3 changes: 2 additions & 1 deletion test/storage/node_insertion_deletion_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ TEST_F(NodeInsertionDeletionTests, TruncatedWalTest) {
// Close database
database.reset();
{
auto walFileInfo = fs.openFile(walPath, O_RDWR);
auto walFileInfo =
fs.openFile(walPath, FileFlags::FILE_FLAGS_READ | FileFlags::FILE_FLAGS_WRITE);
ASSERT_GT(walFileInfo->getFileSize(), BufferPoolConstants::PAGE_4KB_SIZE)
<< "Test needs a wal file with more than one page";
walFileInfo->truncate(BufferPoolConstants::PAGE_4KB_SIZE);
Expand Down

0 comments on commit b22d112

Please sign in to comment.