Merge pull request #17820 from zmedico/PGPool-update-optimize-with-subset-of

osd/PGPool::update: optimize with subset_of

Reviewed-by: Gregory Farnum <gfarnum@redhat.com>
Reviewed-by: Kefu Chai <kchai@redhat.com>
This commit is contained in:
Yuri Weinstein 2017-09-28 15:53:29 -07:00 committed by GitHub
commit 488c6e4e3f
3 changed files with 82 additions and 6 deletions

View File

@ -286,6 +286,38 @@ class interval_set {
}
}
}
bool subset_size_sym(const interval_set &b) const {
auto pa = m.cbegin(), pb = b.m.cbegin();
const auto a_end = m.cend(), b_end = b.m.cend();
while (pa != a_end && pb != b_end) {
while (pb->first + pb->second <= pa->first) {
++pb;
if (pb == b_end)
return false;
}
if (*pa == *pb) {
do {
++pa;
++pb;
} while (pa != a_end && pb != b_end && *pa == *pb);
continue;
}
// interval begins before other
if (pa->first < pb->first)
return false;
// interval is longer than other
if (pa->first + pa->second > pb->first + pb->second)
return false;
++pa;
}
return pa == a_end;
}
public:
bool operator==(const interval_set& other) const {
@ -606,6 +638,21 @@ class interval_set {
}
bool subset_of(const interval_set &big) const {
if (!size())
return true;
if (size() > big.size())
return false;
if (range_end() > big.range_end())
return false;
/*
* Use the lower_bound algorithm for larger size ratios
* where it performs better, but not for smaller size
* ratios where sequential search performs better.
*/
if (big.size() / size() < 10)
return subset_size_sym(big);
for (typename std::map<T,T>::const_iterator i = m.begin();
i != m.end();
i++)

View File

@ -237,12 +237,10 @@ void PGPool::update(OSDMapRef map)
updated = true;
if (pi->maybe_updated_removed_snaps(cached_removed_snaps)) {
pi->build_removed_snaps(newly_removed_snaps);
interval_set<snapid_t> intersection;
intersection.intersection_of(newly_removed_snaps, cached_removed_snaps);
if (intersection == cached_removed_snaps) {
cached_removed_snaps.swap(newly_removed_snaps);
newly_removed_snaps = cached_removed_snaps;
newly_removed_snaps.subtract(intersection);
if (cached_removed_snaps.subset_of(newly_removed_snaps)) {
interval_set<snapid_t> removed_snaps = newly_removed_snaps;
newly_removed_snaps.subtract(cached_removed_snaps);
cached_removed_snaps.swap(removed_snaps);
} else {
lgeneric_subdout(cct, osd, 0) << __func__
<< " cached_removed_snaps shrank from " << cached_removed_snaps

View File

@ -526,6 +526,37 @@ TYPED_TEST(IntervalSetTest, subset_of) {
iset1.insert( 24, 1);
ASSERT_FALSE(iset1.subset_of(iset2));
iset2.insert( 24, 1);
ASSERT_TRUE(iset1.subset_of(iset2));
iset1.insert( 30, 5);
ASSERT_FALSE(iset1.subset_of(iset2));
iset2.insert( 30, 5);
ASSERT_TRUE(iset1.subset_of(iset2));
iset2.erase( 30, 1);
ASSERT_FALSE(iset1.subset_of(iset2));
iset1.erase( 30, 1);
ASSERT_TRUE(iset1.subset_of(iset2));
iset2.erase( 34, 1);
ASSERT_FALSE(iset1.subset_of(iset2));
iset1.erase( 34, 1);
ASSERT_TRUE(iset1.subset_of(iset2));
iset1.insert( 40, 5);
ASSERT_FALSE(iset1.subset_of(iset2));
iset2.insert( 39, 7);
ASSERT_TRUE(iset1.subset_of(iset2));
iset1.insert( 50, 5);
iset2.insert( 55, 2);
ASSERT_FALSE(iset1.subset_of(iset2));
}
TYPED_TEST(IntervalSetTest, span_of) {