diff options
Diffstat (limited to 'src/fieldstat.c')
| -rw-r--r-- | src/fieldstat.c | 1409 |
1 files changed, 165 insertions, 1244 deletions
diff --git a/src/fieldstat.c b/src/fieldstat.c index 376bc43..bb530f1 100644 --- a/src/fieldstat.c +++ b/src/fieldstat.c @@ -6,126 +6,36 @@ #include "cjson/cJSON.h" #include "uthash.h" -#include "serializer.h" + #include "fieldstat.h" #include "metrics/metric.h" -#include "tags/cell_manager.h" - -#define DEFAULT_N_METRIC 64 -#define DEFAULT_N_CUBE 128 - -struct fs_cube { - enum sampling_mode sampling_mode; - struct cell_manager *cell_manager; - size_t max_n_cell; - int next_cell_id; - int primary_metric_id; - - // the key of cube is the combination of shared tags - struct fieldstat_tag *shared_tags; - size_t n_shared_tags; - struct tag_hash_key *key_tag; - - struct metric **metrics; - size_t valid_metric_arr_len; - size_t max_n_metric; -}; - -struct metric_name_id_map { - char *name; - int id; - UT_hash_handle hh; -}; +#include "cube.h" struct fieldstat { - struct fs_cube **cube; - unsigned long *cube_version; // increase from 0 every time the cube is deleted - unsigned long cell_version; // increase from 0 every time fieldstat_reset is called - size_t valid_cube_arr_length; - size_t max_n_cube; - - struct metric **metric_masters; - size_t n_metric_master; - size_t max_n_metric_master; - struct metric_name_id_map *metric_name_id_map; - - struct cube_manager *shared_tag_cube_manager; + struct cube_manager *cube_manager; }; -int name_id_map_get_id_by_name(struct metric_name_id_map *map, const char *metric_name) -{ - struct metric_name_id_map *entry = NULL; - HASH_FIND_STR(map, metric_name, entry); - if (entry == NULL) { - return -1; - } - return entry->id; -} - -void name_id_map_add(struct metric_name_id_map **map, const char *name, int id) -{ - struct metric_name_id_map *entry = malloc(sizeof(struct metric_name_id_map)); - entry->id = id; - entry->name = strdup(name); - HASH_ADD_KEYPTR(hh, *map, entry->name, strlen(entry->name), entry); -} - -void name_id_map_free(struct metric_name_id_map *map) -{ - struct metric_name_id_map *entry, *tmp; - HASH_ITER(hh, map, entry, tmp) { - HASH_DEL(map, entry); - free(entry->name); - free(entry); - } -} - -struct metric_name_id_map *name_id_map_copy(struct metric_name_id_map *map) -{ - struct metric_name_id_map *map_dup = NULL; - struct metric_name_id_map *entry, *tmp; - HASH_ITER(hh, map, entry, tmp) { - name_id_map_add(&map_dup, entry->name, entry->id); - } - return map_dup; -} +/* -------------------------------------------------------------------------- */ +/* fieldstat */ +/* -------------------------------------------------------------------------- */ struct fieldstat *fieldstat_new() { struct fieldstat *instance = calloc(1, sizeof(struct fieldstat)); - instance->max_n_cube = DEFAULT_N_CUBE; - instance->cube = calloc(instance->max_n_cube, sizeof(struct fs_cube *)); - instance->cube_version = calloc(instance->max_n_cube, sizeof(unsigned long)); - - instance->max_n_metric_master = DEFAULT_N_METRIC; - instance->metric_masters = calloc(instance->max_n_metric_master, sizeof(struct metric *)); - instance->metric_name_id_map = NULL; - - instance->shared_tag_cube_manager = cube_manager_new(); + instance->cube_manager = cube_manager_new(); return instance; } -void fieldstat_cube_free(struct fieldstat *instance, int cube_id); void fieldstat_free(struct fieldstat *instance) { if (instance == NULL) { return; } - for (size_t i = 0; i < instance->valid_cube_arr_length; i++) { - fieldstat_cube_free(instance, i); - } - free(instance->cube); - free(instance->cube_version); - cube_manager_free(instance->shared_tag_cube_manager); - for (size_t i = 0; i < instance->n_metric_master; i++) { - metric_free(instance->metric_masters[i]); - } - free(instance->metric_masters); - name_id_map_free(instance->metric_name_id_map); + cube_manager_free(instance->cube_manager); free(instance); } @@ -135,772 +45,163 @@ void fieldstat_reset(struct fieldstat *instance) if (instance == NULL) { return; } - for (size_t i = 0; i < instance->valid_cube_arr_length; i++) { - struct fs_cube *cube = instance->cube[i]; - if (cube == NULL) { - continue; - } - for (size_t j = 0; j < cube->valid_metric_arr_len; j++) { - if (cube->metrics[j] == NULL) { - continue; - } - metric_reset(cube->metrics[j]); - } - - cell_manager_reset(cube->cell_manager); - } - instance->cell_version++; -} - -unsigned long fieldstat_get_version(const struct fieldstat *instance) -{ - if (instance == NULL) { - return 0; - } - return instance->cell_version; + cube_manager_reset(instance->cube_manager); } -int fieldstat_destroy_cube(struct fieldstat *instance, int cube_id) +int fieldstat_cube_destroy(struct fieldstat *instance, int cube_id) { - if (instance == NULL) { - return FS_ERR_NULL_HANDLER; - } - if (cube_id < 0 || cube_id >= instance->valid_cube_arr_length) { - return FS_ERR_INVALID_CUBE_ID; - } - if (instance->cube[cube_id] == NULL) { + struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); + if (cube == NULL) { return FS_ERR_INVALID_CUBE_ID; } - const struct fs_cube *cube = instance->cube[cube_id]; - cube_manager_delete(instance->shared_tag_cube_manager, cube->key_tag); - - fieldstat_cube_free(instance, cube_id); - - instance->cube[cube_id] = NULL; - instance->cube_version[cube_id]++; - return 0; -} - -long long fieldstat_get_cube_version(const struct fieldstat *instance, int cube_id) -{ - if (instance == NULL) { - return FS_ERR_NULL_HANDLER; - } - if (cube_id < 0 || cube_id >= instance->valid_cube_arr_length) { - return FS_ERR_INVALID_CUBE_ID; - } - if (instance->cube[cube_id] == NULL && instance->cube_version[cube_id] == 0) { - return FS_ERR_INVALID_CUBE_ID; - } + cube_manager_delete(instance->cube_manager, cube); - return instance->cube_version[cube_id]; + return FS_OK; } /* -------------------------------------------------------------------------- */ /* cube */ /* -------------------------------------------------------------------------- */ -void fieldstat_free_tag_array(struct fieldstat_tag *tags, size_t n_tags) -{ - for (size_t i = 0; i < n_tags; i++) { - struct fieldstat_tag *tag = &tags[i]; - free((char *)tag->key); - if (tag->type == TAG_CSTRING) { - free((char *)tag->value_str); - } - } - free(tags); -} - -void add_cube_to_position(struct fieldstat *instance, struct fs_cube *cube, int cube_id) -{ - if (cube_id >= instance->max_n_cube) { - instance->max_n_cube *= 2; - struct fs_cube **old_cube_arr = instance->cube; - instance->cube = calloc(instance->max_n_cube, sizeof(struct fs_cube *)); - memcpy(instance->cube, old_cube_arr, sizeof(struct fs_cube *) * instance->valid_cube_arr_length); - free(old_cube_arr); - - unsigned long *old_ver_arr = instance->cube_version; - instance->cube_version = calloc(instance->max_n_cube, sizeof(unsigned long)); - memcpy(instance->cube_version, old_ver_arr, sizeof(unsigned long) * instance->valid_cube_arr_length); - free(old_ver_arr); - } - instance->cube[cube_id] = cube; - if (cube_id >= instance->valid_cube_arr_length) { - instance->valid_cube_arr_length = cube_id + 1; - } -} - -int fieldstat_append_cube_to_instance(struct fieldstat *instance, struct fs_cube *cube) -{ - for (int i = 0; i < instance->valid_cube_arr_length; i++) { - if (instance->cube[i] == NULL) { - instance->cube[i] = cube; - cube_manager_add(instance->shared_tag_cube_manager, cube->key_tag, i); - return i; +// cppcheck-suppress [constParameterPointer, unmatchedSuppression] +int fieldstat_cube_set_sampling(struct fieldstat *instance, int cube_id, enum sampling_mode mode, int max_n_cell, int primary_metric_id) { + if (max_n_cell <= 0) { + if (mode != SAMPLING_MODE_COMPREHENSIVE) { + return FS_ERR_MAX_N_CELL_LESS_THAN_ZERO; + } else { + max_n_cell = INT32_MAX; } } - int cube_id = instance->valid_cube_arr_length; - add_cube_to_position(instance, cube, cube_id); - cube_manager_add(instance->shared_tag_cube_manager, cube->key_tag, cube_id); - - return cube_id; -} -struct fs_cube *fieldstat_cube_info_init(const struct fieldstat_tag *shared_tags, size_t n_tag, enum sampling_mode mode, size_t max_n_cell) -{ - struct fs_cube *cube = calloc(1, sizeof(struct fs_cube)); - cube->sampling_mode = mode; - cube->max_n_cell = max_n_cell; - if (n_tag == 0) { - cube->shared_tags = NULL; - } else { - cube->shared_tags = malloc(sizeof(struct fieldstat_tag) * n_tag); - for (int i = 0; i < n_tag; i++) { - struct fieldstat_tag *dest_tag = &cube->shared_tags[i]; - dest_tag->key = strdup(shared_tags[i].key); - dest_tag->type = shared_tags[i].type; - switch (dest_tag->type) - { - case TAG_INTEGER: - dest_tag->value_longlong = shared_tags[i].value_longlong; - break; - case TAG_CSTRING: - dest_tag->value_str = strdup(shared_tags[i].value_str); - break; - case TAG_DOUBLE: - dest_tag->value_double = shared_tags[i].value_double; - break; - - default: - break; - } - } + struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); + if (cube == NULL) { + return FS_ERR_INVALID_CUBE_ID; } - - cube->n_shared_tags = n_tag; - - struct tag_hash_key *shared_tag_key = malloc(sizeof(struct tag_hash_key)); - tag_hash_key_init_with_fieldstat_tag(shared_tag_key, shared_tags, n_tag, true); - cube->key_tag = shared_tag_key; - - cube->max_n_metric = 64; - cube->metrics = calloc(cube->max_n_metric, sizeof(struct metric *)); - - return cube; -} - -struct fs_cube *fieldstat_cube_new(const struct fieldstat_tag *shared_tags, size_t n_tag, enum sampling_mode mode, size_t max_n_cell) -{ - struct fs_cube *cube = fieldstat_cube_info_init(shared_tags, n_tag, mode, max_n_cell); - - cube->cell_manager = cell_manager_new(mode, max_n_cell); - - return cube; + + return cube_set_sampling(cube, mode, max_n_cell, primary_metric_id); } -int fieldstat_create_cube(struct fieldstat *instance, const struct fieldstat_tag *shared_tags, size_t n_tag, enum sampling_mode mode, size_t max_n_cell) +int fieldstat_cube_create(struct fieldstat *instance, const struct field *cube_dimensions, size_t n_dimension) { if (instance == NULL) { return FS_ERR_NULL_HANDLER; } - if (n_tag == 0 || shared_tags == NULL) { - shared_tags = NULL; - n_tag = 0; - } - if (mode == SAMPLING_MODE_TOPK && max_n_cell == 0) { - return FS_ERR_INVALID_PARAM; - } - if (max_n_cell == 0) { - max_n_cell = INT32_MAX; - } - struct tag_hash_key shared_tag_key; - tag_hash_key_init_with_fieldstat_tag(&shared_tag_key, shared_tags, n_tag, false); - int ret = cube_manager_find(instance->shared_tag_cube_manager, &shared_tag_key); - if (ret != -1) { - return FS_ERR_INVALID_KEY; - } - - struct fs_cube *cube = fieldstat_cube_new(shared_tags, n_tag, mode, max_n_cell); - - int cube_id = fieldstat_append_cube_to_instance(instance, cube); - - return cube_id; -} - -int fieldstat_cube_add(struct fieldstat *instance, int cube_id, const struct fieldstat_tag *tags, size_t n_tag, long long occurrence) -{ - struct fs_cube *cube = instance->cube[cube_id]; - - int ret = -1; - struct tag_hash_key tag_key; - - tag_hash_key_init_with_fieldstat_tag(&tag_key, tags, n_tag, false); - if (cube->sampling_mode == SAMPLING_MODE_COMPREHENSIVE) { - ret = cell_manager_add_cell(cube->cell_manager, &tag_key); - } else { - int popped_cell_id = -1; - ret = cell_manager_add_cell_topk(cube->cell_manager, &tag_key, occurrence, &popped_cell_id); - - if (popped_cell_id != -1) { - for (size_t i = 0; i < cube->valid_metric_arr_len; i++) { - if (cube->metrics[i] == NULL) { - continue; - } - metric_delete_cell(cube->metrics[i], popped_cell_id); - } - } + if (n_dimension == 0 || cube_dimensions == NULL) { + cube_dimensions = NULL; + n_dimension = 0; } + struct cube *cube = cube_new(cube_dimensions, n_dimension); + int ret = cube_manager_add(instance->cube_manager, cube); if (ret < 0) { - return -1; - } - return ret; -} - -void fieldstat_cube_free_contents(struct fieldstat *instance, int cube_id) -{ - struct fs_cube *cube = instance->cube[cube_id]; - - cell_manager_free(cube->cell_manager); - fieldstat_free_tag_array(cube->shared_tags, cube->n_shared_tags); - tag_hash_key_free(cube->key_tag); - - for (size_t i = 0; i < cube->valid_metric_arr_len; i++) { - if (cube->metrics[i] != NULL) { - metric_free(cube->metrics[i]); - } - } - free(cube->metrics); - - free(cube); - instance->cube[cube_id] = NULL; - - if (cube_id == instance->valid_cube_arr_length - 1) { - instance->valid_cube_arr_length--; - } -} - -void fieldstat_cube_free(struct fieldstat *instance, int cube_id) -{ - if (instance->cube[cube_id] == NULL) { - return; - } - - cube_manager_delete(instance->shared_tag_cube_manager, instance->cube[cube_id]->key_tag); - - fieldstat_cube_free_contents(instance, cube_id); -} - -struct fs_cube *fieldstat_cube_fork(const struct fs_cube *cube) { - struct fs_cube *ret = fieldstat_cube_new(cube->shared_tags, cube->n_shared_tags, cube->sampling_mode, cube->max_n_cell); - ret->primary_metric_id = cube->primary_metric_id; - - return ret; -} - -int fieldstat_cube_set_primary_metric(struct fieldstat *instance, int cube_id, int metric_id) -{ - if (instance == NULL) { - return FS_ERR_NULL_HANDLER; - } - if (cube_id < 0 || cube_id >= instance->valid_cube_arr_length) { - return FS_ERR_INVALID_CUBE_ID; + cube_free(cube); + return FS_ERR_DIMENSION_ALREADY_EXISTS; } - struct fs_cube *cube = instance->cube[cube_id]; - if (cube == NULL) { - return FS_ERR_INVALID_CUBE_ID; - } - if (cube->sampling_mode != SAMPLING_MODE_TOPK) { - return FS_ERR_INVALID_PARAM; - } - if (metric_id < 0 || metric_id >= instance->n_metric_master) { - return FS_ERR_INVALID_METRIC_ID; - } - if (instance->metric_masters[metric_id] == NULL) { - return FS_ERR_INVALID_METRIC_ID; - } - if (metric_get_type(instance->metric_masters[metric_id]) != METRIC_TYPE_COUNTER) { - return FS_ERR_INVALID_PARAM; - } - - cube->primary_metric_id = metric_id; - return FS_OK; + return ret; //ret is the cube_id } /* -------------------------------------------------------------------------- */ /* metric register */ /* -------------------------------------------------------------------------- */ - -void add_metric_to_cube(struct fs_cube *cube, struct metric *metric, int metric_id) -{ - if (metric_id >= cube->max_n_metric) { - cube->max_n_metric *= 2; - cube->metrics = realloc(cube->metrics, sizeof(struct metric *) * cube->max_n_metric); - memset(cube->metrics + cube->valid_metric_arr_len, 0, sizeof(struct metric *) * (cube->max_n_metric - cube->valid_metric_arr_len)); - } - - cube->metrics[metric_id] = metric; - if (metric_id >= cube->valid_metric_arr_len) { - cube->valid_metric_arr_len = metric_id + 1; - } -} - -void add_metric_to_instance(struct fieldstat *instance, const struct metric *metric, int metric_id) -{ - if (metric_id >= instance->max_n_metric_master) { - instance->max_n_metric_master *= 2; - instance->metric_masters = realloc(instance->metric_masters, sizeof(struct metric *) * instance->max_n_metric_master); - memset(instance->metric_masters + instance->n_metric_master, 0, sizeof(struct metric *) * (instance->max_n_metric_master - instance->n_metric_master)); - } - - instance->metric_masters[metric_id] = (struct metric *)metric; - if (metric_id >= instance->n_metric_master) { - instance->n_metric_master = metric_id + 1; - } - name_id_map_add(&instance->metric_name_id_map, metric_get_name(metric), metric_id); -} - -struct metric *find_or_add_metric(struct fieldstat *instance, int cube_id, int metric_id) { - struct fs_cube *cube = instance->cube[cube_id]; - if (metric_id < cube->valid_metric_arr_len && cube->metrics[metric_id] != NULL) { - return cube->metrics[metric_id]; - } - struct metric *metric = metric_fork(instance->metric_masters[metric_id]); - add_metric_to_cube(cube, metric, metric_id); - return metric; -} - -static int append_metric_to_instance(struct fieldstat *instance, const struct metric *metric) -{ - int metric_id = instance->n_metric_master; - add_metric_to_instance(instance, metric, metric_id); - - return metric_id; -} - -int check_before_register_metric(const struct fieldstat *instance, const char *metric_name) -{ - if (instance == NULL) { - return FS_ERR_NULL_HANDLER; - } - - if (name_id_map_get_id_by_name(instance->metric_name_id_map, metric_name) != -1) { - return FS_ERR_INVALID_KEY; - } - - return FS_OK; -} - -int fieldstat_register_counter(struct fieldstat *instance, const char *metric_name) +// cppcheck-suppress [constParameterPointer, unmatchedSuppression] +int fieldstat_register_counter(struct fieldstat *instance, int cube_id, const char *metric_name) { - int ret = check_before_register_metric(instance, metric_name); - if (ret != FS_OK) { - return ret; + struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); + if (cube == NULL) { + return FS_ERR_INVALID_CUBE_ID; } - - const struct metric *metric = metric_counter_new(metric_name); - - return append_metric_to_instance(instance, metric); + return cube_register_counter(cube, metric_name); } -int fieldstat_register_hll(struct fieldstat *instance, const char *metric_name, unsigned char precision) +// cppcheck-suppress [constParameterPointer, unmatchedSuppression] +int fieldstat_register_hll(struct fieldstat *instance, int cube_id, const char *metric_name, unsigned char precision) { - int ret = check_before_register_metric(instance, metric_name); - if (ret != FS_OK) { - return ret; - } - if (precision < 4 || precision > 18) { - return FS_ERR_INVALID_PARAM; + struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); + if (cube == NULL) { + return FS_ERR_INVALID_CUBE_ID; } - - const struct metric *metric = metric_hll_new(metric_name, precision); - - return append_metric_to_instance(instance, metric); + return cube_register_hll(cube, metric_name, precision); } -int fieldstat_register_hist(struct fieldstat *instance, const char *metric_name, long long lowest_trackable_value, long long highest_trackable_value, int significant_figures) +// cppcheck-suppress [constParameterPointer, unmatchedSuppression] +int fieldstat_register_histogram(struct fieldstat *instance, int cube_id, const char *metric_name, long long lowest_trackable_value, long long highest_trackable_value, int significant_figures) { - int ret = check_before_register_metric(instance, metric_name); - if (ret != FS_OK) { - return ret; - } - // refer to hdr_histogram.h for the rules of parameters. Just copy them here - if (lowest_trackable_value < 1) { - return FS_ERR_INVALID_PARAM; - } - if (significant_figures < 1 || significant_figures > 5) { - return FS_ERR_INVALID_PARAM; + struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); + if (cube == NULL) { + return FS_ERR_INVALID_CUBE_ID; } - if (lowest_trackable_value * 2 > highest_trackable_value) - { - return FS_ERR_INVALID_PARAM; - } - - const struct metric *metric = metric_histogram_new(metric_name, lowest_trackable_value, highest_trackable_value, significant_figures); - - return append_metric_to_instance(instance, metric); + return cube_register_hist(cube, metric_name, lowest_trackable_value, highest_trackable_value, significant_figures); } /* -------------------------------------------------------------------------- */ /* metric operation */ /* -------------------------------------------------------------------------- */ -static struct metric *fieldstat_find_metric(const struct fieldstat *instance, int cube_id, int metric_id, int *err_code) +// cppcheck-suppress [constParameterPointer, unmatchedSuppression] +int fieldstat_counter_incrby(struct fieldstat *instance, int cube_id, int metric_id, const struct field *cell_dimensions, size_t n_dimensions, long long increment) { - if (instance == NULL) { - *err_code = FS_ERR_NULL_HANDLER; - return NULL; - } - if (cube_id < 0 || cube_id >= instance->valid_cube_arr_length) { - *err_code = FS_ERR_INVALID_CUBE_ID; - return NULL; - } - struct fs_cube *cube = instance->cube[cube_id]; + struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); if (cube == NULL) { - *err_code = FS_ERR_INVALID_CUBE_ID; - return NULL; - } - - *err_code = FS_OK; - return cube->metrics[metric_id]; -} - -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_id < 0 || cube_id >= instance->valid_cube_arr_length) { return FS_ERR_INVALID_CUBE_ID; } - if (instance->cube[cube_id] == NULL) { - return FS_ERR_INVALID_CUBE_ID; - } - - if (metric_id < 0 || metric_id >= instance->n_metric_master) { - return FS_ERR_INVALID_METRIC_ID; - } - const struct metric *metric = instance->metric_masters[metric_id]; - if (metric == NULL || metric_get_type(metric) != type) { - 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; - } - const struct fs_cube *cube = instance->cube[cube_id]; - long long occurrence = 0; - if (cube->sampling_mode == SAMPLING_MODE_TOPK && cube->primary_metric_id == metric_id) { - if (increment < 0) { - return FS_ERR_INVALID_PARAM; - } - - occurrence = increment; - } - - int cell_id = fieldstat_cube_add(instance, cube_id, tags, n_tag, occurrence); - if (cell_id < 0) { - return FS_ERR_TOO_MANY_CELLS; - } - - struct metric *metric = find_or_add_metric(instance, cube_id, metric_id); - - metric_counter_incrby(metric, cell_id, increment); - return FS_OK; -} - -int fieldstat_counter_incrby_batch(struct fieldstat *instance, int cube_id, int metric_ids[], const struct fieldstat_tag *tags, size_t n_tag, long long increments[], int n_metric) -{ - int ret = check_before_add(instance, cube_id, metric_ids[0], METRIC_TYPE_COUNTER); - if (ret != FS_OK) { - return ret; - } - const struct fs_cube *cube = instance->cube[cube_id]; - long long occurrence = 0; - if (cube->sampling_mode == SAMPLING_MODE_TOPK) { - for (int i = 0; i < n_metric; i++) { - if (metric_ids[i] == cube->primary_metric_id) { - if (increments[i] < 0) { - return FS_ERR_INVALID_PARAM; - } - occurrence += increments[i]; - } - } - } - int cell_id = fieldstat_cube_add(instance, cube_id, tags, n_tag, occurrence); - if (cell_id < 0) { - return FS_ERR_TOO_MANY_CELLS; - } - - for (int i = 0; i < n_metric; i++) { - struct metric *metric = find_or_add_metric(instance, cube_id, metric_ids[i]); - metric_counter_incrby(metric, cell_id, increments[i]); - } - return FS_OK; -} - -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; - } - const struct fs_cube *cube = instance->cube[cube_id]; - struct metric *metric = find_or_add_metric(instance, cube_id, metric_id); - int cell_id = -1; - - // get the occurrence - long long occurrence = 0; - if (cube->sampling_mode == SAMPLING_MODE_TOPK && cube->primary_metric_id == metric_id) { - struct tag_hash_key tag_key; - tag_hash_key_init_with_fieldstat_tag(&tag_key, tags, n_tag, false); - cell_id = cell_manager_find(cube->cell_manager, &tag_key); - if (cell_id >= 0) { - long long old_value; - int exist_flag = metric_counter_get(metric, cell_id, &old_value); - if (exist_flag == 0) { // cell already exist in metric - occurrence = value - old_value; - } else { - occurrence = value; - } - } else { - occurrence = value; - } - if (occurrence < 0) { - return FS_ERR_INVALID_PARAM; - } - } - - cell_id = fieldstat_cube_add(instance, cube_id, tags, n_tag, occurrence); - if (cell_id < 0) { - return FS_ERR_TOO_MANY_CELLS; - } - metric_counter_set(metric, cell_id, value); - return 0; + return cube_counter_incrby(cube, metric_id, cell_dimensions, n_dimensions, increment); } -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) +// cppcheck-suppress [constParameterPointer, unmatchedSuppression] +int fieldstat_counter_set(struct fieldstat *instance, int cube_id, int metric_id, const struct field *cell_dimensions, size_t n_dimensions, long long value) { - int ret = check_before_add(instance, cube_id, metric_id, METRIC_TYPE_HLL); - if (ret != FS_OK) { - return ret; - } - if (instance->cube[cube_id]->sampling_mode == SAMPLING_MODE_TOPK) { - return FS_ERR_INVALID_PARAM; - } - int cell_id = fieldstat_cube_add(instance, cube_id, tags, n_tag, 0); - if (cell_id < 0) { - return FS_ERR_TOO_MANY_CELLS; - } - struct metric *metric = find_or_add_metric(instance, cube_id, metric_id); - - metric_hll_add(metric, cell_id, key, key_len); - return 0; -} - -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; - } - if (instance->cube[cube_id]->sampling_mode == SAMPLING_MODE_TOPK) { - return FS_ERR_INVALID_PARAM; - } - - int cell_id = fieldstat_cube_add(instance, cube_id, tags, n_tag, 0); - if (cell_id < 0) { - return FS_ERR_TOO_MANY_CELLS; + struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); + if (cube == NULL) { + return FS_ERR_INVALID_CUBE_ID; } - struct metric *metric = find_or_add_metric(instance, cube_id, metric_id); - ret = metric_histogram_record(metric, cell_id, value); - if (ret < 0) { // it's ok not to recover the cell and metrics even if they are new ones, since unused ones will not be exported. - return FS_ERR_INVALID_PARAM; - } - return 0; + return cube_counter_set(cube, metric_id, cell_dimensions, n_dimensions, value); } - -/* -------------------------------------------------------------------------- */ -/* merge */ -/* -------------------------------------------------------------------------- */ - -struct fs_cube *fieldstat_cube_dup(const struct fs_cube *cube, const int *metric_id_map) +// cppcheck-suppress [constParameterPointer, unmatchedSuppression] +int fieldstat_hll_add(struct fieldstat *instance, int cube_id, int metric_id, const struct field *cell_dimensions, size_t n_dimensions, const char *key, size_t key_len) { - struct fs_cube *cube_dup = fieldstat_cube_info_init(cube->shared_tags, cube->n_shared_tags, cube->sampling_mode, cube->max_n_cell); - const struct cell_manager *cm_src = cube->cell_manager; - - struct cell_manager *cm_dup = cell_manager_copy(cm_src); - cube_dup->cell_manager = cm_dup; - cube_dup->primary_metric_id = metric_id_map[cube->primary_metric_id]; - - for (int i = 0; i < cube->valid_metric_arr_len; i ++) { - if (cube->metrics[i] == NULL) { - continue; - } - struct metric *metric_dup = metric_copy(cube->metrics[i]); - add_metric_to_cube(cube_dup, metric_dup, metric_id_map[i]); + 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_dup; -} - -void fieldstat_cube_merge_comprehensive(struct fs_cube *dest, const struct fs_cube *src, const int *metric_id_src_dest_map) -{ - const struct cell_manager *cell_manager_src = src->cell_manager; - struct cell_manager *cell_manager_dest = dest->cell_manager; - - int arr_len_src = 0; - const struct tag_hash_key **tag_arr_src = cell_manager_dump(cell_manager_src, &arr_len_src); - for (int cell_id_src = 0; cell_id_src < arr_len_src; cell_id_src++) { - const struct tag_hash_key *tag_src = tag_arr_src[cell_id_src]; - if (tag_src == NULL) { - continue; - } - int cell_id_final = cell_manager_add_cell(cell_manager_dest, tag_src); - if (cell_id_final == -1) { // dest is full - break; - } - for (int metric_id_src = 0; metric_id_src < src->valid_metric_arr_len; metric_id_src++) { - if (src->metrics[metric_id_src] == NULL) { - continue; - } - int metric_id_dest = metric_id_src_dest_map[metric_id_src]; - (void)metric_merge_or_copy_cell(dest->metrics[metric_id_dest], src->metrics[metric_id_src], cell_id_final, cell_id_src); - } - } + return cube_hll_add(cube, metric_id, cell_dimensions, n_dimensions, key, key_len); } -void fieldstat_cube_merge_topk(struct fs_cube *dest, const struct fs_cube *src, const int *metric_id_src_dest_map) +// cppcheck-suppress [constParameterPointer, unmatchedSuppression] +int fieldstat_hll_add_field(struct fieldstat *instance, int cube_id, int metric_id, const struct field *cell_dimensions, size_t n_dimensions, const struct field *item, size_t item_len) { - const struct cell_manager *cell_manager_src = src->cell_manager; - struct cell_manager *cell_manager_dest = dest->cell_manager; - int *cell_id_added = NULL; - int *cell_id_old = NULL; - int n_cell_id_added = 0; - int *cell_id_popped = NULL; - int n_cell_id_popped = 0; - - cell_manager_merge_topk(cell_manager_dest, cell_manager_src, &cell_id_popped, &n_cell_id_popped, &cell_id_old, &cell_id_added, &n_cell_id_added); - - for (int i = 0; i < n_cell_id_added; i++) { - int tmp_id_dest = cell_id_added[i]; - int tmp_id_src = cell_id_old[i]; - - for (int j = 0; j < src->valid_metric_arr_len; j++) { - if (src->metrics[j] == NULL) { - continue; - } - int metric_id_dest = metric_id_src_dest_map[j]; - metric_merge_or_copy_cell(dest->metrics[metric_id_dest], src->metrics[j], tmp_id_dest, tmp_id_src); - } - } - // chances are that: a cell exists in both dest and src, but it is not in final. In this case, these cells are both in cell_id_added and cell_id_popped. - // Since all cells are counter, which is easy to merge, we just delete these cells after merging them. - for (int i = 0; i < n_cell_id_popped;i++) { - int id = cell_id_popped[i]; - - for (int j = 0; j < dest->valid_metric_arr_len; j++) { - if (dest->metrics[j] == NULL) { - continue; - } - metric_delete_cell(dest->metrics[j], id); - } + struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); + if (cube == NULL) { + return FS_ERR_INVALID_CUBE_ID; } - free(cell_id_popped); - free(cell_id_added); - free(cell_id_old); + return cube_hll_add_field(cube, metric_id, cell_dimensions, n_dimensions, item, item_len); } -void fieldstat_cube_merge(struct fs_cube *dest, const struct fs_cube *src, const int *metric_id_src_dest_map) +// cppcheck-suppress [constParameterPointer, unmatchedSuppression] +int fieldstat_histogram_record(struct fieldstat *instance, int cube_id, int metric_id, const struct field *cell_dimensions, size_t n_dimensions, long long value) { - for (int metric_id_src = 0; metric_id_src < src->valid_metric_arr_len; metric_id_src++) { - if (src->metrics[metric_id_src] == NULL) { - continue; - } - - int metric_id_dest = metric_id_src_dest_map[metric_id_src]; - if (dest->metrics[metric_id_dest] != NULL) { - continue; - } - - struct metric *metric_dest = metric_fork(src->metrics[metric_id_src]); - add_metric_to_cube(dest, metric_dest, metric_id_dest); + struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); + if (cube == NULL) { + return FS_ERR_INVALID_CUBE_ID; } - if (dest->sampling_mode == SAMPLING_MODE_COMPREHENSIVE) { - return fieldstat_cube_merge_comprehensive(dest, src, metric_id_src_dest_map); - } - fieldstat_cube_merge_topk(dest, src, metric_id_src_dest_map); + return cube_histogram_record(cube, metric_id, cell_dimensions, n_dimensions, 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_id_src_dest_map[src->n_metric_master]; // every metric <src_id> in src move to metric_id_src_dest_map[<src_id>] in dst instance - for (int metric_id_src = 0; metric_id_src < src->n_metric_master; metric_id_src++) { - const char *name_src = metric_get_name(src->metric_masters[metric_id_src]); - int metric_id_dst = name_id_map_get_id_by_name(instance->metric_name_id_map, name_src); - if (metric_id_dst == -1) { - metric_id_dst = append_metric_to_instance(instance, metric_fork(src->metric_masters[metric_id_src])); - name_id_map_add(&instance->metric_name_id_map, name_src, metric_id_dst); - } - metric_id_src_dest_map[metric_id_src] = metric_id_dst; - } - - size_t n_cube_src = src->valid_cube_arr_length; - const struct cube_manager *tag_cube_id_map = instance->shared_tag_cube_manager; - int ret = 0; - for (int i = 0; i < n_cube_src; i++) { - const struct fs_cube *cube_src = src->cube[i]; - if (cube_src == NULL) { - continue; - } - - const struct tag_hash_key *shared_tag_key_src = cube_src->key_tag; - int cube_id_tmp = cube_manager_find(tag_cube_id_map, shared_tag_key_src); - if (cube_id_tmp == -1) { - struct fs_cube *copied_cube = fieldstat_cube_dup(cube_src, metric_id_src_dest_map); - fieldstat_append_cube_to_instance(instance, copied_cube); - } else { - struct fs_cube *cube_dst = instance->cube[cube_id_tmp]; - if (cube_dst->sampling_mode != cube_src->sampling_mode) { - ret = FS_ERR_INVALID_PARAM; - continue; - } - if (cube_dst->sampling_mode == SAMPLING_MODE_TOPK && strcmp( - metric_get_name(instance->metric_masters[cube_dst->primary_metric_id]), - metric_get_name(src->metric_masters[cube_src->primary_metric_id]) - ) != 0) { - printf("primary metric name not match, name instance: %s, name src: %s\n", - metric_get_name(instance->metric_masters[cube_dst->primary_metric_id]), - metric_get_name(src->metric_masters[cube_src->primary_metric_id])); - ret = FS_ERR_INVALID_PARAM; - continue; - } - fieldstat_cube_merge(cube_dst, cube_src, metric_id_src_dest_map); - } - } - - return ret; + return cube_manager_merge(instance->cube_manager, src->cube_manager); } struct fieldstat *fieldstat_fork(const struct fieldstat *instance) @@ -909,132 +210,14 @@ struct fieldstat *fieldstat_fork(const struct fieldstat *instance) return NULL; } struct fieldstat *new_instance = calloc(1, sizeof(struct fieldstat)); - new_instance->shared_tag_cube_manager = cube_manager_new(); - - new_instance->valid_cube_arr_length = instance->valid_cube_arr_length; - new_instance->max_n_cube = instance->max_n_cube; - new_instance->cube = calloc(new_instance->max_n_cube, sizeof(struct fs_cube *)); - for (size_t i = 0; i < new_instance->valid_cube_arr_length; i++) { - struct fs_cube *cube = instance->cube[i]; - if (cube == NULL) { - continue; - } - new_instance->cube[i] = fieldstat_cube_fork(cube); - cube_manager_add(new_instance->shared_tag_cube_manager, cube->key_tag, i); - // copy registered metrics - for (size_t j = 0; j < cube->valid_metric_arr_len; j++) { - const struct metric *metric = cube->metrics[j]; - if (metric == NULL) { - continue; - } - struct metric *new_metric = metric_fork(metric); - add_metric_to_cube(new_instance->cube[i], new_metric, j); - } - } - new_instance->cube_version = calloc(new_instance->max_n_cube, sizeof(unsigned long)); - memcpy(new_instance->cube_version, instance->cube_version, sizeof(unsigned long) * new_instance->max_n_cube); - - new_instance->metric_masters = calloc(instance->max_n_metric_master, sizeof(struct metric *)); - new_instance->max_n_metric_master = instance->max_n_metric_master; - new_instance->n_metric_master = instance->n_metric_master; - for (size_t i = 0; i < instance->n_metric_master; i++) { - new_instance->metric_masters[i] = metric_fork(instance->metric_masters[i]); - } - new_instance->metric_name_id_map = name_id_map_copy(instance->metric_name_id_map); + new_instance->cube_manager = cube_manager_fork(instance->cube_manager); return new_instance; } -void calibrate_metrics_in_instance(const struct fieldstat *master, struct fieldstat *replica) +void fieldstat_calibrate(const struct fieldstat *master, struct fieldstat *replica) { - if (replica->max_n_metric_master < master->max_n_metric_master) { - replica->metric_masters = (struct metric **)realloc(replica->metric_masters, sizeof(struct metric *) * master->max_n_metric_master); - memset(replica->metric_masters + replica->max_n_metric_master, 0, sizeof(struct metric *) * (master->max_n_metric_master - replica->max_n_metric_master)); - replica->max_n_metric_master = master->max_n_metric_master; - } - - size_t longer_arr_len = master->n_metric_master > replica->n_metric_master ? master->n_metric_master : replica->n_metric_master; - for (size_t i = 0; i < longer_arr_len; i++) { - const struct metric *metric_master = i >= master->n_metric_master ? NULL : master->metric_masters[i]; - struct metric *metric_target = i >= replica->n_metric_master ? NULL : replica->metric_masters[i]; - if (metric_master == NULL && metric_target == NULL) { - continue; - } - if (metric_master == NULL && metric_target != NULL) { - metric_free(metric_target); - replica->metric_masters[i] = NULL; - continue; - } - if (metric_master != NULL && metric_target == NULL) { - const struct metric *metric_dup = metric_fork(metric_master); - add_metric_to_instance(replica, metric_dup, i); - continue; - } - if (metric_get_type(metric_master) != metric_get_type(metric_target) || - strcmp(metric_get_name(metric_master), metric_get_name(metric_target)) != 0 - ) { - metric_free(metric_target); - const struct metric *metric_dup = metric_fork(metric_master); - add_metric_to_instance(replica, metric_dup, i); - continue; - } - - // metric same, no need to do anything - } - - replica->n_metric_master = master->n_metric_master; -} - -int fieldstat_calibrate(const struct fieldstat *master, struct fieldstat *replica) -{ - if (master == NULL || replica == NULL) { - return FS_ERR_NULL_HANDLER; - } - - if (replica->max_n_cube < master->max_n_cube) { - replica->cube = (struct fs_cube **)realloc(replica->cube, sizeof(struct fs_cube *) * master->max_n_cube); - memset(replica->cube + replica->max_n_cube, 0, sizeof(struct fs_cube *) * (master->max_n_cube - replica->max_n_cube)); - replica->cube_version = (unsigned long *)realloc(replica->cube_version, sizeof(unsigned long) * master->max_n_cube); - memset(replica->cube_version + replica->max_n_cube, 0, sizeof(unsigned long) * (master->max_n_cube - replica->max_n_cube)); - replica->max_n_cube = master->max_n_cube; - } - - size_t len_master = master->valid_cube_arr_length; - size_t len_replica = replica->valid_cube_arr_length; - size_t longer_arr_len = len_master > len_replica ? len_master : len_replica; - for (size_t i = 0; i < longer_arr_len; i++) { - const struct fs_cube *cube_master = i >= len_master ? NULL : master->cube[i]; - const struct fs_cube *cube_target = i >= len_replica ? NULL : replica->cube[i]; - - if (cube_master == NULL && cube_target == NULL) { - continue; - } - if (cube_master == NULL && cube_target != NULL) { - fieldstat_cube_free_contents(replica, i); - continue; - } - if (cube_master != NULL && cube_target == NULL) { - struct fs_cube *cube_dup = fieldstat_cube_fork(cube_master); - add_cube_to_position(replica, cube_dup, i); - continue; - } - - if (master->cube_version[i] == replica->cube_version[i] && tag_hash_key_cmp(cube_master->key_tag, cube_target->key_tag) == 0) { - continue; - } - - fieldstat_cube_free_contents(replica, i); - struct fs_cube *cube_dup = fieldstat_cube_fork(cube_master); - add_cube_to_position(replica, cube_dup, i); - } - - memcpy(replica->cube_version, master->cube_version, sizeof(unsigned long) * master->max_n_cube); - replica->valid_cube_arr_length = master->valid_cube_arr_length; - - cube_manager_calibrate(replica->shared_tag_cube_manager, master->shared_tag_cube_manager); - calibrate_metrics_in_instance(master, replica); - - return FS_OK; + cube_manager_calibrate(replica->cube_manager, master->cube_manager); } /* -------------------------------------------------------------------------- */ @@ -1042,374 +225,128 @@ int fieldstat_calibrate(const struct fieldstat *master, struct fieldstat *replic /* -------------------------------------------------------------------------- */ void fieldstat_get_cubes(const struct fieldstat *instance, int **cube_ids, int *n_cube) { - if (instance == NULL || instance->valid_cube_arr_length == 0) { - *cube_ids = NULL; - *n_cube = 0; - return; - } - int all_available_cube_count = 0; - - int *tmp_ids = (int *)malloc(sizeof(int) * instance->valid_cube_arr_length); - for (int i = 0; i < instance->valid_cube_arr_length; i++) { - const struct fs_cube *tmp_cube = instance->cube[i]; - if (tmp_cube == NULL) { - continue; - } - tmp_ids[all_available_cube_count] = i; - all_available_cube_count ++; - } - if (all_available_cube_count == 0) { - free(tmp_ids); - *cube_ids = NULL; - *n_cube = 0; - return; - } - - *cube_ids = (int *)malloc(sizeof(int) * all_available_cube_count); - memcpy(*cube_ids, tmp_ids, sizeof(int) * all_available_cube_count); - *n_cube = all_available_cube_count; - - free(tmp_ids); + cube_manager_list(instance->cube_manager, cube_ids, n_cube); } -int fieldstat_get_metrics_used_by_cube(const struct fieldstat *instance, int cube_id, int **metric_id_out, size_t *n_metric) +struct field_list *fieldstat_cube_get_dimensions(const struct fieldstat *instance, int cube_id) { - *metric_id_out = NULL; - *n_metric = 0; - if (instance == NULL) { - return FS_ERR_NULL_HANDLER; - } - if (cube_id >= instance->valid_cube_arr_length || cube_id < 0) { - return FS_ERR_INVALID_CUBE_ID; - } - const struct fs_cube *cube = instance->cube[cube_id]; + const struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); if (cube == NULL) { - return FS_ERR_INVALID_CUBE_ID; - } - - int all_available_metric_count = 0; - if (cube->valid_metric_arr_len == 0) { - return FS_OK; - } - int *tmp_ids = (int *)malloc(sizeof(int) * cube->valid_metric_arr_len); - for (int i = 0; i < cube->valid_metric_arr_len; i++) { - const struct metric *tmp_metric = cube->metrics[i]; - if (tmp_metric == NULL) { - continue; - } - tmp_ids[all_available_metric_count] = i; - all_available_metric_count ++; - } - if (all_available_metric_count == 0) { - free(tmp_ids); - return FS_OK; - } - - *metric_id_out = tmp_ids; - *n_metric = all_available_metric_count; - - return FS_OK; -} - -void fieldstat_get_metrics(const struct fieldstat *instance, int **metric_id_out, size_t *n_metric) -{ - if (instance == NULL || instance->n_metric_master == 0) { - *metric_id_out = NULL; - *n_metric = 0; - return; - } - - int *tmp_ids = (int *)malloc(sizeof(int) * instance->n_metric_master); - *metric_id_out = tmp_ids; - *n_metric = instance->n_metric_master; - for (int i = 0; i < instance->n_metric_master; i++) { - tmp_ids[i] = i; + return NULL; } - - return; + + return cube_get_identifier(cube); } -void fieldstat_get_cells_used_by_metric(const struct fieldstat *instance, int cube_id, int metric_id, - struct fieldstat_tag_list **tag_list, size_t *n_cell) +int fieldstat_counter_get(const struct fieldstat *instance, int cube_id, const struct field_list *cell_dimensions, int metric_id, long long *value) { - *tag_list = NULL; - *n_cell = 0; - int ret = FS_OK; - const struct metric *metric = fieldstat_find_metric(instance, cube_id, metric_id, &ret); - if (metric == NULL) { - return; - } - - size_t n_cell_ret = 0; - int *cell_ids = NULL; - metric_get_cell_ids(metric, &cell_ids, &n_cell_ret); - if (n_cell_ret == 0) { - return; - } - *n_cell = n_cell_ret; - - struct fieldstat_tag_list *tag_list_ret = (struct fieldstat_tag_list *)malloc(sizeof(struct fieldstat_tag_list) * n_cell_ret); - *tag_list = tag_list_ret; - for (int i = 0; i < n_cell_ret; i++) { - const struct tag_hash_key *tag_key = cell_manager_get_tag_by_cell_id(instance->cube[cube_id]->cell_manager, cell_ids[i]); - if (tag_key == NULL) { - continue; - } - tag_hash_key_convert_to_fieldstat_tag(tag_key, &(tag_list_ret[i].tag), &(tag_list_ret[i].n_tag)); + const struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); + if (cube == NULL) { + return FS_ERR_INVALID_CUBE_ID; } - - free(cell_ids); + + return cube_counter_get(cube, metric_id, cell_dimensions, value); } -struct fieldstat_tag_list *fieldstat_get_shared_tags(const struct fieldstat *instance, int cube_id) +int fieldstat_hll_get(const struct fieldstat *instance, int cube_id, const struct field_list *cell_dimensions, int metric_id, double *value) { - if (instance == NULL || cube_id >= instance->valid_cube_arr_length || cube_id < 0) { - return NULL; - } - struct fs_cube *cube = instance->cube[cube_id]; + const struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); if (cube == NULL) { - return NULL; - } - - struct fieldstat_tag_list *tag_list = (struct fieldstat_tag_list *)malloc(sizeof(struct fieldstat_tag_list)); - - if (cube->n_shared_tags == 0) { - tag_list->tag = NULL; - tag_list->n_tag = 0; - return tag_list; - } - - tag_list->tag = (struct fieldstat_tag *)malloc(sizeof(struct fieldstat_tag) * cube->n_shared_tags); - for (int i = 0; i < cube->n_shared_tags; i++) { - struct fieldstat_tag *tag_dest = &(tag_list->tag[i]); - struct fieldstat_tag *tag_src = &(cube->shared_tags[i]); - tag_dest->key = strdup(tag_src->key); - tag_dest->type = tag_src->type; - switch (tag_src->type) { - case TAG_INTEGER: - tag_dest->value_longlong = tag_src->value_longlong; - break; - case TAG_CSTRING: - tag_dest->value_str = strdup(tag_src->value_str); - break; - case TAG_DOUBLE: - tag_dest->value_double = tag_src->value_double; - break; - default: - break; - } + return FS_ERR_INVALID_CUBE_ID; } - tag_list->n_tag = cube->n_shared_tags; - - return tag_list; -} + + int ret = cube_hll_get(cube, metric_id, cell_dimensions, value); -int get_cell_id_by_tag_list(const struct fieldstat *instance, int cube_id, const struct fieldstat_tag_list *tags) -{ - struct tag_hash_key tag_key; - tag_hash_key_init_with_fieldstat_tag(&tag_key, tags->tag, tags->n_tag, false); - int cell_id = cell_manager_find(instance->cube[cube_id]->cell_manager, &tag_key); - return cell_id; + return ret; } -int fieldstat_counter_get(const struct fieldstat *instance, int cube_id, int metric_id, const struct fieldstat_tag_list *tags, long long *value) +long long fieldstat_histogram_value_at_percentile(const struct fieldstat *instance, int cube_id, const struct field_list *cell_dimensions, int metric_id, double percentile) { - int ret; - *value = 0; - const struct metric *metric = fieldstat_find_metric(instance, cube_id, metric_id, &ret); - if (ret != FS_OK) { - return ret; - } - - if (metric == NULL || metric_get_type(metric) != METRIC_TYPE_COUNTER) { - return FS_ERR_INVALID_METRIC_ID; - } - - int cell_id = get_cell_id_by_tag_list(instance, cube_id, tags); - if (cell_id == -1) { - return FS_ERR_INVALID_TAG; + const struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); + if (cube == NULL) { + return FS_ERR_INVALID_CUBE_ID; } - - ret = metric_counter_get(metric, cell_id, value); + long long value; + int ret = cube_histogram_value_at_percentile(cube, metric_id, cell_dimensions, percentile, &value); if (ret < 0) { - return FS_ERR_INVALID_TAG; - } - - return FS_OK; -} - -int fieldstat_hll_get(const struct fieldstat *instance, int cube_id, int metric_id, const struct fieldstat_tag_list *tags, double *value) -{ - int ret; - const struct metric *metric = fieldstat_find_metric(instance, cube_id, metric_id, &ret); - if (ret != FS_OK) { return ret; } - if (metric == NULL || metric_get_type(metric) != METRIC_TYPE_HLL) { - return FS_ERR_INVALID_METRIC_ID; - } - - int cell_id = get_cell_id_by_tag_list(instance, cube_id, tags); - if (cell_id == -1) { - return FS_ERR_INVALID_TAG; - } - - double ret2 = metric_hll_get(metric, cell_id); - if (ret2 < 0) { - return FS_ERR_INVALID_TAG; - } - *value = ret2; - return FS_OK; + return value; } -long long fieldstat_hist_value_at_percentile(const struct fieldstat *instance, int cube_id, int metric_id, const struct fieldstat_tag_list *tags, double percentile) +long long fieldstat_histogram_count_le_value(const struct fieldstat *instance, int cube_id, const struct field_list *cell_dimensions, int metric_id, long long value) { - int ret; - const struct metric *metric = fieldstat_find_metric(instance, cube_id, metric_id, &ret); - if (ret != FS_OK) { - return ret; - } - if (metric == NULL || metric_get_type(metric) != METRIC_TYPE_HISTOGRAM) { - return FS_ERR_INVALID_METRIC_ID; - } - - int cell_id = get_cell_id_by_tag_list(instance, cube_id, tags); - if (cell_id == -1) { - return FS_ERR_INVALID_TAG; - } - long long ret2 = metric_histogram_value_at_percentile(metric, cell_id, percentile); - if (ret2 < 0) { - return FS_ERR_INVALID_TAG; + const struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); + if (cube == NULL) { + return FS_ERR_INVALID_CUBE_ID; } - - return ret2; -} - -long long fieldstat_hist_count_le_value(const struct fieldstat *instance, int cube_id, int metric_id, const struct fieldstat_tag_list *tags, long long value) -{ - int ret; - const struct metric *metric = fieldstat_find_metric(instance, cube_id, metric_id, &ret); - if (ret != FS_OK) { + long long count; + int ret = cube_histogram_count_le_value(cube, metric_id, cell_dimensions, value, &count); + if (ret < 0) { return ret; } - if (metric == NULL || metric_get_type(metric) != METRIC_TYPE_HISTOGRAM) { - return FS_ERR_INVALID_METRIC_ID; - } - - int cell_id = get_cell_id_by_tag_list(instance, cube_id, tags); - if (cell_id == -1) { - return FS_ERR_INVALID_TAG; - } - - long long ret2 = metric_histogram_count_le_value(metric, cell_id, value); - if (ret2 < 0) { - return FS_ERR_INVALID_TAG; - } - - return ret2; + return count; } -void fieldstat_get_serialized_blob(const struct fieldstat *instance, int cube_id, int metric_id, const struct fieldstat_tag_list *tags, char **blob, size_t *blob_size) +void fieldstat_metric_get_serialization_as_base64(const struct fieldstat *instance, int cube_id, int metric_id, const struct field_list *cell_dimensions, char **blob, size_t *blob_size) { - *blob = NULL; - *blob_size = 0; - int ret; - const struct metric *metric = fieldstat_find_metric(instance, cube_id, metric_id, &ret); - if (ret != FS_OK) { - return; - } - if (metric == NULL) { - return; - } - enum metric_type type = metric_get_type(metric); - if (!(type == METRIC_TYPE_HLL || type == METRIC_TYPE_HISTOGRAM)) { - return; - } - - int cell_id = get_cell_id_by_tag_list(instance, cube_id, tags); - if (cell_id == -1) { + const struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); + if (cube == NULL) { + *blob = NULL; + *blob_size = 0; return; } - metric_get_plain_blob(metric, cell_id, blob, blob_size); + cube_get_serialization_as_base64(cube, metric_id, cell_dimensions, blob, blob_size); } -void fieldstat_tag_list_arr_free(struct fieldstat_tag_list *tag_list, size_t n_cell) +void fieldstat_field_list_arr_free(struct field_list *field_lists, size_t n_field_list) { - if (tag_list == NULL) { + if (field_lists == NULL) { return; } - for (int i = 0; i < n_cell; i++) { - fieldstat_free_tag_array(tag_list[i].tag, tag_list[i].n_tag); + for (int i = 0; i < n_field_list; i++) { + for (size_t j = 0; j < field_lists[i].n_field; j++) { + struct field *field = &(field_lists[i].field[j]); + free((char *)field->key); + if (field->type == FIELD_VALUE_CSTRING) { + free((char *)field->value_str); + } + } + free(field_lists[i].field); } - free(tag_list); + free(field_lists); } -const char *fieldstat_get_metric_name(const struct fieldstat *instance, int metric_id) +//uninitialized + +const char *fieldstat_get_metric_name(const struct fieldstat *instance, int cube_id, int metric_id) { - if (metric_id < 0 || metric_id >= instance->n_metric_master) { - return NULL; - } - const struct metric *metric = instance->metric_masters[metric_id]; - if (metric == NULL) { + const struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); + if (cube == NULL) { return NULL; } - - return metric_get_name(metric); + return cube_get_metric_name(cube, metric_id); } -enum metric_type fieldstat_get_metric_type(const struct fieldstat *instance, int metric_id) +enum metric_type fieldstat_get_metric_type(const struct fieldstat *instance, int cube_id, int metric_id) { - if (instance == NULL || metric_id < 0 || metric_id >= instance->n_metric_master) { - return (enum metric_type)(-1); - } - const struct metric *metric = instance->metric_masters[metric_id]; - if (metric == NULL) { + const struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); + if (cube == NULL) { return (enum metric_type)(-1); } - - return metric_get_type(metric); + return cube_get_metric_type(cube, metric_id); } -void fieldstat_get_cells_used_by_cube(const struct fieldstat *instance, int cube_id, struct fieldstat_tag_list **tag_list, size_t *n_cell) +void fieldstat_cube_get_cells(const struct fieldstat *instance, int cube_id, struct field_list **cell_dimensions, size_t *n_cell) { - if (instance == NULL || cube_id < 0 || cube_id >= instance->valid_cube_arr_length) { - return; - } - const struct fs_cube *cube = instance->cube[cube_id]; + const struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); if (cube == NULL) { return; } - int arr_len = 0; - const struct tag_hash_key **tags_discontinuous = cell_manager_dump(cube->cell_manager, &arr_len); - if (arr_len == 0) { - *tag_list = NULL; - *n_cell = 0; - return; - } - - struct fieldstat_tag_list *tag_list_ret = (struct fieldstat_tag_list *)malloc(sizeof(struct fieldstat_tag_list) * arr_len); - int n_cell_ret = 0; - - for (int i = 0; i < arr_len; i++) { - const struct tag_hash_key *tag_key = tags_discontinuous[i]; - if (tag_key == NULL) { - continue; - } - tag_hash_key_convert_to_fieldstat_tag(tag_key, &(tag_list_ret[n_cell_ret].tag), &(tag_list_ret[n_cell_ret].n_tag)); - n_cell_ret++; - } - if (n_cell_ret == 0) { - free(tag_list_ret); - *tag_list = NULL; - *n_cell = 0; - return; - } - - *tag_list = tag_list_ret; - *n_cell = n_cell_ret; + cube_get_cells(cube, cell_dimensions, n_cell); } int fieldstat_get_used_sampling(const struct fieldstat *instance, int cube_id) @@ -1417,52 +354,36 @@ int fieldstat_get_used_sampling(const struct fieldstat *instance, int cube_id) if (instance == NULL) { return FS_ERR_NULL_HANDLER; } - if (cube_id < 0 || cube_id >= instance->valid_cube_arr_length) { - return FS_ERR_INVALID_CUBE_ID; - } - const struct fs_cube *cube = instance->cube[cube_id]; + + const struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); if (cube == NULL) { return FS_ERR_INVALID_CUBE_ID; } - return cell_manager_get_cardinality(cube->cell_manager); + return cube_get_cell_count(cube); } -int fieldstat_find_cube(const struct fieldstat *instance, const struct fieldstat_tag *shared_tags, size_t n_shared_tags) +int fieldstat_find_cube(const struct fieldstat *instance, const struct field *cube_dimensions, size_t n_dimensions) { if (instance == NULL) { return FS_ERR_NULL_HANDLER; } - const struct cube_manager *tag_cube_id_map = instance->shared_tag_cube_manager; - struct tag_hash_key shared_tag_key; - tag_hash_key_init_with_fieldstat_tag(&shared_tag_key, shared_tags, n_shared_tags, false); - int cube_id = cube_manager_find(tag_cube_id_map, &shared_tag_key); + + int cube_id = cube_manager_find(instance->cube_manager, cube_dimensions, n_dimensions); if (cube_id == -1) { - return FS_ERR_INVALID_KEY; + return FS_ERR_INVALID_DIMENSION; } return cube_id; } -int fieldstat_get_cube_mode(const struct fieldstat *instance, int cube_id, enum sampling_mode *mode, int *primary_metric_id) +void fieldstat_get_metric_in_cell(const struct fieldstat *instance, int cube_id, const struct field_list *cell_dimensions, int **metric_id_out, size_t *n_metric_out) { - if (instance == NULL) { - return FS_ERR_NULL_HANDLER; - } - if (cube_id < 0 || cube_id >= instance->valid_cube_arr_length) { - return FS_ERR_INVALID_CUBE_ID; - } - const struct fs_cube *cube = instance->cube[cube_id]; - if (cube == NULL) { - return FS_ERR_INVALID_CUBE_ID; - } - - *mode = cube->sampling_mode; - if (cube->sampling_mode == SAMPLING_MODE_TOPK) { - *primary_metric_id = cube->primary_metric_id; - } else { - *primary_metric_id = -1; - } + const struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); + return cube_get_metrics_in_cell(cube, cell_dimensions, metric_id_out, n_metric_out); +} - return FS_OK; -}
\ No newline at end of file +void fieldstat_cube_get_metrics(const struct fieldstat *instance, int cube_id, int **metric_id_out, size_t *n_metric) { + const struct cube *cube = cube_manager_get_cube_by_id(instance->cube_manager, cube_id); + cube_get_metrics(cube, metric_id_out, n_metric); +} |
