allocate after open
This commit is contained in:
@ -34,7 +34,7 @@ public:
|
||||
private:
|
||||
struct open_directory final {
|
||||
std::shared_ptr<directory_iterator> iterator;
|
||||
std::vector<std::uint64_t> handles{};
|
||||
std::vector<std::uint64_t> 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<directory_iterator>;
|
||||
[[nodiscard]] auto get_directory(std::uint64_t handle)
|
||||
-> std::shared_ptr<directory_iterator>;
|
||||
|
||||
[[nodiscard]] auto remove_directory(const std::string &api_path)
|
||||
-> std::shared_ptr<directory_iterator>;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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<max_cache_size_reached>(cache_size_,
|
||||
max_cache_size);
|
||||
if (not should_wait) {
|
||||
break;
|
||||
}
|
||||
|
||||
notify_.wait(lock);
|
||||
}
|
||||
|
||||
|
@ -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<std::size_t>(write_offset / chunk_size_);
|
||||
auto end_chunk =
|
||||
static_cast<std::size_t>((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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Reference in New Issue
Block a user