diff options
author | Bryn M. Reeves <bmr@redhat.com> | 2016-07-03 22:55:33 +0100 |
---|---|---|
committer | Bryn M. Reeves <bmr@redhat.com> | 2016-07-08 14:35:03 +0100 |
commit | 317db3df02e65067e40542f71f345dedd23d2064 (patch) | |
tree | 467a0e902777206e747237a16d6ee3c43d8476cc | |
parent | 1c3261c8966b88a8f8a98db0ddbcffc580ce1679 (diff) | |
download | lvm2-317db3df02e65067e40542f71f345dedd23d2064.tar.gz |
libdm: allow regions with histograms in dm_stats_create_group()
Allow regions with histograms to be grouped if all histograms have
the same number of bins and matching bounds.
-rw-r--r-- | libdm/libdm-stats.c | 58 |
1 files changed, 53 insertions, 5 deletions
diff --git a/libdm/libdm-stats.c b/libdm/libdm-stats.c index 0aca622d5..55f10104b 100644 --- a/libdm/libdm-stats.c +++ b/libdm/libdm-stats.c @@ -3860,6 +3860,39 @@ merge: return overlap; } +static void _stats_copy_histogram_bounds(struct dm_histogram *to, + struct dm_histogram *from) +{ + uint64_t i; + + to->nr_bins = from->nr_bins; + + for (i = 0; i < to->nr_bins; i++) + to->bins[i].upper = from->bins[i].upper; +} + +/* + * Compare histogram bounds h1 and h2, and return 1 if they match (i.e. + * have the same number of bins and identical bin boundary values), or 0 + * otherwise. + */ +static int _stats_check_histogram_bounds(struct dm_histogram *h1, + struct dm_histogram *h2) +{ + uint64_t i; + + if (!h1 || !h2) + return 0; + + if (h1->nr_bins != h2->nr_bins) + return 0; + + for (i = 0; i < h1->nr_bins; i++) + if (h1->bins[i].upper != h2->bins[i].upper) + return 0; + return 1; +} + /* * Create a new group in stats handle dms from the group description * passed in group. @@ -3867,6 +3900,7 @@ merge: int dm_stats_create_group(struct dm_stats *dms, const char *members, const char *alias, uint64_t *group_id) { + struct dm_histogram *check = NULL, *bounds; int i, count = 0, precise = 0; dm_bitset_t regions; @@ -3877,6 +3911,11 @@ int dm_stats_create_group(struct dm_stats *dms, const char *members, if (!(regions = dm_bitset_parse_list(members, NULL))) { log_error("Could not parse list: '%s'", members); + return 0; + } + + if (!(check = dm_pool_zalloc(dms->hist_mem, sizeof(*check)))) { + log_error("Could not allocate memory for bounds check"); goto bad; } @@ -3902,14 +3941,20 @@ int dm_stats_create_group(struct dm_stats *dms, const char *members, FMTu64, i, dms->regions[i].group_id); goto bad; } - if (dms->regions[i].bounds) { - log_error("Region ID %d: grouping regions with " - "histograms is not yet supported", i); - goto bad; - } if (dms->regions[i].timescale == 1) precise++; + /* check for matching histogram bounds */ + bounds = dms->regions[i].bounds; + if (bounds && !check->nr_bins) + _stats_copy_histogram_bounds(check, bounds); + else if (bounds) { + if (!_stats_check_histogram_bounds(check, bounds)) { + log_error("All region histogram bounds " + "must match exactly"); + goto bad; + } + } count++; } @@ -3923,8 +3968,11 @@ int dm_stats_create_group(struct dm_stats *dms, const char *members, if (!_stats_create_group(dms, regions, alias, group_id)) goto bad; + dm_pool_free(dms->hist_mem, check); return 1; + bad: + dm_pool_free(dms->hist_mem, check); dm_bitset_destroy(regions); return 0; } |