rename fs atomic impl and add simple testcase

pre refactor
This commit is contained in:
Green Sky 2025-04-30 16:10:56 +02:00
parent 738e1a2071
commit 889761f538
No known key found for this signature in database
GPG Key ID: DBE05085D874AB4A
6 changed files with 102 additions and 15 deletions

View File

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

View File

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

View File

@ -49,7 +49,7 @@ struct StorageBackendIFile2 {
FILE2_READ = 1u << 0, FILE2_READ = 1u << 0,
FILE2_WRITE = 1u << 1, 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_COMP = 1u << 2,// dont do any de-/compression
FILE2_NO_ENC = 1u << 3, // dont do any de-/encryption 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_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;
}