1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

libdm: clean up _build_histogram_arg()

Split up _build_histogram_arg() into separate functions to allocate
and fill the histogram arg string and remove nested local variable
declarations from the parent function.
This commit is contained in:
Bryn M. Reeves 2015-09-07 18:27:22 +01:00
parent 4bc7a86f3a
commit 5f990473e4

View File

@ -194,8 +194,6 @@ static int _stats_region_present(const struct dm_stats_region *region)
static void _stats_histograms_destroy(struct dm_pool *mem,
struct dm_stats_region *region)
{
uint64_t n;
/* Unpopulated handle. */
if (!region->counters)
return;
@ -326,11 +324,54 @@ int dm_stats_driver_supports_histogram(void)
return _stats_check_precise_timestamps(NULL);
}
static int _fill_hist_arg(char *hist_arg, size_t hist_len, uint64_t scale,
struct dm_histogram *bounds)
{
int i, l, len = 0, nr_bins;
char *arg = hist_arg;
uint64_t value;
nr_bins = bounds->nr_bins;
for (i = 0; i < nr_bins; i++) {
value = bounds->bins[i].upper / scale;
if ((l = dm_snprintf(arg, hist_len - len, FMTu64"%s", value,
(i == (nr_bins - 1)) ? "" : ",")) < 0)
return_0;
len += l;
arg += l;
}
return 1;
}
static void *_get_hist_arg(struct dm_histogram *bounds, uint64_t scale,
size_t *len)
{
struct dm_histogram_bin *entry, *bins;
size_t hist_len = 1; /* terminating '\0' */
double value;
entry = bins = bounds->bins;
entry += bounds->nr_bins - 1;
while(entry >= bins) {
value = (double) (entry--)->upper;
/* Use lround to avoid size_t -> double cast warning. */
hist_len += 1 + (size_t) lround(log10(value / scale));
if (entry != bins)
hist_len++; /* ',' */
}
*len = hist_len;
return dm_zalloc(hist_len);
}
static char *_build_histogram_arg(struct dm_histogram *bounds, int *precise)
{
struct dm_histogram_bin *entry, *bins;
size_t hist_len = 1, len = 0;
char *hist_arg, *arg = NULL;
size_t hist_len;
char *hist_arg;
uint64_t scale;
entry = bins = bounds->bins;
@ -341,53 +382,37 @@ static char *_build_histogram_arg(struct dm_histogram *bounds, int *precise)
return NULL;
}
/* Validate entries and set *precise if precision < 1ms. */
entry += bounds->nr_bins - 1;
while(entry >= bins) {
double value;
while (entry >= bins) {
if (entry != bins) {
if (entry->upper < (entry - 1)->upper) {
log_error("Histogram boundaries must be in "
"order of increasing magnitude.");
return 0;
}
hist_len++; /* ',' */
}
/*
* Only enable precise_timestamps automatically if any
* value in the histogram bounds uses precision < 1ms.
*/
if (!*precise && (entry->upper % NSEC_PER_MSEC))
if (((entry--)->upper % NSEC_PER_MSEC) && !*precise)
*precise = 1;
value = (double) (entry--)->upper;
/* Use lround to avoid size_t -> double cast warning. */
hist_len += 1 + (size_t) lround(log10(value));
}
if (!(hist_arg = dm_zalloc(hist_len))) {
scale = (*precise) ? 1 : NSEC_PER_MSEC;
/* Calculate hist_len and allocate a character buffer. */
if (!(hist_arg = _get_hist_arg(bounds, scale, &hist_len))) {
log_error("Could not allocate memory for histogram argument.");
return 0;
}
arg = hist_arg;
/* Fill hist_arg with boundary strings. */
if (!_fill_hist_arg(hist_arg, hist_len, scale, bounds))
goto_bad;
if (*precise)
scale = 1;
else
scale = (*precise) ? 1 : NSEC_PER_MSEC;
for (entry = bins; entry < (bins + bounds->nr_bins); entry++) {
uint64_t value;
ssize_t l = 0;
int last = !(entry < (bins + bounds->nr_bins - 1));
value = entry->upper / scale;
if ((l = dm_snprintf(arg, hist_len - len, FMTu64"%s", value,
(last) ? "" : ",")) < 0)
goto_bad;
len += (size_t) l;
arg += (size_t) l;
}
return hist_arg;
bad: