summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryn M. Reeves <bmr@redhat.com>2016-07-03 22:55:33 +0100
committerBryn M. Reeves <bmr@redhat.com>2016-07-08 14:35:03 +0100
commit317db3df02e65067e40542f71f345dedd23d2064 (patch)
tree467a0e902777206e747237a16d6ee3c43d8476cc
parent1c3261c8966b88a8f8a98db0ddbcffc580ce1679 (diff)
downloadlvm2-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.c58
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;
}