mirror of
https://github.com/ceph/ceph
synced 2025-02-22 18:47:18 +00:00
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:
commit
488c6e4e3f
@ -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++)
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user