From: Zac Medico Date: Thu, 31 Aug 2017 20:36:30 +0000 (-0700) Subject: PGPool::update: optimize removed_snaps comparison when possible X-Git-Tag: v12.2.9~118^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e9ee4dd99697001091872c765f34100b70c9e0f6;p=ceph.git PGPool::update: optimize removed_snaps comparison when possible In self/unmanaged snaps mode, optimize removed_snaps comparison for cases where removed_snaps has not changed. This exploits the fact that remove_unmanaged_snap adds a dummy removed snapshot to the end of removed_snaps, allowing for inexpensive detection of changes. In cases where removed_snaps is very large, this optimization improves performance dramatically. Signed-off-by: Zac Medico (cherry picked from commit caf6803b13d9dbd4540da366b018d721fcfc371a) --- diff --git a/src/osd/PG.cc b/src/osd/PG.cc index 1e32d202dae4..4da64a3a0b39 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -237,20 +237,23 @@ void PGPool::update(OSDMapRef map) if ((map->get_epoch() != cached_epoch + 1) || (pi->get_snap_epoch() == map->get_epoch())) { updated = true; - pi->build_removed_snaps(newly_removed_snaps); - interval_set 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); - } else { - lgeneric_subdout(cct, osd, 0) << __func__ - << " cached_removed_snaps shrank from " << cached_removed_snaps - << " to " << newly_removed_snaps << dendl; - cached_removed_snaps.swap(newly_removed_snaps); - newly_removed_snaps.clear(); - } + if (pi->maybe_updated_removed_snaps(cached_removed_snaps)) { + pi->build_removed_snaps(newly_removed_snaps); + interval_set 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); + } else { + lgeneric_subdout(cct, osd, 0) << __func__ + << " cached_removed_snaps shrank from " << cached_removed_snaps + << " to " << newly_removed_snaps << dendl; + cached_removed_snaps.swap(newly_removed_snaps); + newly_removed_snaps.clear(); + } + } else + newly_removed_snaps.clear(); snapc = pi->get_snap_context(); } else { /* 1) map->get_epoch() == cached_epoch + 1 && diff --git a/src/osd/osd_types.cc b/src/osd/osd_types.cc index 5fb226221d12..194b020ff206 100644 --- a/src/osd/osd_types.cc +++ b/src/osd/osd_types.cc @@ -1312,6 +1312,16 @@ void pg_pool_t::build_removed_snaps(interval_set& rs) const } } +bool pg_pool_t::maybe_updated_removed_snaps(const interval_set& cached) const +{ + if (is_unmanaged_snaps_mode()) { // remove_unmanaged_snap increments range_end + if (removed_snaps.empty() || cached.empty()) // range_end is undefined + return removed_snaps.empty() != cached.empty(); + return removed_snaps.range_end() != cached.range_end(); + } + return true; +} + snapid_t pg_pool_t::snap_exists(const char *s) const { for (map::const_iterator p = snaps.begin(); diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h index 254e7b4264f4..58cdfdefbd13 100644 --- a/src/osd/osd_types.h +++ b/src/osd/osd_types.h @@ -1567,6 +1567,7 @@ public: * explicit removed_snaps set. */ void build_removed_snaps(interval_set& rs) const; + bool maybe_updated_removed_snaps(const interval_set& cached) const; snapid_t snap_exists(const char *s) const; void add_snap(const char *n, utime_t stamp); void add_unmanaged_snap(uint64_t& snapid);