sstables: rewrite compound_sstable_set::all()

Procedure is rewritten using std::partition, making it easier to
maintain and it also fixes a theoretical quadratic behavior because
list is entirely copied when extending it, which isn't harmful
because maintenance set will be rarely populated and there are only
2 sets at most.

Signed-off-by: Raphael S. Carvalho <raphaelsc@scylladb.com>
Message-Id: <20210409171412.57729-1-raphaelsc@scylladb.com>
This commit is contained in:
Raphael S. Carvalho
2021-04-09 14:14:12 -03:00
committed by Avi Kivity
parent d77eb39076
commit 224120f7df

View File

@@ -871,21 +871,24 @@ std::vector<sstable_run> compound_sstable_set::select_sstable_runs(const std::ve
}
lw_shared_ptr<sstable_list> compound_sstable_set::all() const {
auto sets = _sets;
auto it = std::partition(sets.begin(), sets.end(), [] (const auto& set) { return set->all()->size() > 0; });
auto non_empty_set_count = std::distance(sets.begin(), it);
if (!non_empty_set_count) {
return make_lw_shared<sstable_list>();
}
// optimize for common case where primary set contains sstables, but secondary one is empty for most of the time.
if (non_empty_set_count == 1) {
const auto& non_empty_set = *std::begin(sets);
return non_empty_set->all();
}
auto ret = make_lw_shared<sstable_list>();
for (auto& set : _sets) {
for (auto& set : boost::make_iterator_range(sets.begin(), it)) {
auto ssts = set->all();
if (ssts->empty()) {
continue;
}
// optimize for common case where primary set contains sstables, but secondary one is empty for most of the time.
if (ret->empty()) {
ret = std::move(ssts);
} else {
// copy list if we need to extend it as a list referenced by a sstable_set cannot be modified.
ret = make_lw_shared<sstable_list>(*ret);
ret->reserve(ret->size() + ssts->size());
ret->insert(ssts->begin(), ssts->end());
}
ret->reserve(ret->size() + ssts->size());
ret->insert(ssts->begin(), ssts->end());
}
return ret;
}