Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion include/miniocpp/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,27 @@ class ListObjectsResult {
bool failed_ = false;
ListObjectsResponse resp_;
std::list<Item>::iterator itr_;
std::shared_ptr<std::future<ListObjectsResponse>> prefetch_future_;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

void Populate();
void StartPrefetch();
void UpdatePaginationArgs();

public:
explicit ListObjectsResult(error::Error err);
ListObjectsResult(Client* const client, const ListObjectsArgs& args);
ListObjectsResult(Client* const client, ListObjectsArgs&& args);
~ListObjectsResult() = default;
ListObjectsResult(const ListObjectsResult&) = default;
ListObjectsResult& operator=(const ListObjectsResult&) = default;
ListObjectsResult(ListObjectsResult&&) = default;
ListObjectsResult& operator=(ListObjectsResult&&) = default;

Item& operator*() const { return *itr_; }
explicit operator bool() const { return itr_ != resp_.contents.end(); }
explicit operator bool() {
if (prefetch_future_ && resp_.contents.empty()) Populate();
return itr_ != resp_.contents.end();
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}

ListObjectsResult& operator++() {
itr_++;
Expand Down
4 changes: 4 additions & 0 deletions include/miniocpp/response.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,10 @@ struct ListObjectsResponse : public Response {
std::string_view next_version_id_marker;

ListObjectsResponse() = default;
ListObjectsResponse(const ListObjectsResponse&) = default;
ListObjectsResponse& operator=(const ListObjectsResponse&) = default;
ListObjectsResponse(ListObjectsResponse&&) = default;
ListObjectsResponse& operator=(ListObjectsResponse&&) = default;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

explicit ListObjectsResponse(error::Error err) : Response(std::move(err)) {}

Expand Down
75 changes: 49 additions & 26 deletions src/client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -141,16 +141,16 @@ ListObjectsResult::ListObjectsResult(error::Error err) : failed_(true) {
ListObjectsResult::ListObjectsResult(Client* const client,
const ListObjectsArgs& args)
: client_(client), args_(args) {
Populate();
StartPrefetch();
}

ListObjectsResult::ListObjectsResult(Client* const client,
ListObjectsArgs&& args)
: client_(client), args_(std::move(args)) {
Populate();
StartPrefetch();
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

void ListObjectsResult::Populate() {
void ListObjectsResult::UpdatePaginationArgs() {
if (args_.include_versions) {
args_.key_marker = resp_.next_key_marker;
args_.version_id_marker = resp_.next_version_id_marker;
Expand All @@ -160,34 +160,57 @@ void ListObjectsResult::Populate() {
args_.start_after = resp_.start_after;
args_.continuation_token = resp_.next_continuation_token;
}
}

std::string region;
if (GetRegionResponse resp = client_->GetRegion(args_.bucket, args_.region)) {
region = resp.region;
if (args_.recursive) {
args_.delimiter = "";
} else if (args_.delimiter.empty()) {
args_.delimiter = "/";
}

if (args_.include_versions || !args_.version_id_marker.empty()) {
resp_ = client_->ListObjectVersions(ListObjectVersionsArgs(args_));
} else if (args_.use_api_v1) {
resp_ = client_->ListObjectsV1(ListObjectsV1Args(args_));
} else {
resp_ = client_->ListObjectsV2(ListObjectsV2Args(args_));
}
void ListObjectsResult::StartPrefetch() {
ListObjectsArgs next_args = args_;
prefetch_future_ =
std::make_shared<std::future<ListObjectsResponse>>(std::async(
std::launch::async,
[this, next_args = std::move(next_args)]() mutable {
std::string region;
if (GetRegionResponse resp =
client_->GetRegion(next_args.bucket, next_args.region)) {
region = resp.region;
if (next_args.recursive) {
next_args.delimiter = "";
} else if (next_args.delimiter.empty()) {
next_args.delimiter = "/";
}

if (next_args.include_versions ||
!next_args.version_id_marker.empty()) {
return client_->ListObjectVersions(
ListObjectVersionsArgs(next_args));
} else if (next_args.use_api_v1) {
return client_->ListObjectsV1(ListObjectsV1Args(next_args));
} else {
return client_->ListObjectsV2(ListObjectsV2Args(next_args));
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}
}
return ListObjectsResponse(
error::make<ListObjectsResponse>("unable to get region"));
}));
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}

if (!resp_) {
failed_ = true;
resp_.contents.push_back(Item(resp_));
}
} else {
void ListObjectsResult::Populate() {
// Always consume from the prefetch future.
if (!prefetch_future_ || !prefetch_future_->valid()) {
return;
}
resp_ = prefetch_future_->get();
prefetch_future_.reset();
if (!resp_) {
failed_ = true;
resp_.contents.push_back(Item(resp));
resp_.contents.push_back(Item(resp_));
}

itr_ = resp_.contents.begin();

// Start next prefetch if there are more pages.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
if (resp_ && resp_.is_truncated) {
UpdatePaginationArgs();
StartPrefetch();
}
}

RemoveObjectsResult::RemoveObjectsResult(error::Error err) {
Expand Down
Loading