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, static void _stats_histograms_destroy(struct dm_pool *mem,
struct dm_stats_region *region) struct dm_stats_region *region)
{ {
uint64_t n;
/* Unpopulated handle. */ /* Unpopulated handle. */
if (!region->counters) if (!region->counters)
return; return;
@ -326,11 +324,54 @@ int dm_stats_driver_supports_histogram(void)
return _stats_check_precise_timestamps(NULL); 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) static char *_build_histogram_arg(struct dm_histogram *bounds, int *precise)
{ {
struct dm_histogram_bin *entry, *bins; struct dm_histogram_bin *entry, *bins;
size_t hist_len = 1, len = 0; size_t hist_len;
char *hist_arg, *arg = NULL; char *hist_arg;
uint64_t scale; uint64_t scale;
entry = bins = bounds->bins; entry = bins = bounds->bins;
@ -341,53 +382,37 @@ static char *_build_histogram_arg(struct dm_histogram *bounds, int *precise)
return NULL; return NULL;
} }
/* Validate entries and set *precise if precision < 1ms. */
entry += bounds->nr_bins - 1; entry += bounds->nr_bins - 1;
while(entry >= bins) { while (entry >= bins) {
double value;
if (entry != bins) { if (entry != bins) {
if (entry->upper < (entry - 1)->upper) { if (entry->upper < (entry - 1)->upper) {
log_error("Histogram boundaries must be in " log_error("Histogram boundaries must be in "
"order of increasing magnitude."); "order of increasing magnitude.");
return 0; return 0;
} }
hist_len++; /* ',' */
} }
/* /*
* Only enable precise_timestamps automatically if any * Only enable precise_timestamps automatically if any
* value in the histogram bounds uses precision < 1ms. * value in the histogram bounds uses precision < 1ms.
*/ */
if (!*precise && (entry->upper % NSEC_PER_MSEC)) if (((entry--)->upper % NSEC_PER_MSEC) && !*precise)
*precise = 1; *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."); log_error("Could not allocate memory for histogram argument.");
return 0; 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; return hist_arg;
bad: bad: