diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cube.c | 51 | ||||
| -rw-r--r-- | src/cube.h | 8 | ||||
| -rw-r--r-- | src/fieldstat.c | 86 | ||||
| -rw-r--r-- | src/metrics/metric.c | 7 | ||||
| -rw-r--r-- | src/metrics/metric.h | 3 | ||||
| -rw-r--r-- | src/version.map | 9 |
6 files changed, 130 insertions, 34 deletions
@@ -803,6 +803,29 @@ int cube_histogram_record(struct cube *cube, int metric_id, const struct field * return FS_OK; } +int cube_histogram_merge(struct cube *cube, int metric_id, const struct field *dimensions, size_t n_dimensions, const struct hdr_histogram *src) { + if (cube->primary_metric_id == -1) { + return FS_ERR_CUBE_SAMPLING_NOT_INITIALIZED; + } + assert(cube->sampling_mode == SAMPLING_MODE_COMPREHENSIVE || (cube->primary_metric_id != metric_id)); + + const struct metric_manifest *manifest = metric_manifest_manager_get_by_id(cube->manifest_manager, metric_id); + if (manifest == NULL || manifest->type != METRIC_TYPE_HISTOGRAM) { + printf("invalid metric id\n"); + return FS_ERR_INVALID_METRIC_ID; + } + + struct cell *cell_data = get_cell_in_cube_generic(cube, dimensions, n_dimensions); + if (cell_data == NULL) { + printf("too many cells\n"); + return FS_ERR_TOO_MANY_CELLS; + } + + struct metric *metric = add_or_find_metric_in_cell(manifest, cell_data); + metric_histogram_merge(metric, src); + return FS_OK; +} + int cube_hll_add(struct cube *cube, int metric_id, const struct field *dimensions, size_t n_dimensions, const char *key, size_t key_len) { if (cube->primary_metric_id == -1) { return FS_ERR_CUBE_SAMPLING_NOT_INITIALIZED; @@ -1388,30 +1411,10 @@ struct field_list *cube_get_identifier(const struct cube *cube) { return ret; } -const char *cube_get_metric_name(const struct cube *cube, int metric_id) { - const struct metric_manifest *metric = metric_manifest_manager_get_by_id(cube->manifest_manager, metric_id); - if (metric == NULL) { - return NULL; - } - - return metric->name; -} - -enum metric_type cube_get_metric_type(const struct cube *cube, int metric_id) { - const struct metric_manifest *metric = metric_manifest_manager_get_by_id(cube->manifest_manager, metric_id); - if (metric == NULL) { - return (enum metric_type)(-1); - } - - return metric->type; +const struct metric_manifest *cube_get_metric_manifest_by_id(const struct cube *cube, int metric_id) { + return metric_manifest_manager_get_by_id(cube->manifest_manager, metric_id); } -int cube_get_metric_id_by_name(const struct cube *cube, const char *metric_name) -{ - const struct metric_manifest *metric = metric_manifest_manager_get_by_name(cube->manifest_manager, metric_name); - if (metric == NULL) { - return FS_ERR_INVALID_METRIC_NAME; - } - - return metric->id; +const struct metric_manifest *cube_get_metric_manifest_by_name(const struct cube *cube, const char *metric_name) { + return metric_manifest_manager_get_by_name(cube->manifest_manager, metric_name); } @@ -7,6 +7,7 @@ extern "C" #include <stddef.h> #include <stdbool.h> +#include "hdr/hdr_histogram.h" #include "fieldstat.h" // for dimensions #include "metric_manifest.h" @@ -26,6 +27,7 @@ int cube_register_hll(struct cube *cube,const char *metric_name, unsigned char p int cube_register_hist(struct cube *cube,const char *metric_name, long long lowest_trackable_value, long long highest_trackable_value, int significant_figures); int cube_histogram_record(struct cube *cube, int metric_id, const struct field *dimensions, size_t n_dimensions, long long value); +int cube_histogram_merge(struct cube *cube, int metric_id, const struct field *dimensions, size_t n_dimensions, const struct hdr_histogram *src); int cube_hll_add(struct cube *cube, int metric_id, const struct field *dimensions, size_t n_dimensions, const char *key, size_t key_len); int cube_hll_add_field(struct cube *cube, int metric_id, const struct field *dimensions, size_t n_dimensions, const struct field *item_fields, size_t n_item); int cube_counter_incrby(struct cube *cube, int metric_id, const struct field *dimensions, size_t n_dimensions, long long increment); @@ -43,9 +45,9 @@ enum sampling_mode cube_get_sampling_mode(const struct cube *cube); void cube_get_cells(const struct cube *cube, struct field_list **cell_dimensions, size_t *n_cell); void cube_get_metrics_in_cell(const struct cube *cube, const struct field_list *dimensions, int **metric_id_out, size_t *n_metric_out); struct field_list *cube_get_identifier(const struct cube *cube); -const char *cube_get_metric_name(const struct cube *cube, int metric_id); -enum metric_type cube_get_metric_type(const struct cube *cube, int metric_id); -int cube_get_metric_id_by_name(const struct cube *cube, const char *metric_name); +const struct metric_manifest *cube_get_metric_manifest_by_id(const struct cube *cube, int metric_id); +const struct metric_manifest *cube_get_metric_manifest_by_name(const struct cube *cube, const char *metric_name); + /* -------------------------------------------------------------------------- */ /* cube manager */ diff --git a/src/fieldstat.c b/src/fieldstat.c index 86aa0b2..1becadd 100644 --- a/src/fieldstat.c +++ b/src/fieldstat.c @@ -6,15 +6,21 @@ #include "cjson/cJSON.h" #include "uthash.h" +#include "hdr/hdr_histogram.h" #include "fieldstat.h" #include "metrics/metric.h" #include "cube.h" +#include "metric_manifest.h" struct fieldstat { struct cube_manager *cube_manager; }; +struct histogram { + struct hdr_histogram *histogram; +}; + /* -------------------------------------------------------------------------- */ /* fieldstat */ @@ -221,6 +227,65 @@ void fieldstat_calibrate(const struct fieldstat *master, struct fieldstat *repli } /* -------------------------------------------------------------------------- */ +/* histogram fast batch transaction */ +/* -------------------------------------------------------------------------- */ +struct histogram *fieldstat_histogram_fork(const struct fieldstat *instance, int cube_id, int metric_id) { + const struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); + if (cube == NULL) { + return NULL; + } + + const struct metric_manifest *manifest = cube_get_metric_manifest_by_id(cube, metric_id); + if (manifest == NULL || manifest->type != METRIC_TYPE_HISTOGRAM) { + return NULL; + } + const struct histogram_parameters *parameters = &(manifest->parameters->hdr); + + struct hdr_histogram* inner = NULL; + int ret = hdr_init(parameters->lowest_trackable_value, parameters->highest_trackable_value, parameters->significant_figures, &inner); + if (ret != 0) { + return NULL; + } + + struct histogram *histogram = calloc(1, sizeof(struct histogram)); + histogram->histogram = inner; + + return histogram; +} + +void histogram_free(struct histogram *histogram) +{ + if (histogram == NULL) { + return; + } + hdr_close(histogram->histogram); + free(histogram); +} + +void histogram_reset(struct histogram *histogram) { + hdr_reset(histogram->histogram); +} + +// cppcheck-suppress [constParameterPointer, unmatchedSuppression] +int fieldstat_histogram_merge(struct fieldstat *instance, int cube_id, int metric_id, const struct field *cell_dimensions, size_t n_dimensions, const struct histogram *src) +{ + struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); + if (cube == NULL) { + return FS_ERR_INVALID_CUBE_ID; + } + + return cube_histogram_merge(cube, metric_id, cell_dimensions, n_dimensions, src->histogram); +} + +int histogram_record(struct histogram *histogram, long long value) { + bool ret = hdr_record_value(histogram->histogram, value); + if (!ret) { + return FS_ERR_INVALID_PARAM; + } + return FS_OK; +} + +/* -------------------------------------------------------------------------- */ /* query */ /* -------------------------------------------------------------------------- */ void fieldstat_get_cubes(const struct fieldstat *instance, int **cube_ids, int *n_cube) @@ -327,7 +392,11 @@ const char *fieldstat_metric_get_name(const struct fieldstat *instance, int cube if (cube == NULL) { return NULL; } - return cube_get_metric_name(cube, metric_id); + const struct metric_manifest *manifest = cube_get_metric_manifest_by_id(cube, metric_id); + if (manifest == NULL) { + return NULL; + } + return manifest->name; } enum metric_type fieldstat_metric_get_type(const struct fieldstat *instance, int cube_id, int metric_id) @@ -336,7 +405,13 @@ enum metric_type fieldstat_metric_get_type(const struct fieldstat *instance, int if (cube == NULL) { return (enum metric_type)(-1); } - return cube_get_metric_type(cube, metric_id); + + const struct metric_manifest *manifest = cube_get_metric_manifest_by_id(cube, metric_id); + if (manifest == NULL) { + return (enum metric_type)(-1); + } + + return manifest->type; } void fieldstat_cube_get_cells(const struct fieldstat *instance, int cube_id, struct field_list **cell_dimensions, size_t *n_cell) @@ -390,5 +465,10 @@ int fieldstat_cube_get_metric_id_by_name(const struct fieldstat *instance, int c return FS_ERR_INVALID_CUBE_ID; } - return cube_get_metric_id_by_name(cube, metric_name); + const struct metric_manifest *manifest = cube_get_metric_manifest_by_name(cube, metric_name); + if (manifest == NULL) { + return FS_ERR_INVALID_METRIC_NAME; + } + + return manifest->id; }
\ No newline at end of file diff --git a/src/metrics/metric.c b/src/metrics/metric.c index 95dc646..f12e6b8 100644 --- a/src/metrics/metric.c +++ b/src/metrics/metric.c @@ -368,6 +368,13 @@ int metric_histogram_record(struct metric *pthis, long long value) { return 0; } +void metric_histogram_merge(struct metric *dest, const struct hdr_histogram *src) { + assert(dest->type == METRIC_TYPE_HISTOGRAM); + hdr_add(dest->data->hdr, src); + + dest->operated_after_reset = true; +} + long long metric_histogram_value_at_percentile(const struct metric *pthis, double percentile) { return hdr_value_at_percentile(pthis->data->hdr, percentile); } diff --git a/src/metrics/metric.h b/src/metrics/metric.h index 0dee126..9a077a3 100644 --- a/src/metrics/metric.h +++ b/src/metrics/metric.h @@ -4,6 +4,7 @@ #include <stdbool.h> #include "fieldstat.h" // for enum metric_type #include "metric_manifest.h" +#include "hdr/hdr_histogram.h" struct metric; @@ -27,4 +28,4 @@ int metric_histogram_record(struct metric *pthis, long long value); // for the meaning of these two query method, refer to https://prometheus.io/docs/concepts/metric_types/, and search for "histogram" and "summary" long long metric_histogram_value_at_percentile(const struct metric *pthis, double percentile); long long metric_histogram_count_le_value(const struct metric *pthis, long long value); - +void metric_histogram_merge(struct metric *dest, const struct hdr_histogram *src); diff --git a/src/version.map b/src/version.map index 5e22600..48a2365 100644 --- a/src/version.map +++ b/src/version.map @@ -1,5 +1,8 @@ { - global: *fieldstat_*, *histogram*; - GIT_VERSION*; - local: *; + global: + *fieldstat_*; + *histogram*; + GIT_VERSION*; + local: + *; };
\ No newline at end of file |
