inline bool at_end() const {
return cursor == end;
}
+ // add the next unique candidate, or return false if we reach the end
+ bool next_candidate(std::map<std::string, size_t>& candidates,
+ size_t tracker_idx) {
+ while (!at_end()) {
+ if (candidates.emplace(entry_name(), tracker_idx).second) {
+ return true;
+ }
+ advance(); // skip duplicate common prefixes
+ }
+ return false;
+ }
}; // ShardTracker
// one tracker per shard requested (may not be all shards)
map<string, size_t> candidates;
size_t tracker_idx = 0;
for (auto& t : results_trackers) {
- if (!t.at_end()) {
- // it's important that the values in the map refer to the index
- // into the results_trackers vector, which may not be the same
- // as the shard number (i.e., when not all shards are requested)
- if (!candidates.emplace(t.entry_name(), tracker_idx).second) {
- t.advance(); // skip duplicate common prefixes
- }
- }
+ // it's important that the values in the map refer to the index
+ // into the results_trackers vector, which may not be the same
+ // as the shard number (i.e., when not all shards are requested)
+ t.next_candidate(candidates, tracker_idx);
++tracker_idx;
}
// refresh the candidates map
candidates.erase(candidates.begin());
- if (! tracker.advance().at_end()) {
- if (!candidates.emplace(tracker.entry_name(), tracker_idx).second) {
- tracker.advance(); // skip duplicate common prefixes
- }
+ tracker.advance();
+ if (tracker.next_candidate(candidates, tracker_idx)) {
+ // we got a candidate, so we're not at the end yet
} else if (tracker.is_truncated()) {
// once we exhaust one shard that is truncated, we need to stop,
// as we cannot be certain that one of the next entries needs to