v2.0.2-rc (#27)
Some checks reported errors
BlockStorage/repertory/pipeline/head Something is wrong with the build of this commit
Some checks reported errors
BlockStorage/repertory/pipeline/head Something is wrong with the build of this commit
## v2.0.2-rc ### BREAKING CHANGES * Refactored `config.json` - will need to verify configuration settings prior to mounting ### Issues * \#12 \[Unit Test\] Complete all providers unit tests * \#14 \[Unit Test\] SQLite mini-ORM unit tests and cleanup * \#16 Add support for bucket name in Sia provider * \#17 Update to common c++ build system * A single 64-bit Linux Jenkins server is used to build all Linux and Windows versions * All dependency sources are now included * MSVC is no longer supported * MSYS2 is required for building Windows binaries on Windows * OS X support is temporarily disabled * \#19 \[bug\] Rename file is broken for files that are existing * \#23 \[bug\] Incorrect file size displayed while upload is pending * \#24 RocksDB implementations should be transactional * \#25 Writes should block when maximum cache size is reached * \#26 Complete ring buffer and direct download support ### Changes from v2.0.1-rc * Ability to choose between RocksDB and SQLite databases * Added direct reads and implemented download fallback * Corrected file times on S3 and Sia providers * Corrected handling of `chown()` and `chmod()` * Fixed erroneous download of chunks after resize Reviewed-on: #27
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef REPERTORY_INCLUDE_FILE_MANAGER_CACHE_SIZE_MGR_HPP_
|
||||
#define REPERTORY_INCLUDE_FILE_MANAGER_CACHE_SIZE_MGR_HPP_
|
||||
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
|
||||
class cache_size_mgr final {
|
||||
public:
|
||||
cache_size_mgr(const cache_size_mgr &) = delete;
|
||||
cache_size_mgr(cache_size_mgr &&) = delete;
|
||||
auto operator=(const cache_size_mgr &) -> cache_size_mgr & = delete;
|
||||
auto operator=(cache_size_mgr &&) -> cache_size_mgr & = delete;
|
||||
|
||||
protected:
|
||||
cache_size_mgr() = default;
|
||||
|
||||
~cache_size_mgr() { stop(); }
|
||||
|
||||
private:
|
||||
static cache_size_mgr instance_;
|
||||
|
||||
private:
|
||||
app_config *cfg_{nullptr};
|
||||
std::uint64_t cache_size_{0U};
|
||||
mutable std::mutex mtx_;
|
||||
std::condition_variable notify_;
|
||||
stop_type stop_requested_{false};
|
||||
|
||||
public:
|
||||
[[nodiscard]] auto expand(std::uint64_t size) -> api_error;
|
||||
|
||||
void initialize(app_config *cfg);
|
||||
|
||||
[[nodiscard]] static auto instance() -> cache_size_mgr & { return instance_; }
|
||||
|
||||
[[nodiscard]] auto shrink(std::uint64_t size) -> api_error;
|
||||
|
||||
[[nodiscard]] auto size() const -> std::uint64_t;
|
||||
|
||||
void stop();
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_INCLUDE_FILE_MANAGER_CACHE_SIZE_MGR_HPP_
|
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef REPERTORY_INCLUDE_FILE_MANAGER_DIRECT_OPEN_FILE_HPP_
|
||||
#define REPERTORY_INCLUDE_FILE_MANAGER_DIRECT_OPEN_FILE_HPP_
|
||||
|
||||
#include "file_manager/ring_buffer_base.hpp"
|
||||
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_provider;
|
||||
class i_upload_manager;
|
||||
|
||||
class direct_open_file final : public ring_buffer_base {
|
||||
public:
|
||||
direct_open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout,
|
||||
filesystem_item fsi, i_provider &provider);
|
||||
|
||||
~direct_open_file() override;
|
||||
|
||||
public:
|
||||
direct_open_file() = delete;
|
||||
direct_open_file(const direct_open_file &) noexcept = delete;
|
||||
direct_open_file(direct_open_file &&) noexcept = delete;
|
||||
auto operator=(direct_open_file &&) noexcept -> direct_open_file & = delete;
|
||||
auto
|
||||
operator=(const direct_open_file &) noexcept -> direct_open_file & = delete;
|
||||
|
||||
private:
|
||||
std::array<data_buffer, min_ring_size> ring_data_;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] auto on_check_start() -> bool override;
|
||||
|
||||
[[nodiscard]] auto
|
||||
on_chunk_downloaded(std::size_t /* chunk */,
|
||||
const data_buffer & /* buffer */) -> api_error override {
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto
|
||||
on_read_chunk(std::size_t chunk, std::size_t read_size,
|
||||
std::uint64_t read_offset, data_buffer &data,
|
||||
std::size_t &bytes_read) -> api_error override;
|
||||
|
||||
[[nodiscard]] auto use_buffer(std::size_t chunk,
|
||||
std::function<api_error(data_buffer &)> func)
|
||||
-> api_error override;
|
||||
|
||||
public:
|
||||
[[nodiscard]] auto native_operation(native_operation_callback /* callback */)
|
||||
-> api_error override {
|
||||
return api_error::not_supported;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto native_operation(std::uint64_t /* new_file_size */,
|
||||
native_operation_callback /* callback */)
|
||||
-> api_error override {
|
||||
return api_error::not_supported;
|
||||
}
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_INCLUDE_FILE_MANAGER_DIRECT_OPEN_FILE_HPP_
|
86
repertory/librepertory/include/file_manager/events.hpp
Normal file
86
repertory/librepertory/include/file_manager/events.hpp
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef REPERTORY_INCLUDE_FILE_MANAGER_EVENTS_HPP_
|
||||
#define REPERTORY_INCLUDE_FILE_MANAGER_EVENTS_HPP_
|
||||
|
||||
#include "events/events.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
// clang-format off
|
||||
E_SIMPLE2(download_begin, info, true,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, dest_path, dest, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(download_end, info, true,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, dest_path, dest, E_FROM_STRING,
|
||||
api_error, result, result, E_FROM_API_FILE_ERROR
|
||||
);
|
||||
|
||||
E_SIMPLE3(download_progress, info, true,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, dest_path, dest, E_FROM_STRING,
|
||||
double, progress, prog, E_FROM_DOUBLE_PRECISE
|
||||
);
|
||||
|
||||
E_SIMPLE2(download_restored, info, true,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, dest_path, dest, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(download_restore_failed, error, true,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, dest_path, dest, E_FROM_STRING,
|
||||
std::string, error, err, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(download_resume_add_failed, error, true,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, dest_path, dest, E_FROM_STRING,
|
||||
std::string, error, err, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(download_resume_added, debug, true,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, dest_path, dest, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(download_resume_removed, debug, true,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, dest_path, dest, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(item_timeout, trace, true,
|
||||
std::string, api_path, ap, E_FROM_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(download_type_selected, debug, true,
|
||||
std::string, api_path, ap, E_FROM_STRING,
|
||||
std::string, source, src, E_FROM_STRING,
|
||||
download_type, download_type, type, E_FROM_DOWNLOAD_TYPE
|
||||
);
|
||||
// clang-format on
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_INCLUDE_FILE_MANAGER_EVENTS_HPP_
|
175
repertory/librepertory/include/file_manager/file_manager.hpp
Normal file
175
repertory/librepertory/include/file_manager/file_manager.hpp
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef REPERTORY_INCLUDE_FILE_MANAGER_FILE_MANAGER_HPP_
|
||||
#define REPERTORY_INCLUDE_FILE_MANAGER_FILE_MANAGER_HPP_
|
||||
|
||||
#include "db/i_file_mgr_db.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
#include "events/events.hpp"
|
||||
#include "file_manager/i_file_manager.hpp"
|
||||
#include "file_manager/i_open_file.hpp"
|
||||
#include "file_manager/i_upload_manager.hpp"
|
||||
#include "file_manager/upload.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "utils/file.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
class i_provider;
|
||||
|
||||
class file_manager final : public i_file_manager, public i_upload_manager {
|
||||
E_CONSUMER();
|
||||
|
||||
public:
|
||||
file_manager(app_config &config, i_provider &provider);
|
||||
|
||||
~file_manager() override;
|
||||
|
||||
public:
|
||||
file_manager() = delete;
|
||||
file_manager(const file_manager &) noexcept = delete;
|
||||
file_manager(file_manager &&) noexcept = delete;
|
||||
auto operator=(file_manager &&) noexcept -> file_manager & = delete;
|
||||
auto operator=(const file_manager &) noexcept -> file_manager & = delete;
|
||||
|
||||
private:
|
||||
app_config &config_;
|
||||
i_provider &provider_;
|
||||
|
||||
private:
|
||||
std::unique_ptr<i_file_mgr_db> mgr_db_;
|
||||
std::atomic<std::uint64_t> next_handle_{0U};
|
||||
mutable std::recursive_mutex open_file_mtx_;
|
||||
std::unordered_map<std::string, std::shared_ptr<i_closeable_open_file>>
|
||||
open_file_lookup_;
|
||||
stop_type stop_requested_{false};
|
||||
std::unordered_map<std::string, std::unique_ptr<upload>> upload_lookup_;
|
||||
mutable std::mutex upload_mtx_;
|
||||
std::condition_variable upload_notify_;
|
||||
std::unique_ptr<std::thread> upload_thread_;
|
||||
|
||||
private:
|
||||
[[nodiscard]] auto close_all(const std::string &api_path) -> bool;
|
||||
|
||||
void close_timed_out_files();
|
||||
|
||||
auto get_open_file_by_handle(std::uint64_t handle) const
|
||||
-> std::shared_ptr<i_closeable_open_file>;
|
||||
|
||||
auto get_open_file_count(const std::string &api_path) const -> std::size_t;
|
||||
|
||||
auto open(const std::string &api_path, bool directory,
|
||||
const open_file_data &ofd, std::uint64_t &handle,
|
||||
std::shared_ptr<i_open_file> &file,
|
||||
std::shared_ptr<i_closeable_open_file> closeable_file) -> api_error;
|
||||
|
||||
void queue_upload(const std::string &api_path, const std::string &source_path,
|
||||
bool no_lock);
|
||||
|
||||
void remove_resume(const std::string &api_path,
|
||||
const std::string &source_path, bool no_lock);
|
||||
|
||||
void remove_upload(const std::string &api_path, bool no_lock);
|
||||
|
||||
void swap_renamed_items(std::string from_api_path, std::string to_api_path,
|
||||
bool directory);
|
||||
|
||||
void upload_completed(const file_upload_completed &evt);
|
||||
|
||||
void upload_handler();
|
||||
|
||||
public:
|
||||
[[nodiscard]] auto get_next_handle() -> std::uint64_t;
|
||||
|
||||
auto handle_file_rename(const std::string &from_api_path,
|
||||
const std::string &to_api_path) -> api_error;
|
||||
|
||||
void queue_upload(const i_open_file &file) override;
|
||||
|
||||
void remove_resume(const std::string &api_path,
|
||||
const std::string &source_path) override;
|
||||
|
||||
static auto remove_source_and_shrink_cache(const std::string &api_path,
|
||||
const std::string &source_path,
|
||||
std::uint64_t file_size,
|
||||
bool allocated) -> bool;
|
||||
|
||||
void remove_upload(const std::string &api_path) override;
|
||||
|
||||
void store_resume(const i_open_file &file) override;
|
||||
|
||||
public:
|
||||
void close(std::uint64_t handle);
|
||||
|
||||
[[nodiscard]] auto create(const std::string &api_path, api_meta_map &meta,
|
||||
open_file_data ofd, std::uint64_t &handle,
|
||||
std::shared_ptr<i_open_file> &file) -> api_error;
|
||||
|
||||
[[nodiscard]] auto evict_file(const std::string &api_path) -> bool override;
|
||||
|
||||
[[nodiscard]] auto get_directory_items(const std::string &api_path) const
|
||||
-> directory_item_list override;
|
||||
|
||||
[[nodiscard]] auto get_open_file(std::uint64_t handle, bool write_supported,
|
||||
std::shared_ptr<i_open_file> &file) -> bool;
|
||||
|
||||
[[nodiscard]] auto get_open_file_count() const -> std::size_t;
|
||||
|
||||
[[nodiscard]] auto get_open_files() const
|
||||
-> std::unordered_map<std::string, std::size_t> override;
|
||||
|
||||
[[nodiscard]] auto get_open_handle_count() const -> std::size_t;
|
||||
|
||||
[[nodiscard]] auto get_stored_downloads() const
|
||||
-> std::vector<i_file_mgr_db::resume_entry>;
|
||||
|
||||
[[nodiscard]] auto has_no_open_file_handles() const -> bool override;
|
||||
|
||||
[[nodiscard]] auto is_processing(const std::string &api_path) const
|
||||
-> bool override;
|
||||
|
||||
#if defined(PROJECT_TESTING)
|
||||
[[nodiscard]] auto open(std::shared_ptr<i_closeable_open_file> of,
|
||||
const open_file_data &ofd, std::uint64_t &handle,
|
||||
std::shared_ptr<i_open_file> &file) -> api_error;
|
||||
#endif // defined(PROJECT_TESTING)
|
||||
[[nodiscard]] auto open(const std::string &api_path, bool directory,
|
||||
const open_file_data &ofd, std::uint64_t &handle,
|
||||
std::shared_ptr<i_open_file> &file) -> api_error;
|
||||
|
||||
[[nodiscard]] auto remove_file(const std::string &api_path) -> api_error;
|
||||
|
||||
[[nodiscard]] auto rename_directory(const std::string &from_api_path,
|
||||
const std::string &to_api_path)
|
||||
-> api_error;
|
||||
|
||||
[[nodiscard]] auto rename_file(const std::string &from_api_path,
|
||||
const std::string &to_api_path, bool overwrite)
|
||||
-> api_error;
|
||||
|
||||
void start();
|
||||
|
||||
void stop();
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_INCLUDE_FILE_MANAGER_FILE_MANAGER_HPP_
|
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef REPERTORY_INCLUDE_FILE_MANAGER_I_FILE_MANAGER_HPP_
|
||||
#define REPERTORY_INCLUDE_FILE_MANAGER_I_FILE_MANAGER_HPP_
|
||||
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_provider;
|
||||
|
||||
class i_file_manager {
|
||||
INTERFACE_SETUP(i_file_manager);
|
||||
|
||||
public:
|
||||
[[nodiscard]] virtual auto evict_file(const std::string &api_path)
|
||||
-> bool = 0;
|
||||
|
||||
[[nodiscard]] virtual auto
|
||||
get_directory_items(const std::string &api_path) const
|
||||
-> directory_item_list = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_open_files() const
|
||||
-> std::unordered_map<std::string, std::size_t> = 0;
|
||||
|
||||
[[nodiscard]] virtual auto has_no_open_file_handles() const -> bool = 0;
|
||||
|
||||
[[nodiscard]] virtual auto is_processing(const std::string &api_path) const
|
||||
-> bool = 0;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_INCLUDE_FILE_MANAGER_I_FILE_MANAGER_HPP_
|
117
repertory/librepertory/include/file_manager/i_open_file.hpp
Normal file
117
repertory/librepertory/include/file_manager/i_open_file.hpp
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef REPERTORY_INCLUDE_FILE_MANAGER_I_OPEN_FILE_HPP_
|
||||
#define REPERTORY_INCLUDE_FILE_MANAGER_I_OPEN_FILE_HPP_
|
||||
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_open_file {
|
||||
INTERFACE_SETUP(i_open_file);
|
||||
|
||||
public:
|
||||
using native_operation_callback = std::function<api_error(native_handle)>;
|
||||
|
||||
public:
|
||||
[[nodiscard]] virtual auto get_api_path() const -> std::string = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_chunk_size() const -> std::size_t = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_file_size() const -> std::uint64_t = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_filesystem_item() const -> filesystem_item = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_open_data()
|
||||
-> std::map<std::uint64_t, open_file_data> & = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_open_data() const
|
||||
-> const std::map<std::uint64_t, open_file_data> & = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_open_data(std::uint64_t handle)
|
||||
-> open_file_data & = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_open_data(std::uint64_t handle) const
|
||||
-> const open_file_data & = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_open_file_count() const -> std::size_t = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_read_state() const
|
||||
-> boost::dynamic_bitset<> = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_read_state(std::size_t chunk) const
|
||||
-> bool = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_source_path() const -> std::string = 0;
|
||||
|
||||
[[nodiscard]] virtual auto is_complete() const -> bool = 0;
|
||||
|
||||
[[nodiscard]] virtual auto is_directory() const -> bool = 0;
|
||||
|
||||
[[nodiscard]] virtual auto is_write_supported() const -> bool = 0;
|
||||
|
||||
[[nodiscard]] virtual auto has_handle(std::uint64_t handle) const -> bool = 0;
|
||||
|
||||
[[nodiscard]] virtual auto
|
||||
native_operation(native_operation_callback callback) -> api_error = 0;
|
||||
|
||||
[[nodiscard]] virtual auto
|
||||
native_operation(std::uint64_t new_file_size,
|
||||
native_operation_callback callback) -> api_error = 0;
|
||||
|
||||
[[nodiscard]] virtual auto read(std::size_t read_size,
|
||||
std::uint64_t read_offset, data_buffer &data)
|
||||
-> api_error = 0;
|
||||
|
||||
[[nodiscard]] virtual auto resize(std::uint64_t new_file_size)
|
||||
-> api_error = 0;
|
||||
|
||||
virtual void set_api_path(const std::string &api_path) = 0;
|
||||
|
||||
[[nodiscard]] virtual auto write(std::uint64_t write_offset,
|
||||
const data_buffer &data,
|
||||
std::size_t &bytes_written) -> api_error = 0;
|
||||
};
|
||||
|
||||
class i_closeable_open_file : public i_open_file {
|
||||
INTERFACE_SETUP(i_closeable_open_file);
|
||||
|
||||
public:
|
||||
virtual void add(std::uint64_t handle, open_file_data ofd) = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_allocated() const -> bool = 0;
|
||||
|
||||
[[nodiscard]] virtual auto can_close() const -> bool = 0;
|
||||
|
||||
virtual auto close() -> bool = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_handles() const
|
||||
-> std::vector<std::uint64_t> = 0;
|
||||
|
||||
[[nodiscard]] virtual auto is_modified() const -> bool = 0;
|
||||
|
||||
virtual void remove(std::uint64_t handle) = 0;
|
||||
|
||||
virtual void remove_all() = 0;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_INCLUDE_FILE_MANAGER_I_OPEN_FILE_HPP_
|
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef REPERTORY_INCLUDE_FILE_MANAGER_I_UPLOAD_MANAGER_HPP_
|
||||
#define REPERTORY_INCLUDE_FILE_MANAGER_I_UPLOAD_MANAGER_HPP_
|
||||
|
||||
namespace repertory {
|
||||
class i_open_file;
|
||||
|
||||
class i_upload_manager {
|
||||
INTERFACE_SETUP(i_upload_manager);
|
||||
|
||||
public:
|
||||
virtual void queue_upload(const i_open_file &file) = 0;
|
||||
|
||||
virtual void remove_resume(const std::string &api_path,
|
||||
const std::string &source_path) = 0;
|
||||
|
||||
virtual void remove_upload(const std::string &api_path) = 0;
|
||||
|
||||
virtual void store_resume(const i_open_file &file) = 0;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_INCLUDE_FILE_MANAGER_I_UPLOAD_MANAGER_HPP_
|
135
repertory/librepertory/include/file_manager/open_file.hpp
Normal file
135
repertory/librepertory/include/file_manager/open_file.hpp
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef REPERTORY_INCLUDE_FILE_MANAGER_OPEN_FILE_HPP_
|
||||
#define REPERTORY_INCLUDE_FILE_MANAGER_OPEN_FILE_HPP_
|
||||
|
||||
#include "file_manager/open_file_base.hpp"
|
||||
|
||||
#include "types/repertory.hpp"
|
||||
#include "utils/types/file/i_file.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_provider;
|
||||
class i_upload_manager;
|
||||
|
||||
class open_file final : public open_file_base {
|
||||
public:
|
||||
open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout,
|
||||
filesystem_item fsi, i_provider &provider, i_upload_manager &mgr);
|
||||
|
||||
open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout,
|
||||
filesystem_item fsi,
|
||||
std::map<std::uint64_t, open_file_data> open_data,
|
||||
i_provider &provider, i_upload_manager &mgr);
|
||||
|
||||
open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout,
|
||||
filesystem_item fsi, i_provider &provider,
|
||||
std::optional<boost::dynamic_bitset<>> read_state,
|
||||
i_upload_manager &mgr);
|
||||
|
||||
private:
|
||||
open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout,
|
||||
filesystem_item fsi,
|
||||
std::map<std::uint64_t, open_file_data> open_data,
|
||||
i_provider &provider,
|
||||
std::optional<boost::dynamic_bitset<>> read_state,
|
||||
i_upload_manager &mgr);
|
||||
|
||||
public:
|
||||
open_file() = delete;
|
||||
open_file(const open_file &) noexcept = delete;
|
||||
open_file(open_file &&) noexcept = delete;
|
||||
auto operator=(open_file &&) noexcept -> open_file & = delete;
|
||||
auto operator=(const open_file &) noexcept -> open_file & = delete;
|
||||
|
||||
public:
|
||||
~open_file() override;
|
||||
|
||||
private:
|
||||
i_upload_manager &mgr_;
|
||||
|
||||
private:
|
||||
bool allocated{false};
|
||||
std::unique_ptr<utils::file::i_file> nf_;
|
||||
bool notified_{false};
|
||||
std::size_t read_chunk_{};
|
||||
boost::dynamic_bitset<> read_state_;
|
||||
std::unique_ptr<std::thread> reader_thread_;
|
||||
mutable std::recursive_mutex rw_mtx_;
|
||||
stop_type stop_requested_{false};
|
||||
|
||||
private:
|
||||
[[nodiscard]] auto adjust_cache_size(std::uint64_t file_size,
|
||||
bool shrink) -> api_error;
|
||||
|
||||
[[nodiscard]] auto check_start() -> api_error;
|
||||
|
||||
void download_chunk(std::size_t chunk, bool skip_active, bool should_reset);
|
||||
|
||||
void download_range(std::size_t begin_chunk, std::size_t end_chunk,
|
||||
bool should_reset);
|
||||
|
||||
void set_modified();
|
||||
|
||||
void set_read_state(std::size_t chunk);
|
||||
|
||||
void set_read_state(boost::dynamic_bitset<> read_state);
|
||||
|
||||
void update_reader(std::size_t chunk);
|
||||
|
||||
public:
|
||||
auto close() -> bool override;
|
||||
|
||||
[[nodiscard]] auto get_allocated() const -> bool override;
|
||||
|
||||
[[nodiscard]] auto get_read_state() const -> boost::dynamic_bitset<> override;
|
||||
|
||||
[[nodiscard]] auto get_read_state(std::size_t chunk) const -> bool override;
|
||||
|
||||
[[nodiscard]] auto is_complete() const -> bool override;
|
||||
|
||||
[[nodiscard]] auto is_write_supported() const -> bool override {
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto
|
||||
native_operation(native_operation_callback callback) -> api_error override;
|
||||
|
||||
[[nodiscard]] auto
|
||||
native_operation(std::uint64_t new_file_size,
|
||||
native_operation_callback callback) -> api_error override;
|
||||
|
||||
void remove(std::uint64_t handle) override;
|
||||
|
||||
void remove_all() override;
|
||||
|
||||
[[nodiscard]] auto read(std::size_t read_size, std::uint64_t read_offset,
|
||||
data_buffer &data) -> api_error override;
|
||||
|
||||
[[nodiscard]] auto resize(std::uint64_t new_file_size) -> api_error override;
|
||||
|
||||
[[nodiscard]] auto write(std::uint64_t write_offset, const data_buffer &data,
|
||||
std::size_t &bytes_written) -> api_error override;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_INCLUDE_FILE_MANAGER_OPEN_FILE_HPP_
|
221
repertory/librepertory/include/file_manager/open_file_base.hpp
Normal file
221
repertory/librepertory/include/file_manager/open_file_base.hpp
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef REPERTORY_INCLUDE_FILE_MANAGER_OPEN_FILE_BASE_HPP_
|
||||
#define REPERTORY_INCLUDE_FILE_MANAGER_OPEN_FILE_BASE_HPP_
|
||||
|
||||
#include "file_manager/i_open_file.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_provider;
|
||||
|
||||
class open_file_base : public i_closeable_open_file {
|
||||
public:
|
||||
open_file_base(std::uint64_t chunk_size, std::uint8_t chunk_timeout,
|
||||
filesystem_item fsi, i_provider &provider, bool disable_io);
|
||||
|
||||
open_file_base(std::uint64_t chunk_size, std::uint8_t chunk_timeout,
|
||||
filesystem_item fsi,
|
||||
std::map<std::uint64_t, open_file_data> open_data,
|
||||
i_provider &provider, bool disable_io);
|
||||
|
||||
~open_file_base() override = default;
|
||||
|
||||
public:
|
||||
open_file_base() = delete;
|
||||
open_file_base(const open_file_base &) noexcept = delete;
|
||||
open_file_base(open_file_base &&) noexcept = delete;
|
||||
auto operator=(open_file_base &&) noexcept -> open_file_base & = delete;
|
||||
auto operator=(const open_file_base &) noexcept -> open_file_base & = delete;
|
||||
|
||||
public:
|
||||
class download final {
|
||||
public:
|
||||
download() = default;
|
||||
|
||||
~download() = default;
|
||||
|
||||
public:
|
||||
download(const download &) noexcept = delete;
|
||||
download(download &&) noexcept = delete;
|
||||
auto operator=(download &&) noexcept -> download & = delete;
|
||||
auto operator=(const download &) noexcept -> download & = delete;
|
||||
|
||||
private:
|
||||
bool complete_{false};
|
||||
api_error error_{api_error::success};
|
||||
std::mutex mtx_;
|
||||
std::condition_variable notify_;
|
||||
|
||||
public:
|
||||
void notify(const api_error &err);
|
||||
|
||||
auto wait() -> api_error;
|
||||
};
|
||||
|
||||
class io_item final {
|
||||
public:
|
||||
io_item(std::function<api_error()> action) : action_(std::move(action)) {}
|
||||
|
||||
~io_item() = default;
|
||||
|
||||
public:
|
||||
io_item() = delete;
|
||||
io_item(const io_item &) noexcept = delete;
|
||||
io_item(io_item &&) noexcept = delete;
|
||||
auto operator=(io_item &&) noexcept -> io_item & = delete;
|
||||
auto operator=(const io_item &) noexcept -> io_item & = delete;
|
||||
|
||||
private:
|
||||
std::function<api_error()> action_;
|
||||
std::mutex mtx_;
|
||||
std::condition_variable notify_;
|
||||
std::optional<api_error> result_;
|
||||
|
||||
public:
|
||||
void action();
|
||||
|
||||
[[nodiscard]] auto get_result() -> api_error;
|
||||
};
|
||||
|
||||
private:
|
||||
std::uint64_t chunk_size_;
|
||||
std::uint8_t chunk_timeout_;
|
||||
filesystem_item fsi_;
|
||||
std::size_t last_chunk_size_;
|
||||
std::map<std::uint64_t, open_file_data> open_data_;
|
||||
i_provider &provider_;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::size_t, std::shared_ptr<download>> active_downloads_;
|
||||
api_error error_{api_error::success};
|
||||
mutable std::mutex error_mtx_;
|
||||
mutable std::recursive_mutex file_mtx_;
|
||||
stop_type io_stop_requested_{false};
|
||||
std::unique_ptr<std::thread> io_thread_;
|
||||
mutable std::mutex io_thread_mtx_;
|
||||
std::condition_variable io_thread_notify_;
|
||||
std::deque<std::shared_ptr<io_item>> io_thread_queue_;
|
||||
std::atomic<std::chrono::system_clock::time_point> last_access_{
|
||||
std::chrono::system_clock::now(),
|
||||
};
|
||||
bool modified_{false};
|
||||
bool removed_{false};
|
||||
|
||||
private:
|
||||
void file_io_thread();
|
||||
|
||||
protected:
|
||||
[[nodiscard]] auto do_io(std::function<api_error()> action) -> api_error;
|
||||
|
||||
[[nodiscard]] auto get_active_downloads()
|
||||
-> std::unordered_map<std::size_t, std::shared_ptr<download>> & {
|
||||
return active_downloads_;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_mutex() const -> std::recursive_mutex & {
|
||||
return file_mtx_;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_last_chunk_size() const -> std::size_t;
|
||||
|
||||
[[nodiscard]] auto get_provider() -> i_provider & { return provider_; }
|
||||
|
||||
[[nodiscard]] auto get_provider() const -> const i_provider & {
|
||||
return provider_;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto is_removed() const -> bool;
|
||||
|
||||
void notify_io();
|
||||
|
||||
void reset_timeout();
|
||||
|
||||
auto set_api_error(const api_error &err) -> api_error;
|
||||
|
||||
void set_file_size(std::uint64_t size);
|
||||
|
||||
void set_last_chunk_size(std::size_t size);
|
||||
|
||||
void set_modified(bool modified);
|
||||
|
||||
void set_removed(bool removed);
|
||||
|
||||
void set_source_path(std::string source_path);
|
||||
|
||||
void wait_for_io(stop_type &stop_requested);
|
||||
|
||||
public:
|
||||
void add(std::uint64_t handle, open_file_data ofd) override;
|
||||
|
||||
[[nodiscard]] auto can_close() const -> bool override;
|
||||
|
||||
auto close() -> bool override;
|
||||
|
||||
[[nodiscard]] auto get_allocated() const -> bool override { return false; }
|
||||
|
||||
[[nodiscard]] auto get_api_error() const -> api_error;
|
||||
|
||||
[[nodiscard]] auto get_api_path() const -> std::string override;
|
||||
|
||||
[[nodiscard]] auto get_chunk_size() const -> std::size_t override {
|
||||
return chunk_size_;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_file_size() const -> std::uint64_t override;
|
||||
|
||||
[[nodiscard]] auto get_filesystem_item() const -> filesystem_item override;
|
||||
|
||||
[[nodiscard]] auto get_handles() const -> std::vector<std::uint64_t> override;
|
||||
|
||||
[[nodiscard]] auto
|
||||
get_open_data() -> std::map<std::uint64_t, open_file_data> & override;
|
||||
|
||||
[[nodiscard]] auto get_open_data() const
|
||||
-> const std::map<std::uint64_t, open_file_data> & override;
|
||||
|
||||
[[nodiscard]] auto
|
||||
get_open_data(std::uint64_t handle) -> open_file_data & override;
|
||||
|
||||
[[nodiscard]] auto
|
||||
get_open_data(std::uint64_t handle) const -> const open_file_data & override;
|
||||
|
||||
[[nodiscard]] auto get_open_file_count() const -> std::size_t override;
|
||||
|
||||
[[nodiscard]] auto get_source_path() const -> std::string override;
|
||||
|
||||
[[nodiscard]] auto has_handle(std::uint64_t handle) const -> bool override;
|
||||
|
||||
[[nodiscard]] auto is_directory() const -> bool override {
|
||||
return fsi_.directory;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto is_modified() const -> bool override;
|
||||
|
||||
void remove(std::uint64_t handle) override;
|
||||
|
||||
void remove_all() override;
|
||||
|
||||
void set_api_path(const std::string &api_path) override;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_INCLUDE_FILE_MANAGER_OPEN_FILE_BASE_HPP_
|
150
repertory/librepertory/include/file_manager/ring_buffer_base.hpp
Normal file
150
repertory/librepertory/include/file_manager/ring_buffer_base.hpp
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef REPERTORY_INCLUDE_FILE_MANAGER_RING_BUFFER_BASE_HPP_
|
||||
#define REPERTORY_INCLUDE_FILE_MANAGER_RING_BUFFER_BASE_HPP_
|
||||
|
||||
#include "file_manager/open_file_base.hpp"
|
||||
|
||||
#include "types/repertory.hpp"
|
||||
#include "utils/file.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_provider;
|
||||
class i_upload_manager;
|
||||
|
||||
class ring_buffer_base : public open_file_base {
|
||||
public:
|
||||
ring_buffer_base(std::uint64_t chunk_size, std::uint8_t chunk_timeout,
|
||||
filesystem_item fsi, i_provider &provider,
|
||||
std::size_t ring_size, bool disable_io);
|
||||
|
||||
~ring_buffer_base() override = default;
|
||||
|
||||
public:
|
||||
ring_buffer_base() = delete;
|
||||
ring_buffer_base(const ring_buffer_base &) noexcept = delete;
|
||||
ring_buffer_base(ring_buffer_base &&) noexcept = delete;
|
||||
auto operator=(ring_buffer_base &&) noexcept -> ring_buffer_base & = delete;
|
||||
auto
|
||||
operator=(const ring_buffer_base &) noexcept -> ring_buffer_base & = delete;
|
||||
|
||||
public:
|
||||
static constexpr const auto min_ring_size{5U};
|
||||
|
||||
private:
|
||||
boost::dynamic_bitset<> read_state_;
|
||||
std::size_t total_chunks_;
|
||||
|
||||
private:
|
||||
std::condition_variable chunk_notify_;
|
||||
mutable std::mutex chunk_mtx_;
|
||||
std::mutex read_mtx_;
|
||||
std::unique_ptr<std::thread> reader_thread_;
|
||||
std::size_t ring_begin_{};
|
||||
std::size_t ring_end_{};
|
||||
std::size_t ring_pos_{};
|
||||
stop_type stop_requested_{false};
|
||||
|
||||
private:
|
||||
[[nodiscard]] auto check_start() -> api_error;
|
||||
|
||||
auto download_chunk(std::size_t chunk, bool skip_active) -> api_error;
|
||||
|
||||
void reader_thread();
|
||||
|
||||
void update_position(std::size_t count, bool is_forward);
|
||||
|
||||
protected:
|
||||
[[nodiscard]] auto has_reader_thread() const -> bool {
|
||||
return reader_thread_ != nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_ring_size() const -> std::size_t {
|
||||
return read_state_.size();
|
||||
}
|
||||
|
||||
[[nodiscard]] virtual auto on_check_start() -> bool = 0;
|
||||
|
||||
[[nodiscard]] virtual auto
|
||||
on_chunk_downloaded(std::size_t chunk,
|
||||
const data_buffer &buffer) -> api_error = 0;
|
||||
|
||||
[[nodiscard]] virtual auto
|
||||
on_read_chunk(std::size_t chunk, std::size_t read_size,
|
||||
std::uint64_t read_offset, data_buffer &data,
|
||||
std::size_t &bytes_read) -> api_error = 0;
|
||||
|
||||
[[nodiscard]] virtual auto
|
||||
use_buffer(std::size_t chunk,
|
||||
std::function<api_error(data_buffer &)> func) -> api_error = 0;
|
||||
|
||||
public:
|
||||
auto close() -> bool override;
|
||||
|
||||
void forward(std::size_t count);
|
||||
|
||||
[[nodiscard]] auto get_current_chunk() const -> std::size_t {
|
||||
return ring_pos_;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_first_chunk() const -> std::size_t {
|
||||
return ring_begin_;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_last_chunk() const -> std::size_t { return ring_end_; }
|
||||
|
||||
[[nodiscard]] auto get_read_state() const -> boost::dynamic_bitset<> override;
|
||||
|
||||
[[nodiscard]] auto get_read_state(std::size_t chunk) const -> bool override;
|
||||
|
||||
[[nodiscard]] auto get_total_chunks() const -> std::size_t {
|
||||
return total_chunks_;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto is_complete() const -> bool override { return false; }
|
||||
|
||||
[[nodiscard]] auto is_write_supported() const -> bool override {
|
||||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto read(std::size_t read_size, std::uint64_t read_offset,
|
||||
data_buffer &data) -> api_error override;
|
||||
|
||||
[[nodiscard]] auto resize(std::uint64_t /* size */) -> api_error override {
|
||||
return api_error::not_supported;
|
||||
}
|
||||
|
||||
void reverse(std::size_t count);
|
||||
|
||||
void set(std::size_t first_chunk, std::size_t current_chunk);
|
||||
|
||||
void set_api_path(const std::string &api_path) override;
|
||||
|
||||
[[nodiscard]] auto
|
||||
write(std::uint64_t /* write_offset */, const data_buffer & /* data */,
|
||||
std::size_t & /* bytes_written */) -> api_error override {
|
||||
return api_error::not_supported;
|
||||
}
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_INCLUDE_FILE_MANAGER_RING_BUFFER_BASE_HPP_
|
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef REPERTORY_INCLUDE_FILE_MANAGER_RING_BUFFER_OPEN_FILE_HPP_
|
||||
#define REPERTORY_INCLUDE_FILE_MANAGER_RING_BUFFER_OPEN_FILE_HPP_
|
||||
|
||||
#include "file_manager/ring_buffer_base.hpp"
|
||||
|
||||
#include "types/repertory.hpp"
|
||||
#include "utils/file.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_provider;
|
||||
class i_upload_manager;
|
||||
|
||||
class ring_buffer_open_file final : public ring_buffer_base {
|
||||
public:
|
||||
ring_buffer_open_file(std::string buffer_directory, std::uint64_t chunk_size,
|
||||
std::uint8_t chunk_timeout, filesystem_item fsi,
|
||||
i_provider &provider, std::size_t ring_size);
|
||||
|
||||
~ring_buffer_open_file() override;
|
||||
|
||||
public:
|
||||
ring_buffer_open_file() = delete;
|
||||
ring_buffer_open_file(const ring_buffer_open_file &) noexcept = delete;
|
||||
ring_buffer_open_file(ring_buffer_open_file &&) noexcept = delete;
|
||||
auto operator=(ring_buffer_open_file &&) noexcept -> ring_buffer_open_file & =
|
||||
delete;
|
||||
auto operator=(const ring_buffer_open_file &) noexcept
|
||||
-> ring_buffer_open_file & = delete;
|
||||
|
||||
private:
|
||||
std::string source_path_;
|
||||
|
||||
private:
|
||||
std::unique_ptr<utils::file::i_file> nf_;
|
||||
|
||||
protected:
|
||||
[[nodiscard]] auto on_check_start() -> bool override;
|
||||
|
||||
[[nodiscard]] auto
|
||||
on_chunk_downloaded(std::size_t chunk,
|
||||
const data_buffer &buffer) -> api_error override;
|
||||
|
||||
[[nodiscard]] auto
|
||||
on_read_chunk(std::size_t chunk, std::size_t read_size,
|
||||
std::uint64_t read_offset, data_buffer &data,
|
||||
std::size_t &bytes_read) -> api_error override;
|
||||
|
||||
[[nodiscard]] auto use_buffer(std::size_t chunk,
|
||||
std::function<api_error(data_buffer &)> func)
|
||||
-> api_error override;
|
||||
|
||||
public:
|
||||
[[nodiscard]] static auto can_handle_file(std::uint64_t file_size,
|
||||
std::size_t chunk_size,
|
||||
std::size_t ring_size) -> bool;
|
||||
|
||||
[[nodiscard]] auto
|
||||
native_operation(native_operation_callback callback) -> api_error override;
|
||||
|
||||
[[nodiscard]] auto native_operation(std::uint64_t /* new_file_size */,
|
||||
native_operation_callback /* callback */)
|
||||
-> api_error override {
|
||||
return api_error::not_supported;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_source_path() const -> std::string override {
|
||||
return source_path_;
|
||||
}
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_INCLUDE_FILE_MANAGER_RING_BUFFER_OPEN_FILE_HPP_
|
75
repertory/librepertory/include/file_manager/upload.hpp
Normal file
75
repertory/librepertory/include/file_manager/upload.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright <2018-2024> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef REPERTORY_INCLUDE_FILE_MANAGER_UPLOAD_HPP_
|
||||
#define REPERTORY_INCLUDE_FILE_MANAGER_UPLOAD_HPP_
|
||||
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_provider;
|
||||
|
||||
class upload final {
|
||||
public:
|
||||
upload(filesystem_item fsi, i_provider &provider);
|
||||
|
||||
~upload();
|
||||
|
||||
public:
|
||||
upload() = delete;
|
||||
upload(const upload &) noexcept = delete;
|
||||
upload(upload &&) noexcept = delete;
|
||||
auto operator=(upload &&) noexcept -> upload & = delete;
|
||||
auto operator=(const upload &) noexcept -> upload & = delete;
|
||||
|
||||
private:
|
||||
filesystem_item fsi_;
|
||||
i_provider &provider_;
|
||||
|
||||
private:
|
||||
bool cancelled_{false};
|
||||
api_error error_{api_error::success};
|
||||
std::unique_ptr<std::thread> thread_;
|
||||
stop_type stop_requested_{false};
|
||||
|
||||
private:
|
||||
void upload_thread();
|
||||
|
||||
public:
|
||||
void cancel();
|
||||
|
||||
[[nodiscard]] auto get_api_error() const -> api_error { return error_; }
|
||||
|
||||
[[nodiscard]] auto get_api_path() const -> std::string {
|
||||
return fsi_.api_path;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_source_path() const -> std::string {
|
||||
return fsi_.source_path;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto is_cancelled() const -> bool { return cancelled_; }
|
||||
|
||||
void stop();
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_INCLUDE_FILE_MANAGER_UPLOAD_HPP_
|
Reference in New Issue
Block a user