refactor unlink'd behavior to always work with handles

This commit is contained in:
2025-09-25 13:52:44 -05:00
parent b58314c6d3
commit 94a04cd718
2 changed files with 26 additions and 41 deletions

View File

@@ -61,14 +61,14 @@ private:
i_provider &provider_;
private:
std::unordered_map<std::string, std::shared_ptr<i_closeable_open_file>>
closed_file_lookup_;
std::unique_ptr<i_file_mgr_db> mgr_db_;
std::atomic<std::uint64_t> next_handle_{0U};
mutable std::recursive_mutex open_file_mtx_;
std::unordered_map<std::string, std::shared_ptr<i_closeable_open_file>>
open_file_lookup_;
stop_type stop_requested_{false};
std::unordered_map<std::uint64_t, std::shared_ptr<i_closeable_open_file>>
unlinked_file_lookup_;
std::unordered_map<std::string, std::unique_ptr<upload>> upload_lookup_;
mutable std::mutex upload_mtx_;
std::condition_variable upload_notify_;
@@ -78,7 +78,7 @@ private:
void close_timed_out_files();
[[nodiscard]] auto get_open_file_by_handle(std::uint64_t handle,
bool &is_closed) const
bool &is_unlinked) const
-> std::shared_ptr<i_closeable_open_file>;
[[nodiscard]] auto get_open_file_count(const std::string &api_path) const

View File

@@ -80,8 +80,8 @@ void file_manager::close(std::uint64_t handle) {
REPERTORY_USES_FUNCTION_NAME();
unique_recur_mutex_lock file_lock(open_file_mtx_);
bool is_closed{};
auto closeable_file = get_open_file_by_handle(handle, is_closed);
bool is_unlinked{};
auto closeable_file = get_open_file_by_handle(handle, is_unlinked);
if (not closeable_file) {
return;
}
@@ -90,11 +90,13 @@ void file_manager::close(std::uint64_t handle) {
closeable_file->remove(handle);
file_lock.lock();
if (not is_closed || closeable_file->get_open_file_count() != 0U) {
return;
if (is_unlinked) {
unlinked_file_lookup_.erase(handle);
}
closed_file_lookup_.erase(closeable_file->get_api_path());
if (not is_unlinked || closeable_file->get_open_file_count() != 0U) {
return;
}
file_lock.unlock();
closeable_file->close();
@@ -310,22 +312,16 @@ auto file_manager::get_next_handle() -> std::uint64_t {
}
auto file_manager::get_open_file_by_handle(std::uint64_t handle,
bool &is_closed) const
bool &is_unlinked) const
-> std::shared_ptr<i_closeable_open_file> {
REPERTORY_USES_FUNCTION_NAME();
{
auto file_iter = std::ranges::find_if(
closed_file_lookup_, [&handle](auto &&item) -> bool {
return item.second->has_handle(handle);
});
if (file_iter != closed_file_lookup_.end()) {
is_closed = true;
return file_iter->second;
}
if (unlinked_file_lookup_.contains(handle)) {
is_unlinked = true;
unlinked_file_lookup_.at(handle);
}
is_closed = false;
is_unlinked = false;
auto file_iter =
std::ranges::find_if(open_file_lookup_, [&handle](auto &&item) -> bool {
return item.second->has_handle(handle);
@@ -349,11 +345,6 @@ auto file_manager::get_open_file(const std::string &api_path,
return true;
}
if (closed_file_lookup_.contains(api_path)) {
file = closed_file_lookup_.at(api_path);
return true;
}
return false;
}
@@ -366,8 +357,8 @@ auto file_manager::get_open_file(std::uint64_t handle, bool write_supported,
}
unique_recur_mutex_lock open_lock(open_file_mtx_);
bool is_closed{};
auto file_ptr = get_open_file_by_handle(handle, is_closed);
bool is_unlinked{};
auto file_ptr = get_open_file_by_handle(handle, is_unlinked);
if (not file_ptr) {
return false;
}
@@ -380,10 +371,12 @@ auto file_manager::get_open_file(std::uint64_t handle, bool write_supported,
: 0U,
file_ptr->get_filesystem_item(), file_ptr->get_open_data(), provider_,
*this);
writeable_file->set_unlinked(is_closed);
if (is_closed) {
writeable_file->set_unlinked(is_unlinked);
if (is_unlinked) {
writeable_file->set_unlinked_meta(file_ptr->get_unlinked_meta());
closed_file_lookup_[file_ptr->get_api_path()] = writeable_file;
for (const auto &[handle, ofd] : writeable_file->get_open_data()) {
unlinked_file_lookup_[handle] = writeable_file;
}
} else {
open_file_lookup_[file_ptr->get_api_path()] = writeable_file;
}
@@ -730,23 +723,15 @@ auto file_manager::remove_file(const std::string &api_path) -> api_error {
return api_error::success;
}
if (closed_file_lookup_.contains(api_path)) {
auto closed_file = closed_file_lookup_.at(api_path);
closed_file_lookup_[api_path] = file_iter->second;
for (auto &[handle, ofd] : closed_file->get_open_data()) {
closed_file_lookup_.at(api_path)->add(handle, ofd, false);
}
} else {
closed_file_lookup_[api_path] = file_iter->second;
}
auto closed_file = file_iter->second;
open_file_lookup_.erase(api_path);
auto closed_file = closed_file_lookup_.at(api_path);
auto allocated = closed_file->get_allocated();
closed_file->set_unlinked(true);
closed_file->set_unlinked_meta(meta);
for (const auto &[handle, ofd] : closed_file->get_open_data()) {
unlinked_file_lookup_[handle] = closed_file;
}
open_lock.unlock();
if (not allocated) {