summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchenzizhan <[email protected]>2024-07-05 15:52:54 +0800
committerchenzizhan <[email protected]>2024-07-05 15:52:54 +0800
commit140bd9a51aac330f7c367b61fe7b85f7d06fefe7 (patch)
treef9de2aa89584a2fa5ca0602e8d603e64c3c704a0
parentd822eaa3006588210a12694dc202df3f8f6e4187 (diff)
renames; manifest manager(a bidict) ; cube itself as item
-rw-r--r--include/fieldstat/fieldstat.h2
-rw-r--r--src/cube.c155
-rw-r--r--src/fieldstat.c357
-rw-r--r--src/metrics/metric.c2
-rw-r--r--src/metrics/metric_manifest.c134
-rw-r--r--src/metrics/metric_manifest.h31
-rw-r--r--test/test_merge.cpp2
7 files changed, 320 insertions, 363 deletions
diff --git a/include/fieldstat/fieldstat.h b/include/fieldstat/fieldstat.h
index 93ac2b8..b0969cf 100644
--- a/include/fieldstat/fieldstat.h
+++ b/include/fieldstat/fieldstat.h
@@ -158,7 +158,7 @@ void fieldstat_reset(struct fieldstat *instance);
@brief Merge the instance. The registered cubes and metrics are merged even if there are no cells added.
@return 0 if success. return FS_ERR_INVALID_PARAM when the registered cubes or metrics between dest and src of the same keys has different types or configurations(like different primary metric).
*/
-int fieldstat_merge(struct fieldstat *instance, struct fieldstat *src);
+int fieldstat_merge(struct fieldstat *instance, const struct fieldstat *src);
/* -------------------------------------------------------------------------- */
/* query */
diff --git a/src/cube.c b/src/cube.c
index 519923b..b95d652 100644
--- a/src/cube.c
+++ b/src/cube.c
@@ -19,15 +19,8 @@ struct exdata_new_args {
size_t n_tags;
};
-struct cube_manager_item {
- char *key;
- size_t key_len;
- int id;
- UT_hash_handle hh;
-};
-
struct cube_manager {
- struct cube_manager_item *head;
+ struct cube *hash_table;
struct cube **cube;
size_t cube_cnt;
@@ -54,9 +47,13 @@ struct cube {
size_t n_shared_tags;
int primary_metric_id;
+ char *key;
+ size_t key_len;
+ int id;
+ UT_hash_handle hh;
};
-static void tag_array_copy(struct fieldstat_tag *tags_dst, const struct fieldstat_tag *tags_src, size_t n_tag)
+static void tag_array_copy(struct fieldstat_tag *tags_dst, const struct fieldstat_tag *tags_src, size_t n_tag) // TODO: 改成clone吧,
{
for (size_t i = 0; i < n_tag; i++) {
tags_dst[i].key = strdup(tags_src[i].key);
@@ -108,28 +105,21 @@ void add_cube_to_position(struct cube_manager *instance, struct cube *cube, int
}
void cube_manager_free(struct cube_manager *pthis) {
- struct cube_manager_item *node = NULL;
- struct cube_manager_item *tmp = NULL;
- struct cube_manager_item *head = pthis->head;
+ struct cube *node = NULL;
+ struct cube *tmp = NULL;
+ struct cube *head = pthis->hash_table;
HASH_ITER(hh, head, node, tmp) {
HASH_DEL(head, node);
- free(node->key);
- free(node);
+ cube_free(node);
}
- for (int i = 0; i < pthis->cube_cnt; i++) {
- if (pthis->cube[i] != NULL) {
- cube_free(pthis->cube[i]);
- }
- }
-
free(pthis->cube);
free(pthis);
}
struct cube_manager *cube_manager_new() {
struct cube_manager *pthis = (struct cube_manager *)malloc(sizeof(struct cube_manager));
- pthis->head = NULL;
+ pthis->hash_table = NULL;
pthis->cube = (struct cube **)calloc(DEFAULT_N_CUBE, sizeof(struct cube *));
pthis->cube_cnt = 0;
@@ -138,7 +128,7 @@ struct cube_manager *cube_manager_new() {
}
-static void build_dynamic_cell_key(const struct fieldstat_tag tags[], size_t n_tags, char **out_key, size_t *out_key_size)
+static void tag2key(const struct fieldstat_tag tags[], size_t n_tags, char **out_key, size_t *out_key_size)
{
if (n_tags == 0) {
// use a default dummy key
@@ -223,14 +213,12 @@ static void build_dynamic_cell_key(const struct fieldstat_tag tags[], size_t n_t
int cube_manager_add(struct cube_manager *pthis, struct cube *cube)
{
- char *key;
- size_t key_len;
- build_dynamic_cell_key(cube->cube_identifier, cube->n_shared_tags, &key, &key_len);
+ char *key = cube->key;
+ size_t key_len = cube->key_len;
- struct cube_manager_item *node = NULL;
- HASH_FIND(hh, pthis->head, key, key_len, node);
- if (node != NULL) {
- free(key);
+ struct cube *old_cube = NULL;
+ HASH_FIND(hh, pthis->hash_table, key, key_len, old_cube);
+ if (old_cube != NULL) {
return -1;
}
@@ -241,55 +229,42 @@ int cube_manager_add(struct cube_manager *pthis, struct cube *cube)
}
}
- node = (struct cube_manager_item *)malloc(sizeof(struct cube_manager_item));
- node->key = key;
- node->key_len = key_len;
- node->id = id;
- HASH_ADD_KEYPTR(hh, pthis->head, node->key, key_len, node);
+ cube->id = id;
+ HASH_ADD_KEYPTR(hh, pthis->hash_table, cube->key, key_len, cube);
add_cube_to_position(pthis, cube, id);
return id;
}
-void cube_manager_delete_by_key(struct cube_manager *pthis, const char *key, size_t key_len)
+void cube_manager_delete(struct cube_manager *pthis, struct cube *cube)
{
- struct cube_manager_item *node = NULL;
- HASH_FIND(hh, pthis->head, key, key_len, node);
- if (node == NULL) {
- return;
- }
-
- int id = node->id;
- cube_free(pthis->cube[id]);
+ // char *key = cube->key;
+ // size_t key_len = cube->key_len;
+ // struct cube *node = NULL;
+ // HASH_FIND(hh, pthis->head, key, key_len, node);
+ // if (node == NULL) {
+ // return;
+ // }
+
+ int id = cube->id;
+ HASH_DEL(pthis->hash_table, cube);
+
+ cube_free(cube);
pthis->cube[id] = NULL;
if (id == pthis->cube_cnt - 1) {
pthis->cube_cnt--;
}
-
- HASH_DEL(pthis->head, node);
- free(node->key);
- free(node);
-}
-
-void cube_manager_delete(struct cube_manager *pthis, struct cube *cube)
-{
- char *key;
- size_t key_len;
- build_dynamic_cell_key(cube->cube_identifier, cube->n_shared_tags, &key, &key_len);
-
- cube_manager_delete_by_key(pthis, key, key_len);
- free(key);
}
int cube_manager_find(const struct cube_manager *pthis, const struct fieldstat_tag *identifier, size_t n_tag)
{
char *key;
size_t key_len;
- build_dynamic_cell_key(identifier, n_tag, &key, &key_len);
+ tag2key(identifier, n_tag, &key, &key_len);
- struct cube_manager_item *node = NULL;
- HASH_FIND(hh, pthis->head, key, key_len, node);
+ struct cube *node = NULL;
+ HASH_FIND(hh, pthis->hash_table, key, key_len, node);
free(key);
if (node == NULL) {
return -1;
@@ -327,27 +302,23 @@ void cube_manager_list(const struct cube_manager *pthis, int **cube_ids, int *n_
void cube_manager_calibrate(struct cube_manager *pthis, const struct cube_manager *master)
{
- struct cube_manager_item *node = NULL;
- struct cube_manager_item *tmp = NULL;
+ struct cube *node_in_master, *node_in_dest, *tmp;
// exist in self but not in master
- HASH_ITER(hh, pthis->head, node, tmp) {
- struct cube_manager_item *node_in_master = NULL;
- HASH_FIND(hh, master->head, node->key, node->key_len, node_in_master);
+ HASH_ITER(hh, pthis->hash_table, node_in_dest, tmp) {
+ HASH_FIND(hh, master->hash_table, node_in_dest->key, node_in_dest->key_len, node_in_master);
if (node_in_master == NULL) {
- cube_manager_delete_by_key(pthis, node->key, node->key_len);
+ cube_manager_delete(pthis, node_in_dest);
}
}
// exist in master but not in self
- HASH_ITER(hh, master->head, node, tmp) {
- struct cube_manager_item *node_in_self = NULL;
- HASH_FIND(hh, pthis->head, node->key, node->key_len, node_in_self);
+ HASH_ITER(hh, master->hash_table, node_in_master, tmp) {
+ HASH_FIND(hh, pthis->hash_table, node_in_master->key, node_in_master->key_len, node_in_dest);
- if (node_in_self == NULL) {
- int cube_id = node->id;
- cube_manager_add(pthis, cube_fork(master->cube[cube_id]));
+ if (node_in_dest == NULL) {
+ cube_manager_add(pthis, cube_fork(node_in_master));
}
}
}
@@ -355,26 +326,26 @@ void cube_manager_calibrate(struct cube_manager *pthis, const struct cube_manage
struct cube_manager *cube_manager_fork(const struct cube_manager *src)
{
struct cube_manager *pthis = cube_manager_new();
- struct cube_manager_item *node = NULL;
- struct cube_manager_item *tmp = NULL;
- HASH_ITER(hh, src->head, node, tmp) {
- cube_manager_add(pthis, cube_fork(src->cube[node->id]));
+ struct cube *node = NULL;
+ struct cube *tmp = NULL;
+ HASH_ITER(hh, src->hash_table, node, tmp) {
+ cube_manager_add(pthis, cube_fork(node));
}
return pthis;
}
void cube_manager_merge(struct cube_manager *dest, const struct cube_manager *src)
{
- struct cube_manager_item *node = NULL;
- struct cube_manager_item *tmp = NULL;
- HASH_ITER(hh, src->head, node, tmp) {
- struct cube_manager_item *node_in_dest = NULL;
- HASH_FIND(hh, dest->head, node->key, node->key_len, node_in_dest);
+ struct cube *node = NULL;
+ struct cube *tmp = NULL;
+ HASH_ITER(hh, src->hash_table, node, tmp) {
+ struct cube *node_in_dest = NULL;
+ HASH_FIND(hh, dest->hash_table, node->key, node->key_len, node_in_dest);
if (node_in_dest == NULL) {
- cube_manager_add(dest, cube_copy(src->cube[node->id]));
+ cube_manager_add(dest, cube_copy(node));
} else {
- cube_merge(dest->cube[node_in_dest->id], src->cube[node->id]);
+ cube_merge(node_in_dest, node);
}
}
}
@@ -530,8 +501,10 @@ struct cube *cube_info_new(const struct fieldstat_tag *shared_tags, size_t n_tag
}
cube->n_shared_tags = n_tag;
-
cube->max_n_cell = max_n_cell;
+ tag2key(shared_tags, n_tag, &cube->key, &cube->key_len);
+
+ cube->id = -1;
return cube;
}
@@ -573,6 +546,7 @@ void cube_free(struct cube *cube) {
}
fieldstat_free_tag_array(cube->cube_identifier, cube->n_shared_tags);
+ free(cube->key);
free(cube);
}
@@ -592,7 +566,7 @@ void cube_set_primary_metric(struct cube *cube, int metric_id) {
struct cell *get_cell(struct cube *cube, const struct fieldstat_tag *tags, size_t n_tag,long long increment, int metric_id) {
char *tag_in_string;
size_t tag_len;
- build_dynamic_cell_key(tags, n_tag, &tag_in_string, &tag_len);
+ tag2key(tags, n_tag, &tag_in_string, &tag_len);
struct exdata_new_args args;
args.tags = tags;
args.n_tags = n_tag;
@@ -634,7 +608,7 @@ struct cell *get_cell(struct cube *cube, const struct fieldstat_tag *tags, size_
int cube_histogram_record(struct cube *cube, const struct metric_manifest *manifest, const struct fieldstat_tag *tags, size_t n_tag, long long value) {
assert(manifest->type == METRIC_TYPE_HISTOGRAM);
- assert(manifest->id != cube->primary_metric_id);
+ assert(cube->sampling_mode == SAMPLING_MODE_COMPREHENSIVE || (cube->primary_metric_id != manifest->id));
struct cell *cell_data = get_cell(cube, tags, n_tag, 0, manifest->id);
if (cell_data == NULL) {
@@ -651,7 +625,7 @@ int cube_histogram_record(struct cube *cube, const struct metric_manifest *manif
int cube_hll_add(struct cube *cube, const struct metric_manifest *manifest, const struct fieldstat_tag *tags, size_t n_tag, const char *key, size_t key_len) {
assert(manifest->type == METRIC_TYPE_HLL);
- assert(manifest->id != cube->primary_metric_id);
+ assert(cube->sampling_mode == SAMPLING_MODE_COMPREHENSIVE || (cube->primary_metric_id != manifest->id));
struct cell *cell_data = get_cell(cube, tags, n_tag, 0, manifest->id);
if (cell_data == NULL) {
@@ -665,7 +639,7 @@ int cube_hll_add(struct cube *cube, const struct metric_manifest *manifest, cons
int cube_counter_incrby(struct cube *cube, const struct metric_manifest *manifest, const struct fieldstat_tag *tags, size_t n_tag, long long increment) {
assert(manifest->type == METRIC_TYPE_COUNTER);
- assert(cube->primary_metric_id != manifest->id || increment >= 0);
+ assert(cube->sampling_mode == SAMPLING_MODE_COMPREHENSIVE || (cube->primary_metric_id != manifest->id || increment >= 0));
struct cell *cell_data = get_cell(cube, tags, n_tag, increment, manifest->id);
if (cell_data == NULL) {
@@ -680,7 +654,8 @@ int cube_counter_incrby(struct cube *cube, const struct metric_manifest *manifes
int cube_counter_set(struct cube *cube, const struct metric_manifest *manifest, const struct fieldstat_tag *tags, size_t n_tag, long long value) {
assert(manifest->type == METRIC_TYPE_COUNTER);
- assert(cube->primary_metric_id != manifest->id);
+ assert(cube->sampling_mode == SAMPLING_MODE_COMPREHENSIVE || (cube->primary_metric_id != manifest->id));
+
struct cell *cell_data = get_cell(cube, tags, n_tag, 0, manifest->id);
if (cell_data == NULL) {
return FS_ERR_TOO_MANY_CELLS;
@@ -793,7 +768,7 @@ const struct cell *get_cell_by_tag_list(const struct cube *cube, const struct fi
const struct cell *ret = NULL;
char *tag_in_string;
size_t tag_len;
- build_dynamic_cell_key(tags->tag, tags->n_tag, &tag_in_string, &tag_len);
+ tag2key(tags->tag, tags->n_tag, &tag_in_string, &tag_len);
switch (cube->sampling_mode)
{
diff --git a/src/fieldstat.c b/src/fieldstat.c
index cc57a68..df5f482 100644
--- a/src/fieldstat.c
+++ b/src/fieldstat.c
@@ -13,23 +13,13 @@
#include "cube.h"
#include "metric_manifest.h"
-#define DEFAULT_N_METRIC 32
-
-struct name_set {
- char *name;
- UT_hash_handle hh;
-};
struct fieldstat {
- struct metric_manifest **manifests;
- size_t manifest_size;
- size_t manifest_cnt;
- struct name_set *metric_name_set;
+ struct metric_manifest_manager *manifest_manager;
struct cube_manager *cube_manager;
};
-
union metric_parameter *construct_parameters(enum metric_type type, ...)
{
union metric_parameter *paras = (union metric_parameter *)malloc(sizeof(union metric_parameter));
@@ -53,29 +43,6 @@ union metric_parameter *construct_parameters(enum metric_type type, ...)
return paras;
}
-struct metric_manifest *metric_manifest_copy(const struct metric_manifest *src)
-{
- struct metric_manifest *dest = (struct metric_manifest *)malloc(sizeof(struct metric_manifest));
- dest->name = strdup(src->name);
- if (src->paras == NULL) {
- dest->paras = NULL;
- } else {
- dest->paras = (union metric_parameter *)malloc(sizeof(union metric_parameter));
- memcpy(dest->paras, src->paras, sizeof(union metric_parameter));
- }
-
- dest->type = src->type;
- dest->id = src->id;
-
- return dest;
-}
-
-void metric_manifest_free(struct metric_manifest *manifest) {
- free(manifest->name);
- free(manifest->paras);
- free(manifest);
-}
-
void tag_array_copy(struct fieldstat_tag *tags_dst, const struct fieldstat_tag *tags_src, size_t n_tag)
{
for (size_t i = 0; i < n_tag; i++) {
@@ -131,15 +98,6 @@ bool is_tag_array_same(const struct fieldstat_tag *tags1, const struct fieldstat
return 0;
}
-bool is_metric_name_duplicate(const struct fieldstat *instance, const char *name)
-{
- for (size_t i = 0; i < instance->manifest_cnt; i++) {
- if (strcmp(instance->manifests[i]->name, name) == 0) {
- return true;
- }
- }
- return false;
-}
/* -------------------------------------------------------------------------- */
/* fieldstat */
/* -------------------------------------------------------------------------- */
@@ -148,9 +106,7 @@ struct fieldstat *fieldstat_new()
{
struct fieldstat *instance = calloc(1, sizeof(struct fieldstat));
- instance->manifest_size = DEFAULT_N_METRIC;
- instance->manifests = calloc(instance->manifest_size, sizeof(struct metric_manifest *));
- instance->manifest_cnt = 0;
+ instance->manifest_manager = metric_manifest_manager_new();
instance->cube_manager = cube_manager_new();
@@ -165,17 +121,7 @@ void fieldstat_free(struct fieldstat *instance)
cube_manager_free(instance->cube_manager);
- for (size_t i = 0; i < instance->manifest_cnt; i++) {
- metric_manifest_free(instance->manifests[i]);
- }
- free(instance->manifests);
-
- struct name_set *name_set, *tmp;
- HASH_ITER(hh, instance->metric_name_set, name_set, tmp) {
- HASH_DEL(instance->metric_name_set, name_set);
- free(name_set->name);
- free(name_set);
- }
+ metric_manifest_manager_free(instance->manifest_manager);
free(instance);
}
@@ -243,6 +189,7 @@ int fieldstat_create_cube(struct fieldstat *instance, const struct fieldstat_tag
return ret; //ret is the cube_id
}
+// cppcheck-suppress [constParameterPointer, unmatchedSuppression]
int fieldstat_cube_set_primary_metric(struct fieldstat *instance, int cube_id, int metric_id)
{
if (instance == NULL) {
@@ -253,13 +200,11 @@ int fieldstat_cube_set_primary_metric(struct fieldstat *instance, int cube_id, i
if (cube == NULL) {
return FS_ERR_INVALID_CUBE_ID;
}
- if (metric_id < 0 || metric_id >= instance->manifest_cnt) {
+ const struct metric_manifest *manifest = metric_manifest_manager_get_by_id(instance->manifest_manager, metric_id);
+ if (manifest == NULL) {
return FS_ERR_INVALID_METRIC_ID;
}
- if (instance->manifests[metric_id] == NULL) {
- return FS_ERR_INVALID_METRIC_ID;
- }
- if (instance->manifests[metric_id]->type != METRIC_TYPE_COUNTER) {
+ if (manifest->type != METRIC_TYPE_COUNTER) {
return FS_ERR_INVALID_PARAM;
}
@@ -271,57 +216,22 @@ int fieldstat_cube_set_primary_metric(struct fieldstat *instance, int cube_id, i
/* -------------------------------------------------------------------------- */
/* metric register */
/* -------------------------------------------------------------------------- */
-
-void add_manifest_to_instance(struct fieldstat *instance, const struct metric_manifest *manifest, int metric_id)
-{
- if (metric_id >= instance->manifest_size) {
- instance->manifests = realloc(instance->manifests, sizeof(struct metric_manifest *) * instance->manifest_size * 2);
- memset(instance->manifests + instance->manifest_size, 0, sizeof(struct metric_manifest *) * (instance->manifest_size));
- instance->manifest_size *= 2;
- }
-
- instance->manifests[metric_id] = (struct metric_manifest *)manifest;
- if (metric_id >= instance->manifest_cnt) {
- instance->manifest_cnt = metric_id + 1;
- }
-
- struct name_set *name_set = (struct name_set *)malloc(sizeof(struct name_set));
- name_set->name = strdup(manifest->name);
- HASH_ADD_KEYPTR(hh, instance->metric_name_set, name_set->name, strlen(name_set->name), name_set);
-}
-
-static int append_manifest_to_instance(struct fieldstat *instance, const struct metric_manifest *metric)
-{
- int metric_id = instance->manifest_cnt;
- add_manifest_to_instance(instance, metric, metric_id);
-
- return metric_id;
-}
-
-bool find_metric(const struct fieldstat *instance, const char *metric_name)
-{
- struct name_set *name_set;
- HASH_FIND_STR(instance->metric_name_set, metric_name, name_set);
- if (name_set != NULL) {
- return true;
- }
- return false;
-}
-
int fieldstat_register_counter(struct fieldstat *instance, const char *metric_name)
{
- if (find_metric(instance, metric_name)) {
- return FS_ERR_INVALID_KEY;
- }
-
struct metric_manifest *metric = malloc(sizeof(struct metric_manifest));
metric->name = strdup(metric_name);
- metric->paras = construct_parameters(METRIC_TYPE_COUNTER);
+ metric->parameters = construct_parameters(METRIC_TYPE_COUNTER);
metric->type = METRIC_TYPE_COUNTER;
- int id = append_manifest_to_instance(instance, metric);
- metric->id = id;
+ int id = metric_manifest_manager_add(instance->manifest_manager, metric);
+ if (id < 0) {
+ free(metric->name);
+ free(metric->parameters);
+ free(metric);
+ return FS_ERR_INVALID_KEY;
+ }
+ metric->id = id;
return id;
}
@@ -330,18 +240,21 @@ int fieldstat_register_hll(struct fieldstat *instance, const char *metric_name,
if (precision < 4 || precision > 18) {
return FS_ERR_INVALID_PARAM;
}
- if (find_metric(instance, metric_name)) {
- return FS_ERR_INVALID_KEY;
- }
struct metric_manifest *metric = malloc(sizeof(struct metric_manifest));
metric->name = strdup(metric_name);
- metric->paras = construct_parameters(METRIC_TYPE_HLL, precision);
+ metric->parameters = construct_parameters(METRIC_TYPE_HLL, precision);
metric->type = METRIC_TYPE_HLL;
- int id = append_manifest_to_instance(instance, metric);
- metric->id = id;
+ int id = metric_manifest_manager_add(instance->manifest_manager, metric);
+ if (id < 0) {
+ free(metric->name);
+ free(metric->parameters);
+ free(metric);
+ return FS_ERR_INVALID_KEY;
+ }
+ metric->id = id;
return id;
}
@@ -358,16 +271,20 @@ int fieldstat_register_hist(struct fieldstat *instance, const char *metric_name,
{
return FS_ERR_INVALID_PARAM;
}
- if (find_metric(instance, metric_name)) {
- return FS_ERR_INVALID_KEY;
- }
+
struct metric_manifest *metric = malloc(sizeof(struct metric_manifest));
metric->name = strdup(metric_name);
- metric->paras = construct_parameters(METRIC_TYPE_HISTOGRAM, lowest_trackable_value, highest_trackable_value, significant_figures);
+ metric->parameters = construct_parameters(METRIC_TYPE_HISTOGRAM, lowest_trackable_value, highest_trackable_value, significant_figures);
metric->type = METRIC_TYPE_HISTOGRAM;
- int id = append_manifest_to_instance(instance, metric);
+ int id = metric_manifest_manager_add(instance->manifest_manager, metric);
+ if (id < 0) {
+ free(metric->name);
+ free(metric->parameters);
+ free(metric);
+ return FS_ERR_INVALID_KEY;
+ }
metric->id = id;
return id;
@@ -376,132 +293,96 @@ int fieldstat_register_hist(struct fieldstat *instance, const char *metric_name,
/* -------------------------------------------------------------------------- */
/* metric operation */
/* -------------------------------------------------------------------------- */
-int check_before_add(const struct fieldstat *instance, int cube_id, int metric_id, enum metric_type type)
-{
- if (instance == NULL) {
- return FS_ERR_NULL_HANDLER;
- }
- if (cube_manager_get_cube_by_id(instance->cube_manager, cube_id) == NULL) {
+// cppcheck-suppress [constParameterPointer, unmatchedSuppression]
+int fieldstat_counter_incrby(struct fieldstat *instance, int cube_id, int metric_id, const struct fieldstat_tag *tags, size_t n_tag, long long increment)
+{
+ struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id);
+ if (cube == NULL) {
return FS_ERR_INVALID_CUBE_ID;
}
-
- if (metric_id < 0 || metric_id >= instance->manifest_cnt) {
- return FS_ERR_INVALID_METRIC_ID;
- }
- const struct metric_manifest *metric = instance->manifests[metric_id];
- if (metric == NULL || metric->type != type) {
+ const struct metric_manifest *manifest = metric_manifest_manager_get_by_id(instance->manifest_manager, metric_id);
+ if (manifest == NULL || manifest->type != METRIC_TYPE_COUNTER) {
return FS_ERR_INVALID_METRIC_ID;
}
-
- return FS_OK;
-}
-
-int fieldstat_counter_incrby(struct fieldstat *instance, int cube_id, int metric_id, const struct fieldstat_tag *tags, size_t n_tag, long long increment)
-{
- int ret = check_before_add(instance, cube_id, metric_id, METRIC_TYPE_COUNTER);
- if (ret != FS_OK) {
- return ret;
- }
-
- struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id);
- const struct metric_manifest *manifest = instance->manifests[metric_id];
return cube_counter_incrby(cube, manifest, tags, n_tag, increment);
-
}
+// cppcheck-suppress [constParameterPointer, unmatchedSuppression]
int fieldstat_counter_set(struct fieldstat *instance, int cube_id, int metric_id, const struct fieldstat_tag *tags, size_t n_tag, long long value)
{
- int ret = check_before_add(instance, cube_id, metric_id, METRIC_TYPE_COUNTER);
- if (ret != FS_OK) {
- return ret;
- }
struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id);
- const struct metric_manifest *manifest = instance->manifests[metric_id];
+ if (cube == NULL) {
+ return FS_ERR_INVALID_CUBE_ID;
+ }
+ const struct metric_manifest *manifest = metric_manifest_manager_get_by_id(instance->manifest_manager, metric_id);
+ if (manifest == NULL || manifest->type != METRIC_TYPE_COUNTER) {
+ return FS_ERR_INVALID_METRIC_ID;
+ }
return cube_counter_set(cube, manifest, tags, n_tag, value);
}
+// cppcheck-suppress [constParameterPointer, unmatchedSuppression]
int fieldstat_hll_add(struct fieldstat *instance, int cube_id, int metric_id, const struct fieldstat_tag *tags, size_t n_tag, const char *key, size_t key_len)
{
- int ret = check_before_add(instance, cube_id, metric_id, METRIC_TYPE_HLL);
- if (ret != FS_OK) {
- return ret;
- }
-
struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id);
- const struct metric_manifest *manifest = instance->manifests[metric_id];
+ if (cube == NULL) {
+ return FS_ERR_INVALID_CUBE_ID;
+ }
+ const struct metric_manifest *manifest = metric_manifest_manager_get_by_id(instance->manifest_manager, metric_id);
+ if (manifest == NULL || manifest->type != METRIC_TYPE_HLL) {
+ return FS_ERR_INVALID_METRIC_ID;
+ }
return cube_hll_add(cube, manifest, tags, n_tag, key, key_len);
}
+// cppcheck-suppress [constParameterPointer, unmatchedSuppression]
int fieldstat_hist_record(struct fieldstat *instance, int cube_id, int metric_id, const struct fieldstat_tag *tags, size_t n_tag, long long value)
{
- int ret = check_before_add(instance, cube_id, metric_id, METRIC_TYPE_HISTOGRAM);
- if (ret != FS_OK) {
- return ret;
- }
-
struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id);
- const struct metric_manifest *manifest = instance->manifests[metric_id];
+ if (cube == NULL) {
+ return FS_ERR_INVALID_CUBE_ID;
+ }
+ const struct metric_manifest *manifest = metric_manifest_manager_get_by_id(instance->manifest_manager, metric_id);
+ if (manifest == NULL || manifest->type != METRIC_TYPE_HISTOGRAM) {
+ return FS_ERR_INVALID_METRIC_ID;
+ }
return cube_histogram_record(cube, manifest, tags, n_tag, value);
}
-int fieldstat_merge(struct fieldstat *instance, struct fieldstat *src)
+int fieldstat_merge(struct fieldstat *instance, const struct fieldstat *src)
{
if (instance == NULL || src == NULL) {
return FS_ERR_NULL_HANDLER;
}
- int metric_len_src = src->manifest_cnt;
- int metric_len_dst = instance->manifest_cnt;
- int len_min = metric_len_src < metric_len_dst ? metric_len_src : metric_len_dst;
+ size_t n_metric_src = 0;
+ const struct metric_manifest **list_src = metric_manifest_manager_list(src->manifest_manager, &n_metric_src);
+ size_t n_metric_dst = 0;
+ const struct metric_manifest **list_dst = metric_manifest_manager_list(instance->manifest_manager, &n_metric_dst);
+ int len_min = n_metric_src < n_metric_dst ? n_metric_src : n_metric_dst;
for (int i = 0; i < len_min; i++) {
- const struct metric_manifest *metric_src = src->manifests[i];
- const struct metric_manifest *metric_dst = instance->manifests[i];
- if (metric_src->type != metric_dst->type ||
- strcmp(metric_src->name, metric_dst->name) != 0
- ) {
- assert(0);
+ if (list_src[i]->type != list_dst[i]->type) {
+ return FS_ERR_INVALID_PARAM;
+ }
+ if (strcmp(list_src[i]->name, list_dst[i]->name) != 0) {
return FS_ERR_INVALID_PARAM;
}
}
- for (int i = metric_len_dst; i < metric_len_src; i++) {
- const struct metric_manifest *metric_src = src->manifests[i];
- append_manifest_to_instance(instance, metric_manifest_copy(metric_src));
+ for (int i = n_metric_dst; i < n_metric_src; i++) {
+ metric_manifest_manager_add(instance->manifest_manager, metric_manifest_copy(list_src[i]));
}
+
cube_manager_merge(instance->cube_manager, src->cube_manager);
return FS_OK;
}
-void metric_name_set_callibrate(struct fieldstat *instance, const struct fieldstat *master)
-{
- struct name_set *name_set_master, *tmp, *name_set_dest;
- // name in dest but not in master
- HASH_ITER(hh, instance->metric_name_set, name_set_dest, tmp) {
- HASH_FIND_STR(master->metric_name_set, name_set_dest->name, name_set_master);
- if (name_set_master == NULL) {
- HASH_DEL(instance->metric_name_set, name_set_dest);
- free(name_set_dest->name);
- free(name_set_dest);
- }
- }
-
- // name in master but not in dest
- HASH_ITER(hh, master->metric_name_set, name_set_master, tmp) {
- HASH_FIND_STR(instance->metric_name_set, name_set_master->name, name_set_dest);
- if (name_set_dest == NULL) {
- name_set_dest = (struct name_set *)malloc(sizeof(struct name_set));
- name_set_dest->name = strdup(name_set_master->name);
- HASH_ADD_KEYPTR(hh, instance->metric_name_set, name_set_dest->name, strlen(name_set_dest->name), name_set_dest);
- }
- }
-}
-
struct fieldstat *fieldstat_fork(const struct fieldstat *instance)
{
if (instance == NULL) {
@@ -510,60 +391,16 @@ struct fieldstat *fieldstat_fork(const struct fieldstat *instance)
struct fieldstat *new_instance = calloc(1, sizeof(struct fieldstat));
new_instance->cube_manager = cube_manager_fork(instance->cube_manager);
- new_instance->manifests = calloc(instance->manifest_size, sizeof(struct metric_manifest *));
- new_instance->manifest_size = instance->manifest_size;
- new_instance->manifest_cnt = instance->manifest_cnt;
-
- for (size_t i = 0; i < instance->manifest_cnt; i++) {
- new_instance->manifests[i] = metric_manifest_copy(instance->manifests[i]);
- }
- metric_name_set_callibrate(new_instance, instance);
+ new_instance->manifest_manager = metric_manifest_manager_copy(instance->manifest_manager);
return new_instance;
}
-void calibrate_metrics_in_instance(const struct fieldstat *master, struct fieldstat *replica)
-{
- if (replica->manifest_size < master->manifest_size) {
- replica->manifests = (struct metric_manifest **)realloc(replica->manifests, sizeof(struct metric_manifest *) * master->manifest_size);
- memset(replica->manifests + replica->manifest_size, 0, sizeof(struct metric_manifest *) * (master->manifest_size - replica->manifest_size));
- replica->manifest_size = master->manifest_size;
- }
-
- size_t longer_arr_len = master->manifest_cnt > replica->manifest_cnt ? master->manifest_cnt : replica->manifest_cnt;
- for (size_t i = 0; i < longer_arr_len; i++) {
- const struct metric_manifest *metric_master = i >= master->manifest_cnt ? NULL : master->manifests[i];
- struct metric_manifest *metric_target = i >= replica->manifest_cnt ? NULL : replica->manifests[i];
- if (metric_master == NULL && metric_target == NULL) {
- continue;
- }
- if (metric_master == NULL && metric_target != NULL) {
- metric_manifest_free(metric_target);
- replica->manifests[i] = NULL;
- continue;
- }
- if (metric_master != NULL && metric_target == NULL) {
- replica->manifests[i] = metric_manifest_copy(metric_master);
- continue;
- }
-
- if (metric_master->type != metric_target->type || strcmp(metric_master->name, metric_target->name) != 0) {
- metric_manifest_free(metric_target);
- replica->manifests[i] = metric_manifest_copy(metric_master);
- continue;
- }
-
- // metric same, no need to do anything
- }
-
- replica->manifest_cnt = master->manifest_cnt;
- metric_name_set_callibrate(replica, master);
-}
-
int fieldstat_calibrate(const struct fieldstat *master, struct fieldstat *replica)
{
cube_manager_calibrate(replica->cube_manager, master->cube_manager);
- calibrate_metrics_in_instance(master, replica);
+ metric_manifest_manager_free(replica->manifest_manager);
+ replica->manifest_manager = metric_manifest_manager_copy(master->manifest_manager);
return FS_OK;
}
@@ -578,20 +415,18 @@ void fieldstat_get_cubes(const struct fieldstat *instance, int **cube_ids, int *
void fieldstat_get_metrics(const struct fieldstat *instance, int **metric_id_out, size_t *n_metric)
{
- int *tmp_ids = (int *)malloc(sizeof(int) * instance->manifest_cnt);
- *metric_id_out = tmp_ids;
- int cnt = 0;
- for (int i = 0; i < instance->manifest_cnt; i++) {
- if (instance->manifests[i] != NULL) {
- tmp_ids[cnt] = i;
- cnt ++;
- }
- }
- if (cnt == 0) {
- free(tmp_ids);
+ const struct metric_manifest **list = metric_manifest_manager_list(instance->manifest_manager, n_metric);
+ if (*n_metric == 0) {
*metric_id_out = NULL;
+ return;
+ }
+
+ int *tmp_ids = (int *)malloc(sizeof(int) * (*n_metric));
+ *metric_id_out = tmp_ids;
+
+ for (int i = 0; i < *n_metric; i++) {
+ tmp_ids[i] = list[i]->id;
}
- *n_metric = cnt;
}
struct fieldstat_tag_list *fieldstat_get_shared_tags(const struct fieldstat *instance, int cube_id)
@@ -680,10 +515,7 @@ void fieldstat_tag_list_arr_free(struct fieldstat_tag_list *tag_list, size_t n_c
const char *fieldstat_get_metric_name(const struct fieldstat *instance, int metric_id)
{
- if (metric_id < 0 || metric_id >= instance->manifest_cnt) {
- return NULL;
- }
- const struct metric_manifest *metric = instance->manifests[metric_id];
+ const struct metric_manifest *metric = metric_manifest_manager_get_by_id(instance->manifest_manager, metric_id);
if (metric == NULL) {
return NULL;
}
@@ -693,10 +525,7 @@ const char *fieldstat_get_metric_name(const struct fieldstat *instance, int metr
enum metric_type fieldstat_get_metric_type(const struct fieldstat *instance, int metric_id)
{
- if (instance == NULL || metric_id < 0 || metric_id >= instance->manifest_cnt) {
- return (enum metric_type)(-1);
- }
- const struct metric_manifest *metric = instance->manifests[metric_id];
+ const struct metric_manifest *metric = metric_manifest_manager_get_by_id(instance->manifest_manager, metric_id);
if (metric == NULL) {
return (enum metric_type)(-1);
}
diff --git a/src/metrics/metric.c b/src/metrics/metric.c
index d66444e..fc7c68b 100644
--- a/src/metrics/metric.c
+++ b/src/metrics/metric.c
@@ -260,7 +260,7 @@ static const struct metric_scheme g_metric_scheme_table[] = {
struct metric *metric_new(const struct metric_manifest *manifest)
{
struct metric *pthis = (struct metric *)calloc(1, sizeof(struct metric));
- pthis->data = g_metric_scheme_table[manifest->type].new(manifest->paras);
+ pthis->data = g_metric_scheme_table[manifest->type].new(manifest->parameters);
pthis->type = manifest->type;
return pthis;
diff --git a/src/metrics/metric_manifest.c b/src/metrics/metric_manifest.c
new file mode 100644
index 0000000..fd03209
--- /dev/null
+++ b/src/metrics/metric_manifest.c
@@ -0,0 +1,134 @@
+
+#include "metric_manifest.h"
+
+#define DEFAULT_N_METRIC 32
+
+struct metric_manifest; // defined in metric_manifest.h
+
+struct metric_manifest_manager {
+ struct metric_manifest *hash_table;
+
+ struct metric_manifest **manifests;
+ size_t manifest_size;
+ size_t manifest_cnt;
+};
+
+struct metric_manifest_manager *metric_manifest_manager_new() {
+ struct metric_manifest_manager *ret = calloc(1, sizeof(struct metric_manifest_manager));
+
+ ret->manifest_size = DEFAULT_N_METRIC;
+ ret->manifests = calloc(DEFAULT_N_METRIC, sizeof(struct metric_manifest *));
+ ret->manifest_cnt = 0;
+
+ return ret;
+}
+
+void metric_manifest_manager_free(struct metric_manifest_manager *pthis) {
+ struct metric_manifest *cur, *tmp;
+ HASH_ITER(hh, pthis->hash_table, cur, tmp) {
+ HASH_DEL(pthis->hash_table, cur);
+ }
+
+ for (size_t i = 0; i < pthis->manifest_cnt; i++) {
+ metric_manifest_free(pthis->manifests[i]);
+ }
+ free(pthis->manifests);
+ free(pthis);
+}
+
+const struct metric_manifest* metric_manifest_manager_get_by_id(const struct metric_manifest_manager *pthis, int metric_id) {
+ if (metric_id >= pthis->manifest_cnt || metric_id < 0) {
+ return NULL;
+ }
+ return pthis->manifests[metric_id];
+}
+
+const struct metric_manifest* metric_manifest_manager_get_by_name(const struct metric_manifest_manager *pthis, const char *name) {
+ struct metric_manifest *manifest = NULL;
+ HASH_FIND_STR(pthis->hash_table, name, manifest);
+ return manifest;
+}
+
+void add_manifest_to_position(struct metric_manifest_manager *pthis, struct metric_manifest *manifest, int metric_id)
+{
+ if (metric_id >= pthis->manifest_size) {
+ pthis->manifests = realloc(pthis->manifests, sizeof(struct metric_manifest *) * pthis->manifest_size * 2);
+ memset(pthis->manifests + pthis->manifest_size, 0, sizeof(struct metric_manifest *) * (pthis->manifest_size));
+ pthis->manifest_size *= 2;
+ }
+
+ pthis->manifests[metric_id] = manifest;
+ if (metric_id >= pthis->manifest_cnt) {
+ pthis->manifest_cnt = metric_id + 1;
+ }
+
+ HASH_ADD_KEYPTR(hh, pthis->hash_table, manifest->name, strlen(manifest->name), manifest);
+}
+
+int metric_manifest_manager_add(struct metric_manifest_manager *pthis, struct metric_manifest *manifest) {
+ struct metric_manifest *tmp;
+ HASH_FIND_STR(pthis->hash_table, manifest->name, tmp);
+ if (tmp != NULL) {
+ return -1;
+ }
+
+ int id = pthis->manifest_cnt;
+ add_manifest_to_position(pthis, manifest, id);
+
+ manifest->id = id;
+ return id;
+}
+
+const struct metric_manifest **metric_manifest_manager_list(const struct metric_manifest_manager *pthis, size_t *n_manifest) {
+ *n_manifest = pthis->manifest_cnt;
+ return (const struct metric_manifest **)pthis->manifests;
+}
+
+bool metric_manifest_manager_equal(const struct metric_manifest_manager *pthis, const struct metric_manifest_manager *other) {
+ if (pthis->manifest_cnt != other->manifest_cnt) {
+ return false;
+ }
+
+ for (size_t i = 0; i < pthis->manifest_cnt; i++) {
+ if (pthis->manifests[i]->type != other->manifests[i]->type) {
+ return false;
+ }
+ if (strcmp(pthis->manifests[i]->name, other->manifests[i]->name) != 0) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void metric_manifest_free(struct metric_manifest *manifest) {
+ free(manifest->name);
+ free(manifest->parameters);
+ free(manifest);
+}
+
+struct metric_manifest *metric_manifest_copy(const struct metric_manifest *src)
+{
+ struct metric_manifest *dest = (struct metric_manifest *)malloc(sizeof(struct metric_manifest));
+ dest->name = strdup(src->name);
+ if (src->parameters == NULL) {
+ dest->parameters = NULL;
+ } else {
+ dest->parameters = (union metric_parameter *)malloc(sizeof(union metric_parameter));
+ memcpy(dest->parameters, src->parameters, sizeof(union metric_parameter));
+ }
+
+ dest->type = src->type;
+ dest->id = src->id;
+
+ return dest;
+}
+
+struct metric_manifest_manager *metric_manifest_manager_copy(const struct metric_manifest_manager *pthis) {
+ struct metric_manifest_manager *ret = metric_manifest_manager_new();
+ for (size_t i = 0; i < pthis->manifest_cnt; i++) {
+ struct metric_manifest *manifest = metric_manifest_copy(pthis->manifests[i]);
+ metric_manifest_manager_add(ret, manifest);
+ }
+ return ret;
+}
diff --git a/src/metrics/metric_manifest.h b/src/metrics/metric_manifest.h
index 83d9ad7..632b314 100644
--- a/src/metrics/metric_manifest.h
+++ b/src/metrics/metric_manifest.h
@@ -1,23 +1,42 @@
#pragma once
-struct para_hdr{
+#include "uthash.h"
+#include "fieldstat.h"
+
+struct histogram_parameters {
long long lowest_trackable_value;
long long highest_trackable_value;
int significant_figures;
};
-struct para_hll {
+struct hll_parameters {
char precision;
};
union metric_parameter {
- struct para_hdr hdr;
- struct para_hll hll;
+ struct histogram_parameters hdr;
+ struct hll_parameters hll;
};
struct metric_manifest {
int id;
char *name;
- union metric_parameter *paras;
+ union metric_parameter *parameters;
enum metric_type type;
-}; \ No newline at end of file
+
+ UT_hash_handle hh;
+};
+
+struct metric_manifest *metric_manifest_copy(const struct metric_manifest *src);
+void metric_manifest_free(struct metric_manifest *pthis);
+
+struct metric_manifest_manager;
+
+struct metric_manifest_manager *metric_manifest_manager_new();
+void metric_manifest_manager_free(struct metric_manifest_manager *pthis);
+int metric_manifest_manager_add(struct metric_manifest_manager *pthis, struct metric_manifest *manifest);
+struct metric_manifest_manager *metric_manifest_manager_copy(const struct metric_manifest_manager *pthis);
+
+const struct metric_manifest **metric_manifest_manager_list(const struct metric_manifest_manager *pthis, size_t *n_manifest);
+const struct metric_manifest*metric_manifest_manager_get_by_id(const struct metric_manifest_manager *pthis, int metric_id);
+const struct metric_manifest*metric_manifest_manager_get_by_name(const struct metric_manifest_manager *pthis, const char *name); \ No newline at end of file
diff --git a/test/test_merge.cpp b/test/test_merge.cpp
index 8f88c80..42f87e0 100644
--- a/test/test_merge.cpp
+++ b/test/test_merge.cpp
@@ -517,7 +517,7 @@ TEST(unit_test_merge, primary_metric_id_different)
int metric_primary_dst = fieldstat_register_counter(instance_dst, "primary");
fieldstat_cube_set_primary_metric(instance_dst, cube_id_dst, metric_primary_dst);
- ASSERT_DEBUG_DEATH(fieldstat_merge(instance_dst, instance), ".*");
+ EXPECT_EQ(fieldstat_merge(instance_dst, instance), FS_ERR_INVALID_PARAM);
fieldstat_free(instance);
fieldstat_free(instance_dst);