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_ | ||||
| @@ -19,23 +19,57 @@ | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include "file_manager/file_manager.hpp" | ||||
| #ifndef REPERTORY_INCLUDE_FILE_MANAGER_UPLOAD_HPP_ | ||||
| #define REPERTORY_INCLUDE_FILE_MANAGER_UPLOAD_HPP_ | ||||
| 
 | ||||
| #include "types/repertory.hpp" | ||||
| 
 | ||||
| namespace repertory { | ||||
| void file_manager::open_file_base::io_item::action() { | ||||
|   result_ = action_(); | ||||
| class i_provider; | ||||
| 
 | ||||
|   mutex_lock lock(mtx_); | ||||
|   notify_.notify_all(); | ||||
| } | ||||
| class upload final { | ||||
| public: | ||||
|   upload(filesystem_item fsi, i_provider &provider); | ||||
| 
 | ||||
| auto file_manager::open_file_base::io_item::get_result() -> api_error { | ||||
|   unique_mutex_lock lock(mtx_); | ||||
|   if (result_.has_value()) { | ||||
|     return result_.value(); | ||||
|   ~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; | ||||
|   } | ||||
| 
 | ||||
|   notify_.wait(lock); | ||||
|   return result_.value_or(api_error::error); | ||||
| } | ||||
|   [[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_
 | ||||
| @@ -23,6 +23,10 @@ | ||||
|  | ||||
| #include "app_config.hpp" | ||||
| #include "file_manager/events.hpp" | ||||
| #include "file_manager/open_file.hpp" | ||||
| #include "file_manager/open_file_base.hpp" | ||||
| #include "file_manager/ring_buffer_open_file.hpp" | ||||
| #include "file_manager/upload.hpp" | ||||
| #include "providers/i_provider.hpp" | ||||
| #include "types/repertory.hpp" | ||||
| #include "utils/common.hpp" | ||||
|   | ||||
| @@ -1,43 +0,0 @@ | ||||
| /* | ||||
|   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. | ||||
| */ | ||||
| #include "file_manager/file_manager.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| void file_manager::open_file_base::download::notify(const api_error &err) { | ||||
|   complete_ = true; | ||||
|   error_ = err; | ||||
|   unique_mutex_lock lock(mtx_); | ||||
|   notify_.notify_all(); | ||||
| } | ||||
|  | ||||
| auto file_manager::open_file_base::download::wait() -> api_error { | ||||
|   if (not complete_) { | ||||
|     unique_mutex_lock lock(mtx_); | ||||
|     if (not complete_) { | ||||
|       notify_.wait(lock); | ||||
|     } | ||||
|     notify_.notify_all(); | ||||
|   } | ||||
|  | ||||
|   return error_; | ||||
| } | ||||
| } // namespace repertory | ||||
| @@ -19,9 +19,10 @@ | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include "file_manager/file_manager.hpp" | ||||
| #include "file_manager/open_file.hpp" | ||||
| 
 | ||||
| #include "file_manager/events.hpp" | ||||
| #include "file_manager/i_upload_manager.hpp" | ||||
| #include "platform/platform.hpp" | ||||
| #include "providers/i_provider.hpp" | ||||
| #include "types/repertory.hpp" | ||||
| @@ -34,31 +35,32 @@ | ||||
| #include "utils/utils.hpp" | ||||
| 
 | ||||
| namespace repertory { | ||||
| file_manager::open_file::open_file(std::uint64_t chunk_size, | ||||
|                                    std::uint8_t chunk_timeout, | ||||
| open_file::open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout, | ||||
|                      filesystem_item fsi, i_provider &provider, | ||||
|                      i_upload_manager &mgr) | ||||
|     : open_file(chunk_size, chunk_timeout, fsi, {}, provider, std::nullopt, | ||||
|                 mgr) {} | ||||
| 
 | ||||
| file_manager::open_file::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::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(chunk_size, chunk_timeout, fsi, open_data, provider, | ||||
|                 std::nullopt, mgr) {} | ||||
| 
 | ||||
| file_manager::open_file::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, | ||||
| open_file::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) | ||||
|     : open_file(chunk_size, chunk_timeout, fsi, {}, provider, read_state, mgr) { | ||||
| } | ||||
| 
 | ||||
| file_manager::open_file::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) | ||||
| open_file::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) | ||||
|     : open_file_base(chunk_size, chunk_timeout, fsi, open_data, provider), | ||||
|       mgr_(mgr) { | ||||
|   if (fsi_.directory && read_state.has_value()) { | ||||
| @@ -93,10 +95,9 @@ file_manager::open_file::open_file( | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| file_manager::open_file::~open_file() { close(); } | ||||
| open_file::~open_file() { close(); } | ||||
| 
 | ||||
| void file_manager::open_file::download_chunk(std::size_t chunk, | ||||
|                                              bool skip_active, | ||||
| void open_file::download_chunk(std::size_t chunk, bool skip_active, | ||||
|                                bool should_reset) { | ||||
|   if (should_reset) { | ||||
|     reset_timeout(); | ||||
| @@ -206,8 +207,8 @@ void file_manager::open_file::download_chunk(std::size_t chunk, | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void file_manager::open_file::download_range( | ||||
|     std::size_t start_chunk_index, std::size_t end_chunk_index_inclusive, | ||||
| void open_file::download_range(std::size_t start_chunk_index, | ||||
|                                std::size_t end_chunk_index_inclusive, | ||||
|                                bool should_reset) { | ||||
|   for (std::size_t chunk = start_chunk_index; | ||||
|        chunk <= end_chunk_index_inclusive; chunk++) { | ||||
| @@ -218,23 +219,22 @@ void file_manager::open_file::download_range( | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file::get_read_state() const | ||||
|     -> boost::dynamic_bitset<> { | ||||
| auto open_file::get_read_state() const -> boost::dynamic_bitset<> { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   return read_state_; | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file::get_read_state(std::size_t chunk) const -> bool { | ||||
| auto open_file::get_read_state(std::size_t chunk) const -> bool { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   return read_state_[chunk]; | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file::is_complete() const -> bool { | ||||
| auto open_file::is_complete() const -> bool { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   return read_state_.all(); | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file::native_operation( | ||||
| auto open_file::native_operation( | ||||
|     i_open_file::native_operation_callback callback) -> api_error { | ||||
|   unique_recur_mutex_lock file_lock(file_mtx_); | ||||
|   if (stop_requested_) { | ||||
| @@ -245,7 +245,7 @@ auto file_manager::open_file::native_operation( | ||||
|   return do_io([&]() -> api_error { return callback(nf_->get_handle()); }); | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file::native_operation( | ||||
| auto open_file::native_operation( | ||||
|     std::uint64_t new_file_size, | ||||
|     i_open_file::native_operation_callback callback) -> api_error { | ||||
|   REPERTORY_USES_FUNCTION_NAME(); | ||||
| @@ -336,9 +336,8 @@ auto file_manager::open_file::native_operation( | ||||
|   return res; | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file::read(std::size_t read_size, | ||||
|                                    std::uint64_t read_offset, data_buffer &data) | ||||
|     -> api_error { | ||||
| auto open_file::read(std::size_t read_size, std::uint64_t read_offset, | ||||
|                      data_buffer &data) -> api_error { | ||||
|   if (fsi_.directory) { | ||||
|     return api_error::invalid_operation; | ||||
|   } | ||||
| @@ -389,7 +388,7 @@ auto file_manager::open_file::read(std::size_t read_size, | ||||
|                                                : get_api_error(); | ||||
| } | ||||
| 
 | ||||
| void file_manager::open_file::remove(std::uint64_t handle) { | ||||
| void open_file::remove(std::uint64_t handle) { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   open_file_base::remove(handle); | ||||
|   if (modified_ && read_state_.all() && | ||||
| @@ -403,7 +402,7 @@ void file_manager::open_file::remove(std::uint64_t handle) { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file::resize(std::uint64_t new_file_size) -> api_error { | ||||
| auto open_file::resize(std::uint64_t new_file_size) -> api_error { | ||||
|   if (fsi_.directory) { | ||||
|     return api_error::invalid_operation; | ||||
|   } | ||||
| @@ -415,7 +414,7 @@ auto file_manager::open_file::resize(std::uint64_t new_file_size) -> api_error { | ||||
|       }); | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file::close() -> bool { | ||||
| auto open_file::close() -> bool { | ||||
|   REPERTORY_USES_FUNCTION_NAME(); | ||||
| 
 | ||||
|   if (not fsi_.directory && not stop_requested_) { | ||||
| @@ -479,7 +478,7 @@ auto file_manager::open_file::close() -> bool { | ||||
|   return false; | ||||
| } | ||||
| 
 | ||||
| void file_manager::open_file::set_modified() { | ||||
| void open_file::set_modified() { | ||||
|   if (not modified_) { | ||||
|     modified_ = true; | ||||
|     mgr_.store_resume(*this); | ||||
| @@ -491,7 +490,7 @@ void file_manager::open_file::set_modified() { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void file_manager::open_file::update_background_reader(std::size_t read_chunk) { | ||||
| void open_file::update_background_reader(std::size_t read_chunk) { | ||||
|   recur_mutex_lock reader_lock(file_mtx_); | ||||
|   read_chunk_index_ = read_chunk; | ||||
| 
 | ||||
| @@ -526,8 +525,7 @@ void file_manager::open_file::update_background_reader(std::size_t read_chunk) { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file::write(std::uint64_t write_offset, | ||||
|                                     const data_buffer &data, | ||||
| auto open_file::write(std::uint64_t write_offset, const data_buffer &data, | ||||
|                       std::size_t &bytes_written) -> api_error { | ||||
|   REPERTORY_USES_FUNCTION_NAME(); | ||||
| 
 | ||||
| @@ -19,19 +19,55 @@ | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include "file_manager/file_manager.hpp" | ||||
| #include "file_manager/open_file_base.hpp" | ||||
| 
 | ||||
| #include "file_manager/events.hpp" | ||||
| #include "providers/i_provider.hpp" | ||||
| #include "utils/path.hpp" | ||||
| 
 | ||||
| namespace repertory { | ||||
| file_manager::open_file_base::open_file_base(std::uint64_t chunk_size, | ||||
|                                              std::uint8_t chunk_timeout, | ||||
|                                              filesystem_item fsi, | ||||
| void open_file_base::download::notify(const api_error &err) { | ||||
|   complete_ = true; | ||||
|   error_ = err; | ||||
|   unique_mutex_lock lock(mtx_); | ||||
|   notify_.notify_all(); | ||||
| } | ||||
| 
 | ||||
| auto open_file_base::download::wait() -> api_error { | ||||
|   if (not complete_) { | ||||
|     unique_mutex_lock lock(mtx_); | ||||
|     if (not complete_) { | ||||
|       notify_.wait(lock); | ||||
|     } | ||||
|     notify_.notify_all(); | ||||
|   } | ||||
| 
 | ||||
|   return error_; | ||||
| } | ||||
| 
 | ||||
| void open_file_base::io_item::action() { | ||||
|   result_ = action_(); | ||||
| 
 | ||||
|   mutex_lock lock(mtx_); | ||||
|   notify_.notify_all(); | ||||
| } | ||||
| 
 | ||||
| auto open_file_base::io_item::get_result() -> api_error { | ||||
|   unique_mutex_lock lock(mtx_); | ||||
|   if (result_.has_value()) { | ||||
|     return result_.value(); | ||||
|   } | ||||
| 
 | ||||
|   notify_.wait(lock); | ||||
|   return result_.value_or(api_error::error); | ||||
| } | ||||
| 
 | ||||
| open_file_base::open_file_base(std::uint64_t chunk_size, | ||||
|                                std::uint8_t chunk_timeout, filesystem_item fsi, | ||||
|                                i_provider &provider) | ||||
|     : open_file_base(chunk_size, chunk_timeout, fsi, {}, provider) {} | ||||
| 
 | ||||
| file_manager::open_file_base::open_file_base( | ||||
| open_file_base::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) | ||||
|     : chunk_size_(chunk_size), | ||||
| @@ -48,8 +84,7 @@ file_manager::open_file_base::open_file_base( | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void file_manager::open_file_base::add(std::uint64_t handle, | ||||
|                                        open_file_data ofd) { | ||||
| void open_file_base::add(std::uint64_t handle, open_file_data ofd) { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   open_data_[handle] = ofd; | ||||
|   if (open_data_.size() == 1U) { | ||||
| @@ -61,7 +96,7 @@ void file_manager::open_file_base::add(std::uint64_t handle, | ||||
|       fsi_.api_path, handle, fsi_.source_path, fsi_.directory); | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file_base::can_close() const -> bool { | ||||
| auto open_file_base::can_close() const -> bool { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   if (fsi_.directory) { | ||||
|     return true; | ||||
| @@ -93,8 +128,7 @@ auto file_manager::open_file_base::can_close() const -> bool { | ||||
|   return (duration.count() >= chunk_timeout_); | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file_base::do_io(std::function<api_error()> action) | ||||
|     -> api_error { | ||||
| auto open_file_base::do_io(std::function<api_error()> action) -> api_error { | ||||
|   unique_mutex_lock io_lock(io_thread_mtx_); | ||||
|   auto item = std::make_shared<io_item>(action); | ||||
|   io_thread_queue_.emplace_back(item); | ||||
| @@ -104,7 +138,7 @@ auto file_manager::open_file_base::do_io(std::function<api_error()> action) | ||||
|   return item->get_result(); | ||||
| } | ||||
| 
 | ||||
| void file_manager::open_file_base::file_io_thread() { | ||||
| void open_file_base::file_io_thread() { | ||||
|   unique_mutex_lock io_lock(io_thread_mtx_); | ||||
|   io_thread_notify_.notify_all(); | ||||
|   io_lock.unlock(); | ||||
| @@ -137,29 +171,27 @@ void file_manager::open_file_base::file_io_thread() { | ||||
|   process_queue(); | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file_base::get_api_error() const -> api_error { | ||||
| auto open_file_base::get_api_error() const -> api_error { | ||||
|   mutex_lock error_lock(error_mtx_); | ||||
|   return error_; | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file_base::get_api_path() const -> std::string { | ||||
| auto open_file_base::get_api_path() const -> std::string { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   return fsi_.api_path; | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file_base::get_file_size() const -> std::uint64_t { | ||||
| auto open_file_base::get_file_size() const -> std::uint64_t { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   return fsi_.size; | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file_base::get_filesystem_item() const | ||||
|     -> filesystem_item { | ||||
| auto open_file_base::get_filesystem_item() const -> filesystem_item { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   return fsi_; | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file_base::get_handles() const | ||||
|     -> std::vector<std::uint64_t> { | ||||
| auto open_file_base::get_handles() const -> std::vector<std::uint64_t> { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   std::vector<std::uint64_t> ret; | ||||
|   for (auto &&item : open_data_) { | ||||
| @@ -169,41 +201,40 @@ auto file_manager::open_file_base::get_handles() const | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file_base::get_open_data() | ||||
| auto open_file_base::get_open_data() | ||||
|     -> std::map<std::uint64_t, open_file_data> & { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   return open_data_; | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file_base::get_open_data() const | ||||
| auto open_file_base::get_open_data() const | ||||
|     -> const std::map<std::uint64_t, open_file_data> & { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   return open_data_; | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file_base::get_open_data(std::uint64_t handle) | ||||
|     -> open_file_data & { | ||||
| auto open_file_base::get_open_data(std::uint64_t handle) -> open_file_data & { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   return open_data_.at(handle); | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file_base::get_open_data(std::uint64_t handle) const | ||||
| auto open_file_base::get_open_data(std::uint64_t handle) const | ||||
|     -> const open_file_data & { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   return open_data_.at(handle); | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file_base::get_open_file_count() const -> std::size_t { | ||||
| auto open_file_base::get_open_file_count() const -> std::size_t { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   return open_data_.size(); | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file_base::is_modified() const -> bool { | ||||
| auto open_file_base::is_modified() const -> bool { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   return modified_; | ||||
| } | ||||
| 
 | ||||
| void file_manager::open_file_base::remove(std::uint64_t handle) { | ||||
| void open_file_base::remove(std::uint64_t handle) { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   open_data_.erase(handle); | ||||
|   event_system::instance().raise<filesystem_item_handle_closed>( | ||||
| @@ -214,12 +245,11 @@ void file_manager::open_file_base::remove(std::uint64_t handle) { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void file_manager::open_file_base::reset_timeout() { | ||||
| void open_file_base::reset_timeout() { | ||||
|   last_access_ = std::chrono::system_clock::now(); | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file_base::set_api_error(const api_error &err) | ||||
|     -> api_error { | ||||
| auto open_file_base::set_api_error(const api_error &err) -> api_error { | ||||
|   mutex_lock error_lock(error_mtx_); | ||||
|   if (error_ != err) { | ||||
|     return ((error_ = (error_ == api_error::success || | ||||
| @@ -232,13 +262,13 @@ auto file_manager::open_file_base::set_api_error(const api_error &err) | ||||
|   return error_; | ||||
| } | ||||
| 
 | ||||
| void file_manager::open_file_base::set_api_path(const std::string &api_path) { | ||||
| void open_file_base::set_api_path(const std::string &api_path) { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   fsi_.api_path = api_path; | ||||
|   fsi_.api_parent = utils::path::get_parent_api_path(api_path); | ||||
| } | ||||
| 
 | ||||
| auto file_manager::open_file_base::close() -> bool { | ||||
| auto open_file_base::close() -> bool { | ||||
|   unique_mutex_lock io_lock(io_thread_mtx_); | ||||
|   if (not fsi_.directory && not io_stop_requested_) { | ||||
|     io_stop_requested_ = true; | ||||
| @@ -19,10 +19,11 @@ | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include "file_manager/file_manager.hpp" | ||||
| #include "file_manager/ring_buffer_open_file.hpp" | ||||
| 
 | ||||
| #include "app_config.hpp" | ||||
| #include "file_manager/events.hpp" | ||||
| #include "file_manager/open_file_base.hpp" | ||||
| #include "platform/platform.hpp" | ||||
| #include "providers/i_provider.hpp" | ||||
| #include "types/repertory.hpp" | ||||
| @@ -33,16 +34,20 @@ | ||||
| #include "utils/utils.hpp" | ||||
| 
 | ||||
| namespace repertory { | ||||
| file_manager::ring_buffer_open_file::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::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::move(buffer_directory), chunk_size, | ||||
|                             chunk_timeout, std::move(fsi), provider, | ||||
|                             (1024ULL * 1024ULL * 1024ULL) / chunk_size) {} | ||||
| 
 | ||||
| file_manager::ring_buffer_open_file::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::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) | ||||
|     : open_file_base(chunk_size, chunk_timeout, fsi, provider), | ||||
|       ring_state_(ring_size), | ||||
| @@ -85,7 +90,7 @@ file_manager::ring_buffer_open_file::ring_buffer_open_file( | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| file_manager::ring_buffer_open_file::~ring_buffer_open_file() { | ||||
| ring_buffer_open_file::~ring_buffer_open_file() { | ||||
|   REPERTORY_USES_FUNCTION_NAME(); | ||||
| 
 | ||||
|   close(); | ||||
| @@ -98,8 +103,7 @@ file_manager::ring_buffer_open_file::~ring_buffer_open_file() { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| auto file_manager::file_manager::ring_buffer_open_file::download_chunk( | ||||
|     std::size_t chunk) -> api_error { | ||||
| auto r::ring_buffer_open_file::download_chunk(std::size_t chunk) -> api_error { | ||||
|   unique_mutex_lock chunk_lock(chunk_mtx_); | ||||
|   if (active_downloads_.find(chunk) != active_downloads_.end()) { | ||||
|     auto active_download = active_downloads_.at(chunk); | ||||
| @@ -149,7 +153,7 @@ auto file_manager::file_manager::ring_buffer_open_file::download_chunk( | ||||
|   return api_error::success; | ||||
| } | ||||
| 
 | ||||
| void file_manager::ring_buffer_open_file::forward(std::size_t count) { | ||||
| void ring_buffer_open_file::forward(std::size_t count) { | ||||
|   mutex_lock chunk_lock(chunk_mtx_); | ||||
|   if ((current_chunk_ + count) > (total_chunks_ - 1U)) { | ||||
|     count = (total_chunks_ - 1U) - current_chunk_; | ||||
| @@ -179,29 +183,27 @@ void file_manager::ring_buffer_open_file::forward(std::size_t count) { | ||||
|   chunk_notify_.notify_all(); | ||||
| } | ||||
| 
 | ||||
| auto file_manager::ring_buffer_open_file::get_read_state() const | ||||
|     -> boost::dynamic_bitset<> { | ||||
| auto ring_buffer_open_file::get_read_state() const -> boost::dynamic_bitset<> { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   auto read_state = ring_state_; | ||||
|   return read_state.flip(); | ||||
| } | ||||
| 
 | ||||
| auto file_manager::ring_buffer_open_file::get_read_state( | ||||
|     std::size_t chunk) const -> bool { | ||||
| auto ring_buffer_open_file::get_read_state(std::size_t chunk) const -> bool { | ||||
|   recur_mutex_lock file_lock(file_mtx_); | ||||
|   return not ring_state_[chunk % ring_state_.size()]; | ||||
| } | ||||
| 
 | ||||
| auto file_manager::ring_buffer_open_file::is_download_complete() const -> bool { | ||||
| auto ring_buffer_open_file::is_download_complete() const -> bool { | ||||
|   return false; | ||||
| } | ||||
| 
 | ||||
| auto file_manager::ring_buffer_open_file::native_operation( | ||||
| auto ring_buffer_open_file::native_operation( | ||||
|     i_open_file::native_operation_callback callback) -> api_error { | ||||
|   return do_io([&]() -> api_error { return callback(nf_->get_handle()); }); | ||||
| } | ||||
| 
 | ||||
| void file_manager::ring_buffer_open_file::reverse(std::size_t count) { | ||||
| void ring_buffer_open_file::reverse(std::size_t count) { | ||||
|   mutex_lock chunk_lock(chunk_mtx_); | ||||
|   if (current_chunk_ < count) { | ||||
|     count = current_chunk_; | ||||
| @@ -231,9 +233,9 @@ void file_manager::ring_buffer_open_file::reverse(std::size_t count) { | ||||
|   chunk_notify_.notify_all(); | ||||
| } | ||||
| 
 | ||||
| auto file_manager::ring_buffer_open_file::read(std::size_t read_size, | ||||
|                                                std::uint64_t read_offset, | ||||
|                                                data_buffer &data) -> api_error { | ||||
| auto ring_buffer_open_file::read(std::size_t read_size, | ||||
|                                  std::uint64_t read_offset, data_buffer &data) | ||||
|     -> api_error { | ||||
|   if (fsi_.directory) { | ||||
|     return api_error::invalid_operation; | ||||
|   } | ||||
| @@ -290,7 +292,7 @@ auto file_manager::ring_buffer_open_file::read(std::size_t read_size, | ||||
|   return res; | ||||
| } | ||||
| 
 | ||||
| void file_manager::ring_buffer_open_file::set(std::size_t first_chunk, | ||||
| void ring_buffer_open_file::set(std::size_t first_chunk, | ||||
|                                 std::size_t current_chunk) { | ||||
|   mutex_lock chunk_lock(chunk_mtx_); | ||||
|   if (first_chunk >= total_chunks_) { | ||||
| @@ -313,8 +315,7 @@ void file_manager::ring_buffer_open_file::set(std::size_t first_chunk, | ||||
|   chunk_notify_.notify_all(); | ||||
| } | ||||
| 
 | ||||
| void file_manager::ring_buffer_open_file::set_api_path( | ||||
|     const std::string &api_path) { | ||||
| void ring_buffer_open_file::set_api_path(const std::string &api_path) { | ||||
|   mutex_lock chunk_lock(chunk_mtx_); | ||||
|   open_file_base::set_api_path(api_path); | ||||
|   chunk_notify_.notify_all(); | ||||
| @@ -19,7 +19,7 @@ | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include "file_manager/file_manager.hpp" | ||||
| #include "file_manager/upload.hpp" | ||||
| 
 | ||||
| #include "platform/platform.hpp" | ||||
| #include "providers/i_provider.hpp" | ||||
| @@ -157,8 +157,8 @@ template <typename ctx_t, typename op_t> struct db_where_t final { | ||||
|  | ||||
|   using action_t = std::variant<db_comp_data_t, n_t, db_where_t>; | ||||
|  | ||||
|   [[nodiscard]] static auto dump(std::int32_t &idx, | ||||
|                                  auto &&actions) -> std::string { | ||||
|   [[nodiscard]] static auto dump(std::int32_t &idx, auto &&actions) | ||||
|       -> std::string { | ||||
|     std::stringstream stream; | ||||
|  | ||||
|     for (auto &&action : actions) { | ||||
|   | ||||
| @@ -27,13 +27,12 @@ std::atomic<const i_exception_handler *> exception_handler{ | ||||
|  | ||||
| auto create_error_message(std::vector<std::string_view> items) -> std::string { | ||||
|   std::stringstream stream{}; | ||||
|   stream << function_name; | ||||
|   for (std::size_t idx = 0U; idx < items.size(); ++idx) { | ||||
|     if (idx > 0) { | ||||
|       stream << '|'; | ||||
|     } | ||||
|  | ||||
|     stream << item; | ||||
|     stream << items.at(idx); | ||||
|   } | ||||
|  | ||||
|   return stream.str(); | ||||
|   | ||||
| @@ -397,6 +397,8 @@ auto file::sha256() -> std::optional<std::string> { | ||||
| #endif // defined(PROJECT_ENABLE_LIBSODIUM) | ||||
|  | ||||
| auto file::remove() -> bool { | ||||
|   REPERTORY_USES_FUNCTION_NAME(); | ||||
|  | ||||
|   close(); | ||||
|  | ||||
|   return utils::retry_action([this]() -> bool { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user