diff --git a/repertory/librepertory/include/drives/directory_cache.hpp b/repertory/librepertory/include/drives/directory_cache.hpp index ba2d88bd..706a64fc 100644 --- a/repertory/librepertory/include/drives/directory_cache.hpp +++ b/repertory/librepertory/include/drives/directory_cache.hpp @@ -34,7 +34,7 @@ public: private: struct open_directory final { std::shared_ptr iterator; - std::vector handles{}; + std::vector handles; std::chrono::system_clock::time_point last_update{ std::chrono::system_clock::now()}; }; @@ -60,8 +60,8 @@ public: void execute_action(const std::string &api_path, const execute_callback &execute); - [[nodiscard]] auto - get_directory(std::uint64_t handle) -> std::shared_ptr; + [[nodiscard]] auto get_directory(std::uint64_t handle) + -> std::shared_ptr; [[nodiscard]] auto remove_directory(const std::string &api_path) -> std::shared_ptr; diff --git a/repertory/librepertory/include/file_manager/cache_size_mgr.hpp b/repertory/librepertory/include/file_manager/cache_size_mgr.hpp index 89bbf957..c1395404 100644 --- a/repertory/librepertory/include/file_manager/cache_size_mgr.hpp +++ b/repertory/librepertory/include/file_manager/cache_size_mgr.hpp @@ -50,7 +50,7 @@ private: stop_type stop_requested_{false}; public: - [[nodiscard]] auto expand(std::uint64_t size, bool should_wait) -> api_error; + [[nodiscard]] auto expand(std::uint64_t size) -> api_error; void initialize(app_config *cfg); diff --git a/repertory/librepertory/include/file_manager/open_file.hpp b/repertory/librepertory/include/file_manager/open_file.hpp index 48ef1475..b317424b 100644 --- a/repertory/librepertory/include/file_manager/open_file.hpp +++ b/repertory/librepertory/include/file_manager/open_file.hpp @@ -67,6 +67,7 @@ private: i_upload_manager &mgr_; private: + bool allocated{false}; bool notified_{false}; std::size_t read_chunk_{}; boost::dynamic_bitset<> read_state_; @@ -76,6 +77,8 @@ private: stop_type stop_requested_{false}; private: + [[nodiscard]] auto check_allocation() -> api_error; + void download_chunk(std::size_t chunk, bool skip_active, bool should_reset); void download_range(std::size_t begin_chunk, std::size_t end_chunk, diff --git a/repertory/librepertory/src/drives/eviction.cpp b/repertory/librepertory/src/drives/eviction.cpp index 1d14397a..b93b8525 100644 --- a/repertory/librepertory/src/drives/eviction.cpp +++ b/repertory/librepertory/src/drives/eviction.cpp @@ -76,10 +76,8 @@ void eviction::service_function() { try { std::string api_path; - fmt::println("path|{}", file_path); auto res = provider_.get_api_path_from_source(file_path, api_path); if (res != api_error::success) { - fmt::println("not found|{}", api_error_to_string(res)); continue; } diff --git a/repertory/librepertory/src/file_manager/cache_size_mgr.cpp b/repertory/librepertory/src/file_manager/cache_size_mgr.cpp index 1cc02c40..32d80059 100644 --- a/repertory/librepertory/src/file_manager/cache_size_mgr.cpp +++ b/repertory/librepertory/src/file_manager/cache_size_mgr.cpp @@ -42,7 +42,7 @@ E_SIMPLE2(max_cache_size_reached, warn, true, cache_size_mgr cache_size_mgr::instance_{}; -auto cache_size_mgr::expand(std::uint64_t size, bool should_wait) -> api_error { +auto cache_size_mgr::expand(std::uint64_t size) -> api_error { if (size == 0U) { return api_error::success; } @@ -61,10 +61,6 @@ auto cache_size_mgr::expand(std::uint64_t size, bool should_wait) -> api_error { cache_dir.count() > 1U) { event_system::instance().raise(cache_size_, max_cache_size); - if (not should_wait) { - break; - } - notify_.wait(lock); } diff --git a/repertory/librepertory/src/file_manager/open_file.cpp b/repertory/librepertory/src/file_manager/open_file.cpp index 61a73f88..fc4a75f7 100644 --- a/repertory/librepertory/src/file_manager/open_file.cpp +++ b/repertory/librepertory/src/file_manager/open_file.cpp @@ -94,15 +94,7 @@ open_file::open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout, 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); - } else if (nf_->truncate(fsi.size)) { - if (file_size > fsi.size) { - set_api_error(cache_size_mgr::instance().shrink(file_size - fsi.size)); - } else { - set_api_error( - cache_size_mgr::instance().expand(fsi.size - file_size, false)); - } - } else { - set_api_error(api_error::os_error); + allocated = true; } } @@ -113,6 +105,34 @@ open_file::open_file(std::uint64_t chunk_size, std::uint8_t chunk_timeout, open_file::~open_file() { close(); } +auto open_file::check_allocation() -> api_error { + unique_recur_mutex_lock file_lock(file_mtx_); + if (allocated) { + return api_error::success; + } + + allocated = true; + if (fsi_.size == 0U) { + return api_error::success; + } + + auto file_size = nf_->size().value_or(0U); + if (file_size == fsi_.size) { + return api_error::success; + } + + if (not nf_->truncate(fsi_.size)) { + return api_error::os_error; + } + file_lock.unlock(); + + if (file_size > fsi_.size) { + return cache_size_mgr::instance().shrink(file_size - fsi_.size); + } + + return cache_size_mgr::instance().expand(fsi_.size - file_size); +} + auto open_file::close() -> bool { REPERTORY_USES_FUNCTION_NAME(); @@ -341,6 +361,11 @@ auto open_file::native_operation( return api_error::download_stopped; } + auto res = check_allocation(); + if (res != api_error::success) { + return res; + } + unique_recur_mutex_lock rw_lock(rw_mtx_); return do_io([&]() -> api_error { return callback(nf_->get_handle()); }); } @@ -358,14 +383,18 @@ auto open_file::native_operation( return api_error::download_stopped; } + auto res = check_allocation(); + if (res != api_error::success) { + return res; + } + if (new_file_size > fsi_.size) { - auto res = - cache_size_mgr::instance().expand(new_file_size - fsi_.size, true); + res = cache_size_mgr::instance().expand(new_file_size - fsi_.size, true); if (res != api_error::success) { return res; } } else if (new_file_size < fsi_.size) { - auto res = cache_size_mgr::instance().shrink(fsi_.size - new_file_size); + res = cache_size_mgr::instance().shrink(fsi_.size - new_file_size); if (res != api_error::success) { return res; } @@ -394,7 +423,7 @@ auto open_file::native_operation( read_state = get_read_state(); auto original_file_size = get_file_size(); - auto res = do_io([&]() -> api_error { return callback(nf_->get_handle()); }); + res = do_io([&]() -> api_error { return callback(nf_->get_handle()); }); if (res != api_error::success) { utils::error::raise_api_path_error(function_name, get_api_path(), utils::get_last_error_code(), @@ -460,6 +489,11 @@ auto open_file::read(std::size_t read_size, std::uint64_t read_offset, return api_error::invalid_operation; } + auto res = check_allocation(); + if (res != api_error::success) { + return res; + } + read_size = utils::calculate_read_size(get_file_size(), read_size, read_offset); if (read_size == 0U) { @@ -624,6 +658,11 @@ auto open_file::write(std::uint64_t write_offset, const data_buffer &data, return api_error::download_stopped; } + auto res = check_allocation(); + if (res != api_error::success) { + return res; + } + auto begin_chunk = static_cast(write_offset / chunk_size_); auto end_chunk = static_cast((write_offset + data.size()) / chunk_size_); @@ -638,13 +677,13 @@ auto open_file::write(std::uint64_t write_offset, const data_buffer &data, unique_recur_mutex_lock rw_lock(rw_mtx_); if ((write_offset + data.size()) > fsi_.size) { - auto res = resize(write_offset + data.size()); + res = resize(write_offset + data.size()); if (res != api_error::success) { return res; } } - auto res = do_io([&]() -> api_error { + res = do_io([&]() -> api_error { if (not nf_->write(data, write_offset, &bytes_written)) { return api_error::os_error; } diff --git a/repertory/repertory_test/src/open_file_test.cpp b/repertory/repertory_test/src/open_file_test.cpp index f99a5efc..5d2d9e42 100644 --- a/repertory/repertory_test/src/open_file_test.cpp +++ b/repertory/repertory_test/src/open_file_test.cpp @@ -494,8 +494,7 @@ TEST_F(open_file_test, resize_file_to_0_bytes) { fsi.size = test_chunk_size * 4U; fsi.source_path = source_path; - EXPECT_EQ(api_error::success, - cache_size_mgr::instance().expand(fsi.size, false)); + EXPECT_EQ(api_error::success, cache_size_mgr::instance().expand(fsi.size)); open_file file(test_chunk_size, 0U, fsi, provider, upload_mgr); test_closeable_open_file(file, false, api_error::success, fsi.size, @@ -548,8 +547,7 @@ TEST_F(open_file_test, resize_file_by_full_chunk) { fsi.size = test_chunk_size * 4U; fsi.source_path = source_path; - EXPECT_EQ(api_error::success, - cache_size_mgr::instance().expand(fsi.size, false)); + EXPECT_EQ(api_error::success, cache_size_mgr::instance().expand(fsi.size)); EXPECT_CALL(upload_mgr, store_resume) .WillOnce([&fsi](const i_open_file &file) {