refactor
This commit is contained in:
@ -27,6 +27,7 @@
|
||||
#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 "platform/platform.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
#include "utils/db/sqlite/db_common.hpp"
|
||||
@ -39,408 +40,6 @@ class i_provider;
|
||||
class file_manager final : public i_file_manager, public i_upload_manager {
|
||||
E_CONSUMER();
|
||||
|
||||
public:
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
~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;
|
||||
};
|
||||
|
||||
protected:
|
||||
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:
|
||||
api_error error_{api_error::success};
|
||||
mutable std::mutex error_mtx_;
|
||||
stop_type io_stop_requested_{false};
|
||||
std::unique_ptr<std::thread> io_thread_;
|
||||
|
||||
protected:
|
||||
std::unordered_map<std::size_t, std::shared_ptr<download>>
|
||||
active_downloads_;
|
||||
mutable std::recursive_mutex file_mtx_;
|
||||
std::atomic<std::chrono::system_clock::time_point> last_access_{
|
||||
std::chrono::system_clock::now()};
|
||||
bool modified_{false};
|
||||
std::unique_ptr<utils::file::i_file> nf_;
|
||||
mutable std::mutex io_thread_mtx_;
|
||||
std::condition_variable io_thread_notify_;
|
||||
std::deque<std::shared_ptr<io_item>> io_thread_queue_;
|
||||
bool removed_{false};
|
||||
|
||||
private:
|
||||
void file_io_thread();
|
||||
|
||||
protected:
|
||||
[[nodiscard]] auto do_io(std::function<api_error()> action) -> api_error;
|
||||
|
||||
virtual auto is_download_complete() const -> bool = 0;
|
||||
|
||||
void reset_timeout();
|
||||
|
||||
auto set_api_error(const api_error &e) -> api_error;
|
||||
|
||||
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_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 {
|
||||
return fsi_.source_path;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto has_handle(std::uint64_t handle) const -> bool override {
|
||||
return open_data_.find(handle) != open_data_.end();
|
||||
}
|
||||
|
||||
[[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 set_api_path(const std::string &api_path) override;
|
||||
};
|
||||
|
||||
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 notified_ = false;
|
||||
std::size_t read_chunk_index_{};
|
||||
boost::dynamic_bitset<> read_state_;
|
||||
std::unique_ptr<std::thread> reader_thread_;
|
||||
std::unique_ptr<std::thread> download_thread_;
|
||||
stop_type stop_requested_ = false;
|
||||
|
||||
private:
|
||||
void download_chunk(std::size_t chunk, bool skip_active, bool should_reset);
|
||||
|
||||
void download_range(std::size_t start_chunk_index,
|
||||
std::size_t end_chunk_index_inclusive,
|
||||
bool should_reset);
|
||||
|
||||
void set_modified();
|
||||
|
||||
void update_background_reader(std::size_t read_chunk);
|
||||
|
||||
protected:
|
||||
auto is_download_complete() const -> bool override {
|
||||
return read_state_.all();
|
||||
}
|
||||
|
||||
public:
|
||||
auto close() -> 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;
|
||||
|
||||
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;
|
||||
|
||||
[[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;
|
||||
};
|
||||
|
||||
class ring_buffer_open_file final : public open_file_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);
|
||||
|
||||
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:
|
||||
boost::dynamic_bitset<> ring_state_;
|
||||
std::size_t total_chunks_;
|
||||
|
||||
private:
|
||||
std::unique_ptr<std::thread> chunk_forward_thread_;
|
||||
std::unique_ptr<std::thread> chunk_reverse_thread_;
|
||||
std::condition_variable chunk_notify_;
|
||||
mutable std::mutex chunk_mtx_;
|
||||
std::size_t current_chunk_{};
|
||||
std::size_t first_chunk_{};
|
||||
std::size_t last_chunk_;
|
||||
|
||||
private:
|
||||
auto download_chunk(std::size_t chunk) -> api_error;
|
||||
|
||||
void forward_reader_thread(std::size_t count);
|
||||
|
||||
void reverse_reader_thread(std::size_t count);
|
||||
|
||||
protected:
|
||||
auto is_download_complete() const -> bool override;
|
||||
|
||||
public:
|
||||
void forward(std::size_t count);
|
||||
|
||||
[[nodiscard]] auto get_current_chunk() const -> std::size_t {
|
||||
return current_chunk_;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_first_chunk() const -> std::size_t {
|
||||
return first_chunk_;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_last_chunk() const -> std::size_t {
|
||||
return last_chunk_;
|
||||
}
|
||||
|
||||
[[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 true; }
|
||||
|
||||
auto is_write_supported() const -> bool override { return false; }
|
||||
|
||||
[[nodiscard]] auto native_operation(native_operation_callback callback)
|
||||
-> api_error override;
|
||||
|
||||
[[nodiscard]] auto native_operation(std::uint64_t,
|
||||
native_operation_callback)
|
||||
-> api_error override {
|
||||
return api_error::not_supported;
|
||||
}
|
||||
|
||||
[[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) -> 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, const data_buffer &, std::size_t &)
|
||||
-> api_error override {
|
||||
return api_error::not_supported;
|
||||
}
|
||||
};
|
||||
|
||||
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();
|
||||
};
|
||||
|
||||
public:
|
||||
file_manager(app_config &config, i_provider &provider);
|
||||
|
||||
|
122
repertory/librepertory/include/file_manager/open_file.hpp
Normal file
122
repertory/librepertory/include/file_manager/open_file.hpp
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
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"
|
||||
|
||||
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 notified_ = false;
|
||||
std::size_t read_chunk_index_{};
|
||||
boost::dynamic_bitset<> read_state_;
|
||||
std::unique_ptr<std::thread> reader_thread_;
|
||||
std::unique_ptr<std::thread> download_thread_;
|
||||
stop_type stop_requested_ = false;
|
||||
|
||||
private:
|
||||
void download_chunk(std::size_t chunk, bool skip_active, bool should_reset);
|
||||
|
||||
void download_range(std::size_t start_chunk_index,
|
||||
std::size_t end_chunk_index_inclusive, bool should_reset);
|
||||
|
||||
void set_modified();
|
||||
|
||||
void update_background_reader(std::size_t read_chunk);
|
||||
|
||||
protected:
|
||||
auto is_download_complete() const -> bool override {
|
||||
return read_state_.all();
|
||||
}
|
||||
|
||||
public:
|
||||
auto close() -> 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;
|
||||
|
||||
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;
|
||||
|
||||
[[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_
|
194
repertory/librepertory/include/file_manager/open_file_base.hpp
Normal file
194
repertory/librepertory/include/file_manager/open_file_base.hpp
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
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"
|
||||
|
||||
#include "utils/types/file/i_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);
|
||||
|
||||
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);
|
||||
|
||||
~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;
|
||||
};
|
||||
|
||||
protected:
|
||||
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:
|
||||
api_error error_{api_error::success};
|
||||
mutable std::mutex error_mtx_;
|
||||
stop_type io_stop_requested_{false};
|
||||
std::unique_ptr<std::thread> io_thread_;
|
||||
|
||||
protected:
|
||||
std::unordered_map<std::size_t, std::shared_ptr<download>> active_downloads_;
|
||||
mutable std::recursive_mutex file_mtx_;
|
||||
std::atomic<std::chrono::system_clock::time_point> last_access_{
|
||||
std::chrono::system_clock::now()};
|
||||
bool modified_{false};
|
||||
std::unique_ptr<utils::file::i_file> nf_;
|
||||
mutable std::mutex io_thread_mtx_;
|
||||
std::condition_variable io_thread_notify_;
|
||||
std::deque<std::shared_ptr<io_item>> io_thread_queue_;
|
||||
bool removed_{false};
|
||||
|
||||
private:
|
||||
void file_io_thread();
|
||||
|
||||
protected:
|
||||
[[nodiscard]] auto do_io(std::function<api_error()> action) -> api_error;
|
||||
|
||||
virtual auto is_download_complete() const -> bool = 0;
|
||||
|
||||
void reset_timeout();
|
||||
|
||||
auto set_api_error(const api_error &e) -> api_error;
|
||||
|
||||
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_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 {
|
||||
return fsi_.source_path;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto has_handle(std::uint64_t handle) const -> bool override {
|
||||
return open_data_.find(handle) != open_data_.end();
|
||||
}
|
||||
|
||||
[[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 set_api_path(const std::string &api_path) override;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // REPERTORY_INCLUDE_FILE_MANAGER_OPEN_FILE_BASE_HPP_
|
@ -0,0 +1,132 @@
|
||||
/*
|
||||
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/open_file_base.hpp"
|
||||
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class i_provider;
|
||||
class i_upload_manager;
|
||||
|
||||
class ring_buffer_open_file final : public open_file_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);
|
||||
|
||||
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:
|
||||
boost::dynamic_bitset<> ring_state_;
|
||||
std::size_t total_chunks_;
|
||||
|
||||
private:
|
||||
std::unique_ptr<std::thread> chunk_forward_thread_;
|
||||
std::unique_ptr<std::thread> chunk_reverse_thread_;
|
||||
std::condition_variable chunk_notify_;
|
||||
mutable std::mutex chunk_mtx_;
|
||||
std::size_t current_chunk_{};
|
||||
std::size_t first_chunk_{};
|
||||
std::size_t last_chunk_;
|
||||
|
||||
private:
|
||||
auto download_chunk(std::size_t chunk) -> api_error;
|
||||
|
||||
void forward_reader_thread(std::size_t count);
|
||||
|
||||
void reverse_reader_thread(std::size_t count);
|
||||
|
||||
protected:
|
||||
auto is_download_complete() const -> bool override;
|
||||
|
||||
public:
|
||||
void forward(std::size_t count);
|
||||
|
||||
[[nodiscard]] auto get_current_chunk() const -> std::size_t {
|
||||
return current_chunk_;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_first_chunk() const -> std::size_t {
|
||||
return first_chunk_;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_last_chunk() const -> std::size_t {
|
||||
return last_chunk_;
|
||||
}
|
||||
|
||||
[[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 true; }
|
||||
|
||||
auto is_write_supported() const -> bool override { return false; }
|
||||
|
||||
[[nodiscard]] auto native_operation(native_operation_callback callback)
|
||||
-> api_error override;
|
||||
|
||||
[[nodiscard]] auto native_operation(std::uint64_t, native_operation_callback)
|
||||
-> api_error override {
|
||||
return api_error::not_supported;
|
||||
}
|
||||
|
||||
[[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) -> 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, const data_buffer &, std::size_t &)
|
||||
-> api_error override {
|
||||
return api_error::not_supported;
|
||||
}
|
||||
};
|
||||
} // 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