diff options
Diffstat (limited to 'lib/includes/hicn/util/map.h')
-rw-r--r-- | lib/includes/hicn/util/map.h | 444 |
1 files changed, 220 insertions, 224 deletions
diff --git a/lib/includes/hicn/util/map.h b/lib/includes/hicn/util/map.h index 01195865e..6e23f222f 100644 --- a/lib/includes/hicn/util/map.h +++ b/lib/includes/hicn/util/map.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -20,231 +20,227 @@ #include "set.h" -#define ERR_MAP_EXISTS -2 +#define ERR_MAP_EXISTS -2 #define ERR_MAP_NOT_FOUND -3 -#define TYPEDEF_MAP_H(NAME, KEY_T, VAL_T) \ - \ -typedef struct { \ - KEY_T key; \ - VAL_T value; \ -} NAME ## _pair_t; \ - \ -NAME ## _pair_t * NAME ## _pair_create(KEY_T key, VAL_T value); \ - \ -void NAME ## _pair_free(NAME ## _pair_t * pair); \ - \ -int NAME ## _pair_cmp(const NAME ## _pair_t * p1, const NAME ## _pair_t * p2); \ - \ -TYPEDEF_SET_H(NAME ## _pair_set, NAME ## _pair_t *) \ - \ -typedef struct NAME ## _s { \ - NAME ## _pair_set_t pair_set; \ -} NAME ## _t; \ - \ -int NAME ## _initialize(NAME ## _t * map); \ - \ -int NAME ## _finalize(NAME ## _t * map); \ - \ -NAME ## _t * NAME ## _create(); \ - \ -void NAME ## _free(NAME ## _t * map); \ - \ -int NAME ## _add(NAME ## _t * map, KEY_T key, VAL_T value); \ - \ -int NAME ## _remove(NAME ## _t * map, KEY_T key, VAL_T * value); \ - \ -int NAME ## _get(NAME ## _t * map, KEY_T key, VAL_T * value); \ - \ -void NAME ## _dump(NAME ## _t * map); +#define TYPEDEF_MAP_H(NAME, KEY_T, VAL_T) \ + \ + typedef struct \ + { \ + KEY_T key; \ + VAL_T value; \ + } NAME##_pair_t; \ + \ + NAME##_pair_t *NAME##_pair_create (KEY_T key, VAL_T value); \ + \ + void NAME##_pair_free (NAME##_pair_t *pair); \ + \ + int NAME##_pair_cmp (const NAME##_pair_t *p1, const NAME##_pair_t *p2); \ + \ + TYPEDEF_SET_H (NAME##_pair_set, NAME##_pair_t *) \ + \ + typedef struct NAME##_s \ + { \ + NAME##_pair_set_t pair_set; \ + } NAME##_t; \ + \ + int NAME##_initialize (NAME##_t *map); \ + \ + int NAME##_finalize (NAME##_t *map); \ + \ + NAME##_t *NAME##_create (); \ + \ + void NAME##_free (NAME##_t *map); \ + \ + int NAME##_add (NAME##_t *map, KEY_T key, VAL_T value); \ + \ + int NAME##_remove (NAME##_t *map, KEY_T key, VAL_T *value); \ + \ + int NAME##_get (NAME##_t *map, KEY_T key, VAL_T *value); \ + \ + void NAME##_dump (NAME##_t *map); \ + \ + int NAME##_get_key_array (NAME##_t *map, KEY_T **array); \ + \ + int NAME##_get_value_array (NAME##_t *map, VAL_T **array); - - - -#define TYPEDEF_MAP(NAME, KEY_T, VAL_T, CMP, KEY_SNPRINTF, VALUE_SNPRINTF) \ - \ -NAME ## _pair_t * NAME ## _pair_create(KEY_T key, VAL_T value) \ -{ \ - /* Create pair */ \ - NAME ## _pair_t * pair = malloc(sizeof(NAME ## _pair_t)); \ - if (!pair) \ - return NULL; \ - \ - pair->key = key; \ - pair->value = value; \ - \ - return pair; \ -} \ - \ -void NAME ## _pair_free(NAME ## _pair_t * pair) \ -{ \ - free(pair); \ -} \ - \ -int \ -NAME ## _pair_cmp(const NAME ## _pair_t * p1, const NAME ## _pair_t * p2) \ -{ \ - return (CMP(p1->key, p2->key)); \ -} \ - \ -int \ -NAME ## _pair_snprintf(char * buf, size_t size, const NAME ## _pair_t * pair) { \ - int rc; \ - rc = KEY_SNPRINTF(buf, BUFSIZE/2, (KEY_T)pair->key); \ - if (rc < 0) \ - return rc; \ - rc = VALUE_SNPRINTF(buf+rc, BUFSIZE/2, (VAL_T)pair->value); \ - return (int)rc; \ -} \ - \ -TYPEDEF_SET(NAME ## _pair_set, NAME ## _pair_t *, NAME ## _pair_cmp, NAME ## _pair_snprintf); \ - \ -int \ -NAME ## _initialize(NAME ## _t * map) \ -{ \ - return NAME ## _pair_set_initialize(&map->pair_set); \ -} \ - \ -int \ -NAME ## _finalize(NAME ## _t * map) \ -{ \ - NAME ## _pair_t ** array; \ - int n = NAME ## _pair_set_get_array(&map->pair_set, &array); \ - if (n < 0) \ - return -1; \ - for (unsigned i = 0; i < n; i++) { \ - NAME ## _pair_t * pair = array[i]; \ - NAME ## _pair_set_remove(&map->pair_set, pair, NULL); \ - NAME ## _pair_free(pair); \ - } \ - free(array); \ - return NAME ## _pair_set_finalize(&map->pair_set); \ -} \ - \ -NAME ## _t * \ -NAME ## _create() \ -{ \ - NAME ## _t * map = malloc(sizeof(NAME ## _t)); \ - if (!map) \ - goto ERR_MALLOC; \ - \ - if (NAME ## _initialize(map) < 0) \ - goto ERR_INITIALIZE; \ - \ - return map; \ - \ -ERR_INITIALIZE: \ - free(map); \ -ERR_MALLOC: \ - return NULL; \ -} \ - \ -void \ -NAME ## _free(NAME ## _t * map) \ -{ \ - NAME ## _finalize(map); \ - free(map); \ -} \ - \ -int \ -NAME ## _add(NAME ## _t * map, KEY_T key, VAL_T value) \ -{ \ - int rc; \ - NAME ## _pair_t * found = NULL; \ - \ - NAME ## _pair_t * pair = NAME ## _pair_create(key, value); \ - if (!pair) \ - return -1; \ - \ - rc = NAME ## _pair_set_get(&map->pair_set, pair, &found); \ - if (rc < 0) \ - return -1; \ - if (found) { \ - NAME ## _pair_free(pair); \ - return ERR_MAP_EXISTS; \ - } \ - \ - rc = NAME ## _pair_set_add(&map->pair_set, pair); \ - if (rc < 0) { \ - NAME ## _pair_free(pair); \ - return -1; \ - } \ - return 0; \ -} \ - \ -int \ -NAME ## _remove(NAME ## _t * map, KEY_T key, VAL_T * value) \ -{ \ - NAME ## _pair_t * found = NULL; \ - NAME ## _pair_t search = { .key = key }; \ - int rc = NAME ## _pair_set_remove(&map->pair_set, &search, &found); \ - if (rc < 0) \ - return ERR_MAP_NOT_FOUND; \ - if (value) \ - *value = found->value; \ - NAME ## _pair_free(found); \ - return 0; \ -} \ - \ -int \ -NAME ## _get(NAME ## _t * map, KEY_T key, VAL_T * value) \ -{ \ - NAME ## _pair_t * found = NULL, search = { .key = key }; \ - int rc = NAME ## _pair_set_get(&map->pair_set, &search, &found); \ - if (rc < 0) \ - return -1; \ - if (found) \ - *value = found->value; \ - return 0; \ -} \ - \ -void \ -NAME ## _dump(NAME ## _t * map) { \ - NAME ## _pair_set_dump(&map->pair_set); \ -} \ - \ -int \ -NAME ## _get_key_array(NAME ## _t * map, KEY_T **array) { \ - NAME ## _pair_t ** pair_array; \ - int n = NAME ## _pair_set_get_array(&map->pair_set, &pair_array); \ - if (n < 0) \ - return -1; \ - if (!array) \ - goto END; \ - /* Allocate result array */ \ - *array = malloc(n * sizeof(KEY_T)); \ - if (!array) { \ - free(pair_array); \ - return -1; \ - } \ - /* Copy keys */ \ - for (int i = 0; i < n; i++) \ - (*array)[i] = pair_array[i]->key; \ - free(pair_array); \ -END: \ - return n; \ -} \ - \ -int \ -NAME ## _get_value_array(NAME ## _t * map, VAL_T **array) { \ - NAME ## _pair_t ** pair_array; \ - int n = NAME ## _pair_set_get_array(&map->pair_set, &pair_array); \ - if (n < 0) \ - return -1; \ - if (!array) \ - goto END; \ - /* Allocate result array */ \ - *array = malloc(n * sizeof(VAL_T)); \ - if (!array) { \ - free(pair_array); \ - return -1; \ - } \ - /* Copy values */ \ - for (int i = 0; i < n; i++) \ - (*array)[i] = pair_array[i]->value; \ - free(pair_array); \ -END: \ - return n; \ -} +#define TYPEDEF_MAP(NAME, KEY_T, VAL_T, CMP, KEY_SNPRINTF, VALUE_SNPRINTF) \ + \ + NAME##_pair_t *NAME##_pair_create (KEY_T key, VAL_T value) \ + { \ + /* Create pair */ \ + NAME##_pair_t *pair = malloc (sizeof (NAME##_pair_t)); \ + if (!pair) \ + return NULL; \ + \ + pair->key = key; \ + pair->value = value; \ + \ + return pair; \ + } \ + \ + void NAME##_pair_free (NAME##_pair_t *pair) { free (pair); } \ + \ + int NAME##_pair_cmp (const NAME##_pair_t *p1, const NAME##_pair_t *p2) \ + { \ + return (CMP (p1->key, p2->key)); \ + } \ + \ + int NAME##_pair_snprintf (char *buf, size_t size, \ + const NAME##_pair_t *pair) \ + { \ + int rc; \ + rc = KEY_SNPRINTF (buf, BUFSIZE / 2, (KEY_T) pair->key); \ + if (rc < 0) \ + return rc; \ + rc = VALUE_SNPRINTF (buf + rc, BUFSIZE / 2, (VAL_T) pair->value); \ + return (int) rc; \ + } \ + \ + TYPEDEF_SET (NAME##_pair_set, NAME##_pair_t *, NAME##_pair_cmp, \ + NAME##_pair_snprintf); \ + \ + int NAME##_initialize (NAME##_t *map) \ + { \ + return NAME##_pair_set_initialize (&map->pair_set); \ + } \ + \ + int NAME##_finalize (NAME##_t *map) \ + { \ + NAME##_pair_t **array; \ + int n = NAME##_pair_set_get_array (&map->pair_set, &array); \ + if (n < 0) \ + return -1; \ + for (unsigned i = 0; i < n; i++) \ + { \ + NAME##_pair_t *pair = array[i]; \ + NAME##_pair_set_remove (&map->pair_set, pair, NULL); \ + NAME##_pair_free (pair); \ + } \ + free (array); \ + return NAME##_pair_set_finalize (&map->pair_set); \ + } \ + \ + NAME##_t *NAME##_create () \ + { \ + NAME##_t *map = malloc (sizeof (NAME##_t)); \ + if (!map) \ + goto ERR_MALLOC; \ + \ + if (NAME##_initialize (map) < 0) \ + goto ERR_INITIALIZE; \ + \ + return map; \ + \ + ERR_INITIALIZE: \ + free (map); \ + ERR_MALLOC: \ + return NULL; \ + } \ + \ + void NAME##_free (NAME##_t *map) \ + { \ + NAME##_finalize (map); \ + free (map); \ + } \ + \ + int NAME##_add (NAME##_t *map, KEY_T key, VAL_T value) \ + { \ + int rc; \ + NAME##_pair_t *found = NULL; \ + \ + NAME##_pair_t *pair = NAME##_pair_create (key, value); \ + if (!pair) \ + return -1; \ + \ + rc = NAME##_pair_set_get (&map->pair_set, pair, &found); \ + if (rc < 0) \ + return -1; \ + if (found) \ + { \ + NAME##_pair_free (pair); \ + return ERR_MAP_EXISTS; \ + } \ + \ + rc = NAME##_pair_set_add (&map->pair_set, pair); \ + if (rc < 0) \ + { \ + NAME##_pair_free (pair); \ + return -1; \ + } \ + return 0; \ + } \ + \ + int NAME##_remove (NAME##_t *map, KEY_T key, VAL_T *value) \ + { \ + NAME##_pair_t *found = NULL; \ + NAME##_pair_t search = { .key = key }; \ + int rc = NAME##_pair_set_remove (&map->pair_set, &search, &found); \ + if (rc < 0) \ + return ERR_MAP_NOT_FOUND; \ + if (value) \ + *value = found->value; \ + NAME##_pair_free (found); \ + return 0; \ + } \ + \ + int NAME##_get (NAME##_t *map, KEY_T key, VAL_T *value) \ + { \ + NAME##_pair_t *found = NULL, search = { .key = key }; \ + int rc = NAME##_pair_set_get (&map->pair_set, &search, &found); \ + if (rc < 0) \ + return -1; \ + if (found) \ + *value = found->value; \ + return 0; \ + } \ + \ + void NAME##_dump (NAME##_t *map) { NAME##_pair_set_dump (&map->pair_set); } \ + \ + int NAME##_get_key_array (NAME##_t *map, KEY_T **array) \ + { \ + NAME##_pair_t **pair_array; \ + int n = NAME##_pair_set_get_array (&map->pair_set, &pair_array); \ + if (n < 0) \ + return -1; \ + if (!array) \ + goto END; \ + /* Allocate result array */ \ + *array = malloc (n * sizeof (KEY_T)); \ + if (!array) \ + { \ + free (pair_array); \ + return -1; \ + } \ + /* Copy keys */ \ + for (int i = 0; i < n; i++) \ + (*array)[i] = pair_array[i]->key; \ + free (pair_array); \ + END: \ + return n; \ + } \ + \ + int NAME##_get_value_array (NAME##_t *map, VAL_T **array) \ + { \ + NAME##_pair_t **pair_array; \ + int n = NAME##_pair_set_get_array (&map->pair_set, &pair_array); \ + if (n < 0) \ + return -1; \ + if (!array) \ + goto END; \ + /* Allocate result array */ \ + *array = malloc (n * sizeof (VAL_T)); \ + if (!array) \ + { \ + free (pair_array); \ + return -1; \ + } \ + /* Copy values */ \ + for (int i = 0; i < n; i++) \ + (*array)[i] = pair_array[i]->value; \ + free (pair_array); \ + END: \ + return n; \ + } #endif /* UTIL_MAP_H */ |