Compare commits

...

3 Commits

Author SHA1 Message Date
889761f538 rename fs atomic impl and add simple testcase
pre refactor
2025-04-30 16:10:56 +02:00
738e1a2071 refactor zstd cmake and prefer system lib 2025-04-06 20:50:16 +02:00
2d5478c19e fix last mentions of contact3 2025-03-12 22:21:11 +01:00
9 changed files with 138 additions and 41 deletions

View File

@ -28,29 +28,7 @@ if (NOT TARGET nlohmann_json::nlohmann_json)
FetchContent_MakeAvailable(json)
endif()
if (NOT TARGET zstd::zstd)
# TODO: try find_package() first
# TODO: try pkg-config next (will work on most distros)
set(ZSTD_BUILD_STATIC ON)
set(ZSTD_BUILD_SHARED OFF)
set(ZSTD_BUILD_PROGRAMS OFF)
set(ZSTD_BUILD_CONTRIB OFF)
set(ZSTD_BUILD_TESTS OFF)
FetchContent_Declare(zstd
URL "https://github.com/facebook/zstd/releases/download/v1.5.6/zstd-1.5.6.tar.gz"
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
SOURCE_SUBDIR build/cmake
EXCLUDE_FROM_ALL
)
FetchContent_MakeAvailable(zstd)
add_library(zstd INTERFACE) # somehow zstd fkd this up
target_include_directories(zstd INTERFACE ${zstd_SOURCE_DIR}/lib/)
target_link_libraries(zstd INTERFACE libzstd_static)
#TODO: new zstd also provides zstd::libzstd
add_library(zstd::zstd ALIAS zstd)
endif()
add_subdirectory(./zstd)
#if (NOT TARGET solanaceae_plugin)
#FetchContent_Declare(solanaceae_plugin

32
external/zstd/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,32 @@
cmake_minimum_required(VERSION 3.24 FATAL_ERROR)
include(FetchContent)
if (NOT TARGET zstd::libzstd)
find_package(zstd CONFIG GLOBAL QUIET)
endif()
if (NOT TARGET zstd::libzstd)
# TODO: try find_package() first
# TODO: try pkg-config next (will work on most distros)
set(ZSTD_BUILD_STATIC ON)
set(ZSTD_BUILD_SHARED OFF)
set(ZSTD_BUILD_PROGRAMS OFF)
set(ZSTD_BUILD_CONTRIB OFF)
set(ZSTD_BUILD_TESTS OFF)
FetchContent_Declare(zstd
URL "https://github.com/facebook/zstd/releases/download/v1.5.6/zstd-1.5.6.tar.gz"
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
SOURCE_SUBDIR build/cmake
EXCLUDE_FROM_ALL
)
FetchContent_MakeAvailable(zstd)
add_library(libzstd_tmp INTERFACE) # somehow zstd fkd this up
target_include_directories(libzstd_tmp INTERFACE ${zstd_SOURCE_DIR}/lib/)
target_link_libraries(libzstd_tmp INTERFACE libzstd_static)
#TODO: new zstd also provides zstd::libzstd
add_library(zstd::libzstd ALIAS libzstd_tmp)
endif()

View File

@ -32,7 +32,7 @@ target_include_directories(solanaceae_file2_zstd PUBLIC .)
target_compile_features(solanaceae_file2_zstd PUBLIC cxx_std_17)
target_link_libraries(solanaceae_file2_zstd PUBLIC
solanaceae_file2
zstd::zstd
zstd::libzstd
)
########################################
@ -40,8 +40,8 @@ target_link_libraries(solanaceae_file2_zstd PUBLIC
add_library(solanaceae_object_store_backend_filesystem
./solanaceae/object_store/backends/file2_stack.hpp
./solanaceae/object_store/backends/file2_stack.cpp
./solanaceae/object_store/backends/filesystem_storage.hpp
./solanaceae/object_store/backends/filesystem_storage.cpp
./solanaceae/object_store/backends/filesystem_storage_atomic.hpp
./solanaceae/object_store/backends/filesystem_storage_atomic.cpp
)
target_include_directories(solanaceae_object_store_backend_filesystem PUBLIC .)

View File

@ -1,4 +1,4 @@
#include "./filesystem_storage.hpp"
#include "./filesystem_storage_atomic.hpp"
#include <solanaceae/object_store/meta_components.hpp>
#include <solanaceae/object_store/serializer_json.hpp>
@ -29,17 +29,17 @@ static const char* metaFileTypeSuffix(MetaFileType mft) {
namespace Backends {
FilesystemStorage::FilesystemStorage(
FilesystemStorageAtomic::FilesystemStorageAtomic(
ObjectStore2& os,
std::string_view storage_path,
MetaFileType mft_new
) : _os(os), _storage_path(storage_path), _mft_new(mft_new) {
}
FilesystemStorage::~FilesystemStorage(void) {
FilesystemStorageAtomic::~FilesystemStorageAtomic(void) {
}
ObjectHandle FilesystemStorage::newObject(ByteSpan id, bool throw_construct) {
ObjectHandle FilesystemStorageAtomic::newObject(ByteSpan id, bool throw_construct) {
{ // first check if id is already used (TODO: solve the multi obj/backend problem)
auto exising_oh = _os.getOneObjectByID(id);
if (static_cast<bool>(exising_oh)) {
@ -96,7 +96,7 @@ ObjectHandle FilesystemStorage::newObject(ByteSpan id, bool throw_construct) {
return oh;
}
bool FilesystemStorage::write(Object o, std::function<write_to_storage_fetch_data_cb>& data_cb) {
bool FilesystemStorageAtomic::write(Object o, std::function<write_to_storage_fetch_data_cb>& data_cb) {
auto& reg = _os.registry();
if (!reg.valid(o)) {
@ -303,7 +303,7 @@ bool FilesystemStorage::write(Object o, std::function<write_to_storage_fetch_dat
return true;
}
bool FilesystemStorage::read(Object o, std::function<read_from_storage_put_data_cb>& data_cb) {
bool FilesystemStorageAtomic::read(Object o, std::function<read_from_storage_put_data_cb>& data_cb) {
auto& reg = _os.registry();
if (!reg.valid(o)) {
@ -355,11 +355,11 @@ bool FilesystemStorage::read(Object o, std::function<read_from_storage_put_data_
return true;
}
void FilesystemStorage::scanAsync(void) {
void FilesystemStorageAtomic::scanAsync(void) {
scanPathAsync(_storage_path);
}
size_t FilesystemStorage::scanPath(std::string_view path) {
size_t FilesystemStorageAtomic::scanPath(std::string_view path) {
// TODO: extract so async can work (or/and make iteratable generator)
if (path.empty() || !std::filesystem::is_directory(path)) {
@ -615,7 +615,7 @@ size_t FilesystemStorage::scanPath(std::string_view path) {
return scanned_objs.size();
}
void FilesystemStorage::scanPathAsync(std::string path) {
void FilesystemStorageAtomic::scanPathAsync(std::string path) {
// add path to queue
// HACK: if path is known/any fragment is in the path, this operation blocks (non async)
scanPath(path); // TODO: make async and post result

View File

@ -9,15 +9,15 @@ namespace Backends {
// TODO: rename to atomic filesystem store?
// provides meta and atomic read/write on your filesystem
struct FilesystemStorage : public StorageBackendIMeta, public StorageBackendIAtomic {
struct FilesystemStorageAtomic : public StorageBackendIMeta, public StorageBackendIAtomic {
ObjectStore2& _os;
FilesystemStorage(
FilesystemStorageAtomic(
ObjectStore2& os,
std::string_view storage_path = "test_obj_store",
MetaFileType mft_new = MetaFileType::BINARY_MSGPACK
);
~FilesystemStorage(void);
~FilesystemStorageAtomic(void);
// TODO: fix the path for this specific fs?
// for now we assume a single storage path per backend (there can be multiple per type)

View File

@ -9,7 +9,7 @@
#include <vector>
#include <string>
// fwd enum (obj cant depend on Contact3
// fwd enum (obj cant depend on Contact4
enum class Contact4 : uint32_t;
namespace ObjectStore::Components {
@ -137,7 +137,7 @@ namespace ObjectStore::Components {
#if 0
struct TransferStatsSeparated {
entt::dense_map<Contact3, TransferStats> stats;
entt::dense_map<Contact4, TransferStats> stats;
};
#endif

View File

@ -49,7 +49,7 @@ struct StorageBackendIFile2 {
FILE2_READ = 1u << 0,
FILE2_WRITE = 1u << 1,
// only relevant for backend implementing this (ideally all)
// only relevant for backends implementing this (ideally all)
FILE2_NO_COMP = 1u << 2,// dont do any de-/compression
FILE2_NO_ENC = 1u << 3, // dont do any de-/encryption

View File

@ -12,3 +12,14 @@ target_link_libraries(solanaceae_file2_zstd_test PUBLIC
add_test(NAME solanaceae_file2_zstd_test COMMAND solanaceae_file2_zstd_test)
########################################
add_executable(solanaceae_backend_fs_atomic_test
./test_backend_fs_atomic.cpp
)
target_link_libraries(solanaceae_backend_fs_atomic_test PUBLIC
solanaceae_object_store_backend_filesystem
)
add_test(NAME solanaceae_backend_fs_atomic_test COMMAND solanaceae_backend_fs_atomic_test)

View File

@ -0,0 +1,76 @@
#include <solanaceae/object_store/object_store.hpp>
#include <solanaceae/object_store/backends/filesystem_storage_atomic.hpp>
#include <solanaceae/object_store/meta_components.hpp>
#include <solanaceae/object_store/meta_components_file.hpp>
#include <filesystem>
#include <cassert>
#include <vector>
int main(void) {
const auto temp_dir_str = (std::filesystem::temp_directory_path() / "test_obj_store_tests").u8string();
assert(!std::filesystem::exists(temp_dir_str));
// test1, create store with 2 objects
{
ObjectStore2 os;
Backends::FilesystemStorageAtomic fsa{os, temp_dir_str};
// empty, does nothing
fsa.scanAsync();
assert(!std::filesystem::exists(temp_dir_str));
{ // o1
// id1
std::vector<uint8_t> id{0x00, 0x13, 0x37, 0x01};
auto o = fsa.newObject(ByteSpan{id});
std::vector<uint8_t> data{0x01, 0x01, 0x11, 0xf1, 0xae, 0x0b, 0x33};
static_cast<StorageBackendIAtomic&>(fsa).write(o, ByteSpan{data});
}
{ // o2
// id2
std::vector<uint8_t> id{0x00, 0x13, 0x37, 0x02};
auto o = fsa.newObject(ByteSpan{id});
std::vector<uint8_t> data{0x11, 0x11, 0x11, 0xff, 0xff, 0xee, 0xee};
static_cast<StorageBackendIAtomic&>(fsa).write(o, ByteSpan{data});
}
}
assert(std::filesystem::exists(temp_dir_str));
// test2, load store created in test1
{
ObjectStore2 os;
Backends::FilesystemStorageAtomic fsa{os, temp_dir_str};
fsa.scanAsync();
assert(os.registry().storage<Object>().size() == 2);
{ // o1
std::vector<uint8_t> id{0x00, 0x13, 0x37, 0x01};
auto o = os.getOneObjectByID(ByteSpan{id});
assert(static_cast<bool>(o));
std::vector<uint8_t> orig_data{0x01, 0x01, 0x11, 0xf1, 0xae, 0x0b, 0x33};
// TODO: read and test content
//static_cast<StorageBackendIAtomic&>(fsa).write(o, ByteSpan{data});
}
{ // o2
std::vector<uint8_t> id{0x00, 0x13, 0x37, 0x02};
auto o = os.getOneObjectByID(ByteSpan{id});
assert(static_cast<bool>(o));
}
}
std::filesystem::remove_all(temp_dir_str);
return 0;
}