From f4c319b94cd4b6c0d39358b3fe9a06fca0b0a31f Mon Sep 17 00:00:00 2001 From: Greg Lange Date: Tue, 5 Jun 2012 21:32:25 +0000 Subject: [PATCH] Made dispersion report work with any replica count other than 3. This changes the JSON output keys missing_one and missing_two to missing_1 and missing_2 (if there are at least 2 replicas), drops the missing_all key, and can add more missing_x keys depending on the replica count. We will definitely need to post a prominent notice of this change with the next release. bug 862816 Change-Id: Ib747d944476638c33ee1d876b8f9db28953826e2 --- bin/swift-dispersion-report | 93 +++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 36 deletions(-) diff --git a/bin/swift-dispersion-report b/bin/swift-dispersion-report index 2800658332..4ff4468226 100755 --- a/bin/swift-dispersion-report +++ b/bin/swift-dispersion-report @@ -78,7 +78,7 @@ def container_dispersion_report(coropool, connpool, account, container_ring, return retries_done = [0] containers_queried = [0] - container_copies_found = [0, 0, 0, 0] + container_copies_found = [0] * (container_ring.replica_count + 1) begun = time() next_report = [time() + 2] @@ -130,15 +130,11 @@ def container_dispersion_report(coropool, connpool, account, container_ring, if containers_listed - distinct_partitions: print 'There were %d overlapping partitions' % ( containers_listed - distinct_partitions) - if container_copies_found[2]: - print 'There were %d partitions missing one copy.' % \ - container_copies_found[2] - if container_copies_found[1]: - print '! There were %d partitions missing two copies.' % \ - container_copies_found[1] - if container_copies_found[0]: - print '!!! There were %d partitions missing all copies.' % \ - container_copies_found[0] + for copies in xrange(container_ring.replica_count - 1, -1, -1): + missing_copies = container_ring.replica_count - copies + if container_copies_found[copies]: + print missing_string(container_copies_found[copies], + missing_copies, container_ring.replica_count) print '%.02f%% of container copies found (%d of %d)' % ( value, copies_found, copies_expected) print 'Sample represents %.02f%% of the container partition space' % ( @@ -146,14 +142,16 @@ def container_dispersion_report(coropool, connpool, account, container_ring, stdout.flush() return None else: - return {'retries': retries_done[0], - 'overlapping': containers_listed - distinct_partitions, - 'missing_one': container_copies_found[2], - 'missing_two': container_copies_found[1], - 'missing_all': container_copies_found[0], - 'pct_found': value, - 'copies_found': copies_found, - 'copies_expected': copies_expected} + results = {'retries': retries_done[0], + 'overlapping': containers_listed - distinct_partitions, + 'pct_found': value, + 'copies_found': copies_found, + 'copies_expected': copies_expected} + for copies in xrange(container_ring.replica_count): + missing_copies = container_ring.replica_count - copies + results['missing_%d' % (missing_copies)] = \ + container_copies_found[copies] + return results def object_dispersion_report(coropool, connpool, account, object_ring, @@ -178,7 +176,7 @@ def object_dispersion_report(coropool, connpool, account, object_ring, return retries_done = [0] objects_queried = [0] - object_copies_found = [0, 0, 0, 0] + object_copies_found = [0] * (object_ring.replica_count + 1) begun = time() next_report = [time() + 2] @@ -230,15 +228,11 @@ def object_dispersion_report(coropool, connpool, account, object_ring, if objects_listed - distinct_partitions: print 'There were %d overlapping partitions' % ( objects_listed - distinct_partitions) - if object_copies_found[2]: - print 'There were %d partitions missing one copy.' % \ - object_copies_found[2] - if object_copies_found[1]: - print '! There were %d partitions missing two copies.' % \ - object_copies_found[1] - if object_copies_found[0]: - print '!!! There were %d partitions missing all copies.' % \ - object_copies_found[0] + for copies in xrange(object_ring.replica_count - 1, -1, -1): + missing_copies = object_ring.replica_count - copies + if object_copies_found[copies]: + print missing_string(object_copies_found[copies], + missing_copies, object_ring.replica_count) print '%.02f%% of object copies found (%d of %d)' % \ (value, copies_found, copies_expected) print 'Sample represents %.02f%% of the object partition space' % ( @@ -246,14 +240,41 @@ def object_dispersion_report(coropool, connpool, account, object_ring, stdout.flush() return None else: - return {'retries': retries_done[0], - 'overlapping': objects_listed - distinct_partitions, - 'missing_one': object_copies_found[2], - 'missing_two': object_copies_found[1], - 'missing_all': object_copies_found[0], - 'pct_found': value, - 'copies_found': copies_found, - 'copies_expected': copies_expected} + results = {'retries': retries_done[0], + 'overlapping': objects_listed - distinct_partitions, + 'pct_found': value, + 'copies_found': copies_found, + 'copies_expected': copies_expected} + for copies in xrange(object_ring.replica_count): + missing_copies = object_ring.replica_count - copies + results['missing_%d' % (missing_copies)] = \ + object_copies_found[copies] + return results + + +def missing_string(partition_count, missing_copies, copy_count): + exclamations = '' + missing_string = str(missing_copies) + if missing_copies == copy_count: + exclamations = '!!! ' + missing_string = 'all' + elif copy_count - missing_copies == 1: + exclamations = '! ' + + verb_string = 'was' + partition_string = 'partition' + if partition_count > 1: + verb_string = 'were' + partition_string = 'partitions' + + copy_string = 'copy' + if missing_copies > 1: + copy_string = 'copies' + + return '%sThere %s %d %s missing %s %s.' % ( + exclamations, verb_string, partition_count, partition_string, + missing_string, copy_string + ) if __name__ == '__main__':