From 3587b47edd9d929a9cdc077bb32423e9e7ce5e65 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Wed, 25 Dec 2024 11:48:59 -0600 Subject: [PATCH] refactor --- .../include/file_manager/open_file.hpp | 3 + .../src/file_manager/open_file.cpp | 144 ++++++++++++------ 2 files changed, 103 insertions(+), 44 deletions(-) diff --git a/repertory/librepertory/include/file_manager/open_file.hpp b/repertory/librepertory/include/file_manager/open_file.hpp index 18f0088b..382df53a 100644 --- a/repertory/librepertory/include/file_manager/open_file.hpp +++ b/repertory/librepertory/include/file_manager/open_file.hpp @@ -77,6 +77,9 @@ private: stop_type stop_requested_{false}; private: + [[nodiscard]] auto adjust_cache_size(std::uint64_t file_size, bool shrink) + -> api_error; + [[nodiscard]] auto check_allocation() -> api_error; void download_chunk(std::size_t chunk, bool skip_active, bool should_reset); diff --git a/repertory/librepertory/src/file_manager/open_file.cpp b/repertory/librepertory/src/file_manager/open_file.cpp index 720f6c81..ea9c9c64 100644 --- a/repertory/librepertory/src/file_manager/open_file.cpp +++ b/repertory/librepertory/src/file_manager/open_file.cpp @@ -87,16 +87,30 @@ open_file::open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout, if (read_state.has_value()) { read_state_ = read_state.value(); set_modified(); - } else if (fsi_.size > 0U) { - read_state_.resize(static_cast( - utils::divide_with_ceiling(fsi_.size, chunk_size)), - false); + allocated = true; + return; + } - auto file_size = nf_->size().value_or(0U); - if (provider_.is_read_only() || file_size == fsi.size) { - read_state_.set(0U, read_state_.size(), true); - allocated = true; - } + if (fsi_.size == 0U) { + return; + } + + read_state_.resize(static_cast( + utils::divide_with_ceiling(fsi_.size, chunk_size)), + false); + + auto file_size = nf_->size(); + if (not file_size.has_value()) { + utils::error::raise_api_path_error( + function_name, fsi.api_path, fsi.source_path, + utils::get_last_error_code(), "failed to get file size"); + set_api_error(api_error::os_error); + return; + } + + if (provider_.is_read_only() || file_size.value() == fsi.size) { + read_state_.set(0U, read_state_.size(), true); + allocated = true; } if (get_api_error() != api_error::success && *nf_) { @@ -106,34 +120,76 @@ open_file::open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout, open_file::~open_file() { close(); } +auto open_file::adjust_cache_size(std::uint64_t file_size, bool shrink) + -> api_error { + + if (file_size == fsi_.size) { + return api_error::success; + } + + if (file_size > fsi_.size) { + auto size = file_size - file_size.value(); + auto res = shrink ? cache_size_mgr::instance().shrink(size) + : cache_size_mgr::instance().expand(size); + if (res == api_error::success) { + return res; + } + + utils::error::raise_api_path_error( + function_name, fsi_.api_path, fsi_.source_path, res, + fmt::format("failed to {} cache|size|{}", + (shrink ? "shrink" : "expand"), size)); + return set_api_error(res); + } + + auto size = fsi_.size = file_size; + auto res = shrink ? cache_size_mgr::instance().expand(size) + : cache_size_mgr::instance().shrink(size); + if (res == api_error::success) { + return res; + } + + utils::error::raise_api_path_error( + function_name, fsi_.api_path, fsi_.source_path, res, + fmt::format("failed to {} cache|size|{}", (shrink ? "expand" : "shrink"), + size)); + return set_api_error(res); +} + auto open_file::check_allocation() -> api_error { + REPERTORY_USES_FUNCTION_NAME(); + unique_recur_mutex_lock file_lock(file_mtx_); if (allocated) { return api_error::success; } - auto file_size = nf_->size().value_or(0U); - if (file_size == fsi_.size) { + auto file_size = nf_->size(); + if (not file_size.has_value()) { + utils::error::raise_api_path_error( + function_name, fsi_.api_path, fsi_.source_path, + utils::get_last_error_code(), "failed to get file size"); + return set_api_error(api_error::os_error); + } + + if (file_size.value() == fsi_.size) { allocated = true; return api_error::success; } file_lock.unlock(); - if (file_size > fsi_.size) { - auto res = cache_size_mgr::instance().shrink(file_size - fsi_.size); - if (res != api_error::success) { - return res; - } - } else if (file_size < fsi_.size) { - auto res = cache_size_mgr::instance().expand(fsi_.size - file_size); - if (res != api_error::success) { - return res; - } + res = adjust_cache_size(file_size.value(), true); + if (res != api_error::success) { + return res; } file_lock.lock(); if (not nf_->truncate(fsi_.size)) { - return api_error::os_error; + utils::error::raise_api_path_error( + function_name, fsi_.api_path, fsi_.source_path, + utils::get_last_error_code(), + fmt::format("failed to truncate file|size|{}", fsi_.size)); + return set_api_error(res); } allocated = true; @@ -359,7 +415,7 @@ auto open_file::is_download_complete() const -> bool { auto open_file::native_operation( i_open_file::native_operation_callback callback) -> api_error { if (stop_requested_) { - return api_error::download_stopped; + return set_api_error(api_error::download_stopped); } auto res = check_allocation(); @@ -377,11 +433,11 @@ auto open_file::native_operation( REPERTORY_USES_FUNCTION_NAME(); if (fsi_.directory) { - return api_error::invalid_operation; + return set_api_error(api_error::invalid_operation); } if (stop_requested_) { - return api_error::download_stopped; + return set_api_error(api_error::download_stopped); } auto res = check_allocation(); @@ -389,16 +445,9 @@ auto open_file::native_operation( return res; } - if (new_file_size > fsi_.size) { - res = cache_size_mgr::instance().expand(new_file_size - fsi_.size); - if (res != api_error::success) { - return res; - } - } else if (new_file_size < fsi_.size) { - res = cache_size_mgr::instance().shrink(fsi_.size - new_file_size); - if (res != api_error::success) { - return res; - } + res = adjust_cache_size(new_file_size, false); + if (res != api_error::success) { + return res; } auto is_empty_file = new_file_size == 0U; @@ -433,13 +482,20 @@ auto open_file::native_operation( } { - auto file_size = nf_->size().value_or(0U); - if (file_size != new_file_size) { + auto file_size = nf_->size(); + if (not file_size.has_value()) { utils::error::raise_api_path_error( function_name, get_api_path(), api_error::file_size_mismatch, - "allocated file size mismatch|expected|" + - std::to_string(new_file_size) + "|actual|" + - std::to_string(file_size)); + fmt::format("failed to get file size|error|{}", + utils::get_last_error_code())); + return set_api_error(api_error::error); + } + + if (file_size.value() != new_file_size) { + utils::error::raise_api_path_error( + function_name, get_api_path(), api_error::file_size_mismatch, + fmt::format("file size mismatch|expected|{}|actual|{}", new_file_size, + file_size.value())); return set_api_error(api_error::error); } } @@ -487,7 +543,7 @@ auto open_file::native_operation( 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; + return set_api_error(api_error::invalid_operation); } auto res = check_allocation(); @@ -567,7 +623,7 @@ void open_file::remove_all() { auto open_file::resize(std::uint64_t new_file_size) -> api_error { if (fsi_.directory) { - return api_error::invalid_operation; + return set_api_error(api_error::invalid_operation); } if (new_file_size == fsi_.size) { @@ -648,7 +704,7 @@ auto open_file::write(std::uint64_t write_offset, const data_buffer &data, bytes_written = 0U; if (fsi_.directory || provider_.is_read_only()) { - return api_error::invalid_operation; + return set_api_error(api_error::invalid_operation); } if (data.empty()) { @@ -656,7 +712,7 @@ auto open_file::write(std::uint64_t write_offset, const data_buffer &data, } if (stop_requested_) { - return api_error::download_stopped; + return set_api_error(api_error::download_stopped); } auto res = check_allocation();