diff options
| author | yangwei <[email protected]> | 2024-11-25 19:22:41 +0800 |
|---|---|---|
| committer | yangwei <[email protected]> | 2024-11-25 19:22:41 +0800 |
| commit | e2776414401af0bc02beb305b0d366fe3828cffd (patch) | |
| tree | 46aecfbe9531f15717626b2b4ec8d2a39e5603f2 /deps/utable | |
| parent | 40083638202cbedea0728ce0ebe49472212aad9f (diff) | |
✨ feat(deps/utable): define kv in utable.h temporary
Diffstat (limited to 'deps/utable')
| -rw-r--r-- | deps/utable/ipfix_exporter_example.cpp | 2 | ||||
| -rw-r--r-- | deps/utable/test/unit_test_utable.cpp | 18 | ||||
| -rw-r--r-- | deps/utable/utable.c | 519 | ||||
| -rw-r--r-- | deps/utable/utable.h | 116 |
4 files changed, 387 insertions, 268 deletions
diff --git a/deps/utable/ipfix_exporter_example.cpp b/deps/utable/ipfix_exporter_example.cpp index c7811c4..a6c11c2 100644 --- a/deps/utable/ipfix_exporter_example.cpp +++ b/deps/utable/ipfix_exporter_example.cpp @@ -132,7 +132,7 @@ void *ipfix_worker_thread_data_flow_send(void *arg) { struct utable *table = utable_new(); ipfix_exporter_test_utable_init(table, i, ipfix_schema_json_path); - utable_delete_item(table, "decoded_as"); + utable_delete(table, "decoded_as", strlen("decoded_as")); utable_add_cstring(table, "decoded_as", template_id_list[i].template_name, strlen(template_id_list[i].template_name)); size_t blob_len = 0; diff --git a/deps/utable/test/unit_test_utable.cpp b/deps/utable/test/unit_test_utable.cpp index f264372..0015f83 100644 --- a/deps/utable/test/unit_test_utable.cpp +++ b/deps/utable/test/unit_test_utable.cpp @@ -399,7 +399,7 @@ TEST(utable_test, add_blob_then_del) char *value; size_t value_len; - utable_delete_item(table, "key"); + utable_delete(table, "key", strlen("key")); EXPECT_EQ(utable_get0_blob_value(table, "key", &value, &value_len), -1); EXPECT_EQ(utable_get0_cstring_value(table, "key", &value, &value_len), -1); int64_t *value_array; @@ -435,7 +435,7 @@ TEST(utable_test, add_string_array_then_del) char *value; size_t value_len; - utable_delete_item(table, "key"); + utable_delete(table, "key", strlen("key")); EXPECT_EQ(utable_get0_blob_value(table, "key", &value, &value_len), -1); EXPECT_EQ(utable_get0_cstring_value(table, "key", &value, &value_len), -1); int64_t *value_array; @@ -583,7 +583,7 @@ TEST(utable_test, replace_8k_cstring) test_utable_assert_str(table, "key1", str1); - utable_delete_item(table, "key1"); + utable_delete(table, "key1", strlen("key1")); utable_add_cstring(table, "key1", str2, strlen(str2)); test_utable_assert_str(table, "key1", str2); @@ -616,7 +616,7 @@ TEST(utable_test, replace_cstring_many_times) for(int i=0; i<100000; i++) { - utable_delete_item(table, "key1"); + utable_delete(table, "key1", strlen("key1")); utable_add_cstring(table, "key1", str, strlen(str)); } @@ -639,7 +639,7 @@ TEST(utable_test, merge_empty_to_empty) { struct utable *table = utable_new(); struct utable *table2 = utable_new(); - utable_merge(table, table2); + utable_union(table, table2); EXPECT_EQ(utable_next_key(table), nullptr); struct utable_stat A={}, B={}; @@ -664,12 +664,12 @@ TEST(utable_test, merge_all_new) const char *blob = "bin hello world"; utable_add_blob(table2, "key on tbl2", blob, strlen(blob)); - utable_merge(table2, table); + utable_union(table2, table); test_utable_assert_arr(table2, "key2", int_array, 2); test_utable_assert_str(table2, "key1", str); test_utable_assert_blob(table2, "key on tbl2", blob, strlen(blob)); - utable_merge(table, table2); + utable_union(table, table2); struct utable_stat A={}, B={}; utable_stat(table, &A); utable_stat(table2, &B); @@ -688,7 +688,7 @@ TEST(utable_test, merge_all_skip) utable_add_integer_array(table, "key2", int_array, 2); struct utable *table2 = utable_duplicate(table); - utable_merge(table2, table); + utable_union(table2, table); EXPECT_STREQ(utable_next_key(table2), "key1"); EXPECT_STREQ(utable_next_key(table2), "key2"); @@ -710,7 +710,7 @@ TEST(utable_test, merge_some_skip_some_new) const char *str3 = "val on tbl1"; utable_add_cstring(table, "key1", str3, strlen(str3)); - utable_merge(table2, table); + utable_union(table2, table); test_utable_assert_str(table2, "key_share", str2); test_utable_assert_str(table2, "key1", str3); diff --git a/deps/utable/utable.c b/deps/utable/utable.c index 1ab36a4..3abfc0e 100644 --- a/deps/utable/utable.c +++ b/deps/utable/utable.c @@ -34,49 +34,37 @@ #define MEMPOOL_FREE(pool, p) mem_free(pool, p) +#define MEM_ALLOC(pool, number, type) ((pool) ? MEMPOOL_ALLOC(pool, number, type) : ALLOC(number, type)) +#define MEM_FREE(pool, p) do { \ + if (pool) { \ + MEMPOOL_FREE(pool, p); \ + } else { \ + FREE(p); \ + } \ +} while (0) -struct utable_item { - char *key; - size_t key_sz; - enum utable_value_type value_type; - size_t value_sz; - union { - struct - { - char *cstring; - size_t cstring_sz; - }; - struct - { - char *blob; - size_t blob_sz; - }; - struct - { - int64_t *interger_array; - size_t n_integer; - }; - struct - { - char **cstring_array; - size_t *cstring_array_sz; - size_t n_cstring; - }; - int64_t integer; - }; + +static char*MEM_STRDUP(MEMPOOL_TYPE *mempool, const char* s, size_t len) +{ + char* new_str = MEM_ALLOC(mempool, len + 1, char); + memcpy(new_str, s, len + 1); + return new_str; +} + +struct utable_item +{ + struct utable_kv *kv; UT_hash_handle hh; }; -struct utable { +struct utable +{ struct utable_item *items; struct utable_item *iter; MEMPOOL_TYPE *mempool; struct utable_stat stat; }; - - - struct utable *utable_new_with_size(size_t sz) { struct utable *table = ALLOC(1, struct utable); @@ -105,7 +93,182 @@ inline void utable_stat(struct utable *table, struct utable_stat *stat) memcpy(stat, &table->stat, sizeof(struct utable_stat)); } -static void utable_item_stat_add(struct utable_stat *stat, struct utable_item *item) + + +struct utable_kv *utable_kv_new_with_cstring_from_mempool(MEMPOOL_TYPE *pool, const char *key, size_t key_sz, const char *value, size_t value_sz) +{ + struct utable_kv *kv = MEM_ALLOC(pool, 1, struct utable_kv); + kv->key = MEM_STRDUP(pool, key, key_sz); + kv->key_sz = key_sz; + kv->value_type = utable_value_type_cstring; + kv->cstring = MEM_STRDUP(pool, value, value_sz); + kv->cstring_sz = value_sz; + kv->value_sz = value_sz; + return kv; +} + +struct utable_kv *utable_kv_new_with_blob_from_mempool(MEMPOOL_TYPE *pool,const char *key, size_t key_sz, const char *blob, size_t blob_sz) +{ + struct utable_kv *kv = MEM_ALLOC(pool,1, struct utable_kv); + kv->key = MEM_STRDUP(pool, key, key_sz); + kv->key_sz = key_sz; + kv->value_type = utable_value_type_blob; + kv->blob = MEM_ALLOC(pool, blob_sz, char); + memcpy(kv->blob, blob, blob_sz); + kv->blob_sz = blob_sz; + kv->value_sz = blob_sz; + return kv; +} +struct utable_kv *utable_kv_new_with_integer_from_mempool(MEMPOOL_TYPE *pool, const char *key, size_t key_sz, int64_t value) +{ + struct utable_kv *kv = MEM_ALLOC(pool,1, struct utable_kv); + kv->key = MEM_STRDUP(pool, key, key_sz); + kv->key_sz = key_sz; + kv->value_type = utable_value_type_integer; + kv->integer = value; + kv->value_sz = sizeof(int64_t); + return kv; +} +struct utable_kv *utable_kv_new_with_integer_array_from_mempool(MEMPOOL_TYPE *pool, const char *key, size_t key_sz, int64_t value[], size_t n_value) +{ + struct utable_kv *kv = MEM_ALLOC(pool,1, struct utable_kv); + kv->key = MEM_STRDUP(pool, key, key_sz); + kv->key_sz = key_sz; + kv->value_type = utable_value_type_integer_array; + kv->interger_array = MEM_ALLOC(pool, n_value, int64_t); + memcpy(kv->interger_array, value, sizeof(int64_t) * n_value); + kv->n_integer = n_value; + kv->value_sz = sizeof(int64_t) * n_value; + return kv; +} +struct utable_kv *utable_kv_new_with_cstring_array_from_mempool(MEMPOOL_TYPE *pool,const char *key, size_t key_sz, const char* value[], size_t value_sz[], size_t n_value) +{ + struct utable_kv *kv = MEM_ALLOC(pool,1, struct utable_kv); + kv->key = MEM_STRDUP(pool, key, key_sz); + kv->key_sz = key_sz; + kv->value_type = utable_value_type_cstring_array; + kv->cstring_array = MEM_ALLOC(pool, n_value, char *); + kv->cstring_array_sz = MEM_ALLOC(pool, n_value, size_t); + kv->value_sz = 0; + for(size_t i =0; i < n_value; i++) + { + kv->cstring_array[i] = MEM_STRDUP(pool, value[i], value_sz[i]); + kv->cstring_array_sz[i] = value_sz[i]; + kv->value_sz += value_sz[i]; + } + kv->n_cstring = n_value; + return kv; +} + +void utable_kv_free_from_pool(MEMPOOL_TYPE *pool, struct utable_kv *kv) +{ + if(kv->key) MEM_FREE(pool, kv->key); + MEM_FREE(pool, kv); +} + +struct utable_kv *utable_kv_new_with_cstring(const char *key, size_t key_sz, const char *value, size_t value_sz) +{ + return utable_kv_new_with_cstring_from_mempool(NULL, key, key_sz, value, value_sz); +} + +struct utable_kv *utable_kv_new_with_blob(const char *key, size_t key_sz, const char *blob, size_t blob_sz) +{ + return utable_kv_new_with_blob_from_mempool(NULL, key, key_sz, blob, blob_sz); +} +struct utable_kv *utable_kv_new_with_integer(const char *key, size_t key_sz, int64_t value) +{ + return utable_kv_new_with_integer_from_mempool(NULL, key, key_sz, value); +} +struct utable_kv *utable_kv_new_with_integer_array(const char *key, size_t key_sz, int64_t value[], size_t n_value) +{ + return utable_kv_new_with_integer_array_from_mempool(NULL, key, key_sz, value, n_value); +} +struct utable_kv *utable_kv_new_with_cstring_array(const char *key, size_t key_sz, const char* value[], size_t value_sz[], size_t n_value) +{ + return utable_kv_new_with_cstring_array_from_mempool(NULL, key, key_sz, value, value_sz, n_value); +} + +void utable_kv_free(struct utable_kv *kv) +{ + return utable_kv_free_from_pool(NULL, kv); +} + +struct utable_kv *utable_kv_duplicate_from_mempool(MEMPOOL_TYPE *pool, const struct utable_kv *kv) +{ + struct utable_kv *new_kv = NULL; + switch (kv->value_type) + { + case utable_value_type_cstring: + new_kv=utable_kv_new_with_cstring_from_mempool(pool, kv->key, kv->key_sz, kv->cstring, kv->cstring_sz); + break; + case utable_value_type_blob: + new_kv=utable_kv_new_with_blob_from_mempool(pool, kv->key, kv->key_sz, kv->blob, kv->blob_sz); + break; + case utable_value_type_integer: + new_kv=utable_kv_new_with_integer_from_mempool(pool, kv->key, kv->key_sz, kv->integer); + break; + case utable_value_type_integer_array: + new_kv=utable_kv_new_with_integer_array_from_mempool(pool, kv->key, kv->key_sz, kv->interger_array, kv->n_integer); + break; + case utable_value_type_cstring_array: + new_kv=utable_kv_new_with_cstring_array_from_mempool(pool, kv->key, kv->key_sz, (const char **)kv->cstring_array, kv->cstring_array_sz, kv->n_cstring); + break; + default: + break; + } + return new_kv; +} + +struct utable_kv *utable_kv_duplicate(const struct utable_kv *kv) +{ + return utable_kv_duplicate_from_mempool(NULL, kv); +} + +void utable_add_kv(struct utable *table, struct utable_kv *kv) +{ + struct utable_item *item; + HASH_FIND(hh, table->items, kv->key, kv->key_sz, item); + if (item) { + DEBUG_PRINT("ERR: key %s already exists\n", kv->key); + return; + } + item = MEM_ALLOC(table->mempool, 1, struct utable_item); + item->kv = utable_kv_duplicate_from_mempool(table->mempool, kv); + HASH_ADD_KEYPTR(hh, table->items, item->kv->key, item->kv->key_sz, item); +} + +void utable_add_kv_array(struct utable *table, struct utable_kv *kv_array, size_t n_kv) +{ + for (size_t i = 0; i < n_kv; i++) { + utable_add_kv(table, &kv_array[i]); + } +} + +struct utable_kv *utable_get0_kv(struct utable *table, const char *key, size_t key_sz) +{ + struct utable_item *item; + HASH_FIND(hh, table->items, key, key_sz, item); + if (item) { + return item->kv; + } + return NULL; +} + +struct utable_kv *utable_next_kv(struct utable *table) +{ + if (table->iter == NULL) { + table->iter = table->items; + } else { + table->iter = (struct utable_item *)table->iter->hh.next; + } + if (table->iter == NULL) { + return NULL; + } + return table->iter->kv; +} + + +static void utable_item_stat_add(struct utable_stat *stat, struct utable_kv *item) { if(stat==NULL || item == NULL) return; @@ -139,7 +302,7 @@ static void utable_item_stat_add(struct utable_stat *stat, struct utable_item *i } } -static void utable_item_stat_sub(struct utable_stat *stat, struct utable_item *item) +static void utable_item_stat_sub(struct utable_stat *stat, struct utable_kv *item) { if(stat==NULL || item == NULL) return; @@ -173,13 +336,6 @@ static void utable_item_stat_sub(struct utable_stat *stat, struct utable_item *i } } -static char*mempool_strdup(MEMPOOL_TYPE *mempool, const char* s, size_t len) -{ - char* new_str = MEMPOOL_ALLOC(mempool, len + 1, char); - memcpy(new_str, s, len + 1); - return new_str; -} - void utable_add_cstring(struct utable *table, const char *key, const char *value, size_t value_sz) { // check if key already exists @@ -191,16 +347,9 @@ void utable_add_cstring(struct utable *table, const char *key, const char *value return; } item = MEMPOOL_ALLOC(table->mempool ,1,struct utable_item); - item->key = mempool_strdup(table->mempool,key, key_sz); - item->key_sz = key_sz; - item->value_type = utable_value_type_cstring; - item->cstring = MEMPOOL_ALLOC(table->mempool ,value_sz + 1, char); - memcpy(item->cstring, value, value_sz); - item->cstring[value_sz] = '\0'; - item->cstring_sz = value_sz; - item->value_sz = value_sz; - HASH_ADD_KEYPTR(hh, table->items, item->key, item->key_sz, item); - utable_item_stat_add(&table->stat, item); + item->kv= utable_kv_new_with_cstring(key, key_sz, value, value_sz); + HASH_ADD_KEYPTR(hh, table->items, item->kv->key, item->kv->key_sz, item); + utable_item_stat_add(&table->stat, item->kv); } void utable_add_blob(struct utable *table, const char *key, const char *blob, size_t blob_sz) @@ -214,16 +363,10 @@ void utable_add_blob(struct utable *table, const char *key, const char *blob, si return; } item = MEMPOOL_ALLOC(table->mempool ,1, struct utable_item); - item->key = mempool_strdup(table->mempool, key, key_sz); - item->key_sz = key_sz; - item->value_type = utable_value_type_blob; - item->blob = MEMPOOL_ALLOC(table->mempool ,blob_sz, char); - memcpy(item->blob, blob, blob_sz); - item->blob_sz = blob_sz; - item->value_sz = blob_sz; - HASH_ADD_KEYPTR(hh, table->items, item->key, item->key_sz, item); + item->kv = utable_kv_new_with_blob(key, key_sz, blob, blob_sz); - utable_item_stat_add(&table->stat, item); + HASH_ADD_KEYPTR(hh, table->items, item->kv->key, item->kv->key_sz, item); + utable_item_stat_add(&table->stat, item->kv); } void utable_add_integer(struct utable *table, const char *key, int64_t value) @@ -237,14 +380,10 @@ void utable_add_integer(struct utable *table, const char *key, int64_t value) return; } item = MEMPOOL_ALLOC(table->mempool ,1, struct utable_item); - item->key = mempool_strdup(table->mempool, key, key_sz); - item->key_sz = key_sz; - item->value_type = utable_value_type_integer; - item->integer = value; - item->value_sz = sizeof(int64_t); - HASH_ADD_KEYPTR(hh, table->items, item->key, item->key_sz, item); + item->kv = utable_kv_new_with_integer(key, key_sz, value); - utable_item_stat_add(&table->stat, item); + HASH_ADD_KEYPTR(hh, table->items, item->kv->key, item->kv->key_sz, item); + utable_item_stat_add(&table->stat, item->kv); } void utable_add_integer_array(struct utable *table, const char *key, int64_t value_array[], size_t n_value) @@ -258,16 +397,10 @@ void utable_add_integer_array(struct utable *table, const char *key, int64_t val return; } item = MEMPOOL_ALLOC(table->mempool ,1, struct utable_item); - item->key = mempool_strdup(table->mempool, key, key_sz); - item->key_sz = key_sz; - item->value_type = utable_value_type_integer_array; - item->interger_array = MEMPOOL_ALLOC(table->mempool ,n_value, int64_t); - memcpy(item->interger_array, value_array, sizeof(int64_t) * n_value); - item->n_integer = n_value; - item->value_sz = sizeof(int64_t) * n_value; - HASH_ADD_KEYPTR(hh, table->items, item->key, item->key_sz, item); + item->kv = utable_kv_new_with_integer_array(key, key_sz, value_array, n_value); - utable_item_stat_add(&table->stat, item); + HASH_ADD_KEYPTR(hh, table->items, item->kv->key, item->kv->key_sz, item); + utable_item_stat_add(&table->stat, item->kv); } void utable_add_cstring_array(struct utable *table, const char *key, const char* value_array[], size_t value_sz[], size_t n_value) @@ -281,54 +414,20 @@ void utable_add_cstring_array(struct utable *table, const char *key, const char* return; } item = MEMPOOL_ALLOC(table->mempool ,1, struct utable_item); - item->key = mempool_strdup(table->mempool, key, key_sz); - item->key_sz = key_sz; - item->value_type = utable_value_type_cstring_array; - item->cstring_array = MEMPOOL_ALLOC(table->mempool ,n_value, char *); - item->cstring_array_sz = MEMPOOL_ALLOC(table->mempool ,n_value, size_t); - item->value_sz = 0; - for(size_t i =0; i < n_value; i++) - { - item->cstring_array[i] = MEMPOOL_ALLOC(table->mempool , value_sz[i]+1, char); - memcpy(item->cstring_array[i], value_array[i], value_sz[i]); - item->cstring_array[i][value_sz[i]] = '\0'; - item->cstring_array_sz[i] = value_sz[i]; - item->value_sz += value_sz[i]; - } - item->n_cstring = n_value; - HASH_ADD_KEYPTR(hh, table->items, item->key, item->key_sz, item); + item->kv = utable_kv_new_with_cstring_array(key, key_sz, value_array, value_sz, n_value); - utable_item_stat_add(&table->stat, item); + HASH_ADD_KEYPTR(hh, table->items, item->kv->key, item->kv->key_sz, item); + utable_item_stat_add(&table->stat, item->kv); } -void utable_delete_item(struct utable *table, const char *key) +void utable_delete(struct utable *table, const char *key, size_t key_sz) { struct utable_item *item; - HASH_FIND_STR(table->items, key, item); + HASH_FIND(hh, table->items, key, key_sz, item); if (item) { HASH_DEL(table->items, item); - MEMPOOL_FREE(table->mempool, item->key); - switch (item->value_type) { - case utable_value_type_cstring: - MEMPOOL_FREE(table->mempool,item->cstring); - break; - case utable_value_type_blob: - MEMPOOL_FREE(table->mempool,item->blob); - break; - case utable_value_type_integer_array: - MEMPOOL_FREE(table->mempool,item->interger_array); - break; - case utable_value_type_cstring_array: - for(size_t i=0; i < item->n_cstring; i++) - { - MEMPOOL_FREE(table->mempool,item->cstring_array[i]); - } - MEMPOOL_FREE(table->mempool,item->cstring_array_sz); - break; - default: - break; - } - utable_item_stat_sub(&table->stat, item); + utable_item_stat_sub(&table->stat, item->kv); + utable_kv_free(item->kv); MEMPOOL_FREE(table->mempool,item); } } @@ -348,7 +447,7 @@ const char *utable_next_key(struct utable *table) if (table->iter == NULL) { return NULL; } - return table->iter->key; + return table->iter->kv->key; } enum utable_value_type utable_get_value_type(const struct utable *table, const char *key) @@ -356,7 +455,7 @@ enum utable_value_type utable_get_value_type(const struct utable *table, const c struct utable_item *item; HASH_FIND_STR(table->items, key, item); if (item) { - return item->value_type; + return item->kv->value_type; } return utable_value_type_undefined; } @@ -366,9 +465,9 @@ int utable_get0_blob_value(const struct utable *table, const char *key, char **v struct utable_item *item; HASH_FIND_STR(table->items, key, item); if (item) { - if (item->value_type == utable_value_type_blob) { - *value = item->blob; - *value_len = item->blob_sz; + if (item->kv->value_type == utable_value_type_blob) { + *value = item->kv->blob; + *value_len = item->kv->blob_sz; return 0; } } @@ -380,9 +479,9 @@ int utable_get0_cstring_value(const struct utable *table, const char *key, char struct utable_item *item; HASH_FIND_STR(table->items, key, item); if (item) { - if (item->value_type == utable_value_type_cstring) { - *value = item->cstring; - *value_len = item->cstring_sz; + if (item->kv->value_type == utable_value_type_cstring) { + *value = item->kv->cstring; + *value_len = item->kv->cstring_sz; return 0; } } @@ -394,8 +493,8 @@ int utable_get0_integer_value(const struct utable *table, const char *key, int64 struct utable_item *item; HASH_FIND_STR(table->items, key, item); if (item) { - if (item->value_type == utable_value_type_integer) { - *value = item->integer; + if (item->kv->value_type == utable_value_type_integer) { + *value = item->kv->integer; return 0; } } @@ -407,9 +506,9 @@ int utable_get0_integer_value_array(const struct utable *table, const char *key, struct utable_item *item; HASH_FIND_STR(table->items, key, item); if (item) { - if (item->value_type == utable_value_type_integer_array) { - *value_array = item->interger_array; - *n_value = item->n_integer; + if (item->kv->value_type == utable_value_type_integer_array) { + *value_array = item->kv->interger_array; + *n_value = item->kv->n_integer; return 0; } } @@ -421,10 +520,10 @@ int utable_get0_cstring_value_array(const struct utable *table, const char *key, struct utable_item *item; HASH_FIND_STR(table->items, key, item); if (item) { - if (item->value_type == utable_value_type_cstring_array) { - *value_array = item->cstring_array; - *value_len = item->cstring_array_sz; - *n_value = item->n_cstring; + if (item->kv->value_type == utable_value_type_cstring_array) { + *value_array = item->kv->cstring_array; + *value_len = item->kv->cstring_array_sz; + *n_value = item->kv->n_cstring; return 0; } } @@ -434,46 +533,7 @@ int utable_get0_cstring_value_array(const struct utable *table, const char *key, struct utable_item *utable_item_dup(MEMPOOL_TYPE *mempool, const struct utable_item *item) { struct utable_item *new_item = MEMPOOL_ALLOC(mempool, 1, struct utable_item); - size_t key_sz = item->key_sz; - new_item->key = mempool_strdup(mempool, item->key, key_sz); - new_item->key_sz = key_sz; - new_item->value_type = item->value_type; - new_item->value_sz= item->value_sz; - switch (item->value_type) { - case utable_value_type_cstring: - new_item->cstring = MEMPOOL_ALLOC(mempool,item->cstring_sz + 1, char); - memcpy(new_item->cstring, item->cstring, item->cstring_sz); - new_item->cstring[item->cstring_sz] = '\0'; - new_item->cstring_sz = item->cstring_sz; - break; - case utable_value_type_blob: - new_item->blob = MEMPOOL_ALLOC(mempool,item->blob_sz, char); - memcpy(new_item->blob, item->blob, item->blob_sz); - new_item->blob_sz = item->blob_sz; - break; - case utable_value_type_integer: - new_item->integer = item->integer; - break; - case utable_value_type_integer_array: - new_item->interger_array = MEMPOOL_ALLOC(mempool,item->n_integer, int64_t); - memcpy(new_item->interger_array, item->interger_array, sizeof(int64_t) * item->n_integer); - new_item->n_integer = item->n_integer; - break; - case utable_value_type_cstring_array: - new_item->n_cstring= item->n_cstring; - new_item->cstring_array = MEMPOOL_ALLOC(mempool ,item->n_cstring, char *); - new_item->cstring_array_sz = MEMPOOL_ALLOC(mempool ,item->n_cstring, size_t); - for(size_t i =0; i < item->n_cstring; i++) - { - new_item->cstring_array[i] = MEMPOOL_ALLOC(mempool , item->cstring_array_sz[i]+1, char); - memcpy(new_item->cstring_array[i], item->cstring_array[i], item->cstring_array_sz[i]); - new_item->cstring_array[i][item->cstring_array_sz[i]] = '\0'; - new_item->cstring_array_sz[i] = item->cstring_array_sz[i]; - } - break; - default: - break; - } + new_item->kv = utable_kv_duplicate_from_mempool(mempool, item->kv); return new_item; } @@ -483,24 +543,24 @@ struct utable *utable_duplicate(const struct utable *table) struct utable_item *item, *tmp; HASH_ITER(hh, table->items, item, tmp) { struct utable_item *new_item = utable_item_dup(new_table->mempool, item); - HASH_ADD_KEYPTR(hh, new_table->items, new_item->key, new_item->key_sz, new_item); + HASH_ADD_KEYPTR(hh, new_table->items, new_item->kv->key, new_item->kv->key_sz, new_item); } new_table->stat = table->stat; return new_table; } -int utable_merge(struct utable *dst, const struct utable *src) +int utable_union(struct utable *dst, const struct utable *src) { struct utable_item *item, *tmp; HASH_ITER(hh, src->items, item, tmp) { struct utable_item *dst_item; - HASH_FIND(hh, dst->items, item->key, item->key_sz, dst_item); + HASH_FIND(hh, dst->items, item->kv->key, item->kv->key_sz, dst_item); if (dst_item) { continue; } struct utable_item *new_item = utable_item_dup(dst->mempool, item); - HASH_ADD_KEYPTR(hh, dst->items, new_item->key, new_item->key_sz, new_item); - utable_item_stat_add(&dst->stat, item); + HASH_ADD_KEYPTR(hh, dst->items, new_item->kv->key, new_item->kv->key_sz, new_item); + utable_item_stat_add(&dst->stat, item->kv); } return 0; } @@ -514,30 +574,30 @@ int utable_json_export(const struct utable *table, char **blob, size_t *blob_len struct utable_item *item, *tmp; int enc_cnt = 0; HASH_ITER(hh, table->items, item, tmp) { - switch (item->value_type) { + switch (item->kv->value_type) { case utable_value_type_cstring: { - yyjson_mut_obj_add_str(doc, root, item->key, item->cstring); // key and cstring are shallow copied + yyjson_mut_obj_add_str(doc, root, item->kv->key, item->kv->cstring); // key and cstring are shallow copied } break; case utable_value_type_blob: { - char *enc = b64_encode((unsigned char *)item->blob, item->blob_sz); - yyjson_mut_obj_add_str(doc, root, item->key, enc); + char *enc = b64_encode((unsigned char *)item->kv->blob, item->kv->blob_sz); + yyjson_mut_obj_add_str(doc, root, item->kv->key, enc); // do not free enc now, it is shallow copied encs[enc_cnt++] = enc; } break; case utable_value_type_integer: { - yyjson_mut_obj_add_int(doc, root, item->key, item->integer); + yyjson_mut_obj_add_int(doc, root, item->kv->key, item->kv->integer); } break; case utable_value_type_integer_array: { - yyjson_mut_val *arr = yyjson_mut_arr_with_sint64(doc, item->interger_array, item->n_integer); - yyjson_mut_obj_add_val(doc, root, item->key, arr); + yyjson_mut_val *arr = yyjson_mut_arr_with_sint64(doc, item->kv->interger_array, item->kv->n_integer); + yyjson_mut_obj_add_val(doc, root, item->kv->key, arr); } break; case utable_value_type_cstring_array: { - yyjson_mut_val *arr = yyjson_mut_arr_with_strn(doc, (const char **)item->cstring_array, item->cstring_array_sz, item->n_cstring); - yyjson_mut_obj_add_val(doc, root, item->key, arr); + yyjson_mut_val *arr = yyjson_mut_arr_with_strn(doc, (const char **)item->kv->cstring_array, item->kv->cstring_array_sz, item->kv->n_cstring); + yyjson_mut_obj_add_val(doc, root, item->kv->key, arr); } break; default: @@ -571,10 +631,10 @@ int utable_msgpack_export(const struct utable *table, char **blob, size_t *blob_ HASH_ITER(hh, table->items, item, tmp) { mpack_start_map(&writer, 3); mpack_write_cstr(&writer, "key"); - mpack_write_cstr(&writer, item->key); + mpack_write_cstr(&writer, item->kv->key); mpack_write_cstr(&writer, "type"); - switch (item->value_type) { + switch (item->kv->value_type) { case utable_value_type_cstring: mpack_write_cstr(&writer, "c_str"); break; @@ -592,20 +652,20 @@ int utable_msgpack_export(const struct utable *table, char **blob, size_t *blob_ } mpack_write_cstr(&writer, "value"); - switch (item->value_type) { + switch (item->kv->value_type) { case utable_value_type_cstring: - mpack_write_bin(&writer, item->cstring, item->cstring_sz); + mpack_write_bin(&writer, item->kv->cstring, item->kv->cstring_sz); break; case utable_value_type_blob: - mpack_write_bin(&writer, item->blob, item->blob_sz); + mpack_write_bin(&writer, item->kv->blob, item->kv->blob_sz); break; case utable_value_type_integer: - mpack_write_i64(&writer, item->integer); + mpack_write_i64(&writer, item->kv->integer); break; case utable_value_type_integer_array: - mpack_start_array(&writer, item->n_integer); - for (size_t i = 0; i < item->n_integer; i++) { - mpack_write_i64(&writer, item->interger_array[i]); + mpack_start_array(&writer, item->kv->n_integer); + for (size_t i = 0; i < item->kv->n_integer; i++) { + mpack_write_i64(&writer, item->kv->interger_array[i]); } mpack_finish_array(&writer); break; @@ -641,23 +701,23 @@ static void utable_item_free(MEMPOOL_TYPE *mempool, struct utable_item *item) { if(item == NULL) return; - if(item->key)MEMPOOL_FREE(mempool, item->key); - switch (item->value_type) { + if(item->kv->key)MEMPOOL_FREE(mempool, item->kv->key); + switch (item->kv->value_type) { case utable_value_type_cstring: - MEMPOOL_FREE(mempool,item->cstring); + MEMPOOL_FREE(mempool,item->kv->cstring); break; case utable_value_type_blob: - MEMPOOL_FREE(mempool,item->blob); + MEMPOOL_FREE(mempool,item->kv->blob); break; case utable_value_type_integer_array: - MEMPOOL_FREE(mempool,item->interger_array); + MEMPOOL_FREE(mempool,item->kv->interger_array); break; case utable_value_type_cstring_array: - for(size_t i=0; i < item->n_cstring; i++) + for(size_t i=0; i < item->kv->n_cstring; i++) { - MEMPOOL_FREE(mempool,item->cstring_array[i]); + MEMPOOL_FREE(mempool,item->kv->cstring_array[i]); } - MEMPOOL_FREE(mempool,item->cstring_array_sz); + MEMPOOL_FREE(mempool,item->kv->cstring_array_sz); break; default: break; @@ -685,33 +745,34 @@ struct utable *utable_deserialize(const char *blob, size_t blob_len) char *type_str = get_cstring_from_mpack_node(table->mempool, type); struct utable_item *new_item = MEMPOOL_ALLOC(table->mempool,1, struct utable_item); - new_item->key = get_cstring_from_mpack_node(table->mempool, key); - new_item->key_sz = strlen(new_item->key); - new_item->value_sz = 0; + new_item->kv=MEMPOOL_ALLOC(table->mempool,1, struct utable_kv); + new_item->kv->key = get_cstring_from_mpack_node(table->mempool, key); + new_item->kv->key_sz = strlen(new_item->kv->key); + new_item->kv->value_sz = 0; if (strcmp(type_str, "c_str") == 0) { - new_item->value_type = utable_value_type_cstring; - new_item->cstring = MEMPOOL_ALLOC(table->mempool,mpack_node_bin_size(value), char); - new_item->cstring_sz = mpack_node_bin_size(value); - new_item->value_sz = new_item->cstring_sz; - memcpy(new_item->cstring, mpack_node_bin_data(value), mpack_node_bin_size(value)); + new_item->kv->value_type = utable_value_type_cstring; + new_item->kv->cstring = MEMPOOL_ALLOC(table->mempool,mpack_node_bin_size(value), char); + new_item->kv->cstring_sz = mpack_node_bin_size(value); + new_item->kv->value_sz = new_item->kv->cstring_sz; + memcpy(new_item->kv->cstring, mpack_node_bin_data(value), mpack_node_bin_size(value)); } else if (strcmp(type_str, "blob") == 0) { - new_item->value_type = utable_value_type_blob; - new_item->blob = MEMPOOL_ALLOC(table->mempool,mpack_node_bin_size(value), char); - new_item->blob_sz = mpack_node_bin_size(value); - new_item->value_sz = new_item->blob_sz; - memcpy(new_item->blob, mpack_node_bin_data(value), mpack_node_bin_size(value)); + new_item->kv->value_type = utable_value_type_blob; + new_item->kv->blob = MEMPOOL_ALLOC(table->mempool,mpack_node_bin_size(value), char); + new_item->kv->blob_sz = mpack_node_bin_size(value); + new_item->kv->value_sz = new_item->kv->blob_sz; + memcpy(new_item->kv->blob, mpack_node_bin_data(value), mpack_node_bin_size(value)); } else if (strcmp(type_str, "i") == 0) { - new_item->value_type = utable_value_type_integer; - new_item->integer = mpack_node_i64(value); + new_item->kv->value_type = utable_value_type_integer; + new_item->kv->integer = mpack_node_i64(value); } else if (strcmp(type_str, "i_arr") == 0) { - new_item->value_type = utable_value_type_integer_array; - new_item->n_integer = mpack_node_array_length(value); - new_item->interger_array = MEMPOOL_ALLOC(table->mempool,new_item->n_integer, int64_t); - for (size_t j = 0; j < new_item->n_integer; j++) { - new_item->interger_array[j] = mpack_node_i64(mpack_node_array_at(value, j)); + new_item->kv->value_type = utable_value_type_integer_array; + new_item->kv->n_integer = mpack_node_array_length(value); + new_item->kv->interger_array = MEMPOOL_ALLOC(table->mempool,new_item->kv->n_integer, int64_t); + for (size_t j = 0; j < new_item->kv->n_integer; j++) { + new_item->kv->interger_array[j] = mpack_node_i64(mpack_node_array_at(value, j)); } - new_item->value_sz = sizeof(int64_t) * new_item->n_integer; + new_item->kv->value_sz = sizeof(int64_t) * new_item->kv->n_integer; } else { DEBUG_PRINT("ERR unknown type %s\n", type_str); mpack_tree_destroy(&tree); @@ -720,8 +781,8 @@ struct utable *utable_deserialize(const char *blob, size_t blob_len) return NULL; } - HASH_ADD_KEYPTR(hh, table->items, new_item->key, new_item->key_sz, new_item); - utable_item_stat_add(&table->stat, new_item); + HASH_ADD_KEYPTR(hh, table->items, new_item->kv->key, new_item->kv->key_sz, new_item); + utable_item_stat_add(&table->stat, new_item->kv); MEMPOOL_FREE(table->mempool, type_str); } diff --git a/deps/utable/utable.h b/deps/utable/utable.h index 13dfa5c..0ba974a 100644 --- a/deps/utable/utable.h +++ b/deps/utable/utable.h @@ -8,49 +8,83 @@ extern "C" { #endif -struct utable_stat +/*********************************** + * utable_kv * + ***********************************/ + +enum utable_value_type { - size_t n_item; - size_t n_item_size; - size_t n_blob; - size_t n_blob_size; - size_t n_cstring; - size_t n_cstring_size; - size_t n_integer; - size_t n_integer_size; - size_t n_integer_array; - size_t n_integer_array_size; - size_t n_cstring_array; - size_t n_cstring_array_size; + utable_value_type_undefined = 0, + utable_value_type_cstring, + utable_value_type_blob, + utable_value_type_integer, + utable_value_type_integer_array, + utable_value_type_cstring_array +}; + +struct utable_kv { + char *key; + size_t key_sz; + enum utable_value_type value_type; + size_t value_sz; + union { + struct + { + char *cstring; + size_t cstring_sz; + }; + struct + { + char *blob; + size_t blob_sz; + }; + struct + { + int64_t *interger_array; + size_t n_integer; + }; + struct + { + char **cstring_array; + size_t *cstring_array_sz; + size_t n_cstring; + }; + int64_t integer; + }; }; +struct utable_kv *utable_kv_new_with_cstring(const char *key, size_t key_sz, const char *value, size_t value_sz); +struct utable_kv *utable_kv_new_with_blob(const char *key, size_t key_sz, const char *blob, size_t blob_sz); +struct utable_kv *utable_kv_new_with_integer(const char *key, size_t key_sz, int64_t value); +struct utable_kv *utable_kv_new_with_integer_array(const char *key, size_t key_sz, int64_t value[], size_t n_value); +struct utable_kv *utable_kv_new_with_cstring_array(const char *key, size_t key_sz, const char* value[], size_t value_sz[], size_t n_value); + +void utable_kv_free(struct utable_kv *kv); +struct utable_kv *utable_kv_duplicate(const struct utable_kv *kv); + + +/*********************************** + * utable API * + ***********************************/ + struct utable; struct utable *utable_new(void); struct utable *utable_new_with_size(size_t sz); void utable_free(struct utable *table); +void utable_add_kv(struct utable *table, struct utable_kv *kv); +void utable_add_kv_array(struct utable *table, struct utable_kv *kv_array, size_t n_kv); - - - -void utable_stat(struct utable *table, struct utable_stat *stat); +struct utable_kv *utable_get0_kv(struct utable *table, const char *key, size_t key_sz); +struct utable_kv *utable_next_kv(struct utable *table); void utable_add_cstring(struct utable *table, const char *key, const char *value, size_t value_sz); void utable_add_blob(struct utable *table, const char *key, const char *blob, size_t blob_sz); void utable_add_integer(struct utable *table, const char *key, int64_t value); void utable_add_integer_array(struct utable *table, const char *key, int64_t value_array[], size_t n_value); void utable_add_cstring_array(struct utable *table, const char *key, const char* value_array[], size_t value_sz[], size_t n_value); -void utable_delete_item(struct utable *table, const char *key); +void utable_delete(struct utable *table, const char *key, size_t key_sz); -enum utable_value_type -{ - utable_value_type_undefined=0, - utable_value_type_cstring, - utable_value_type_blob, - utable_value_type_integer, - utable_value_type_integer_array, - utable_value_type_cstring_array -}; void utable_reset_iter(struct utable *table); const char *utable_next_key(struct utable *table); @@ -62,13 +96,37 @@ int utable_get0_integer_value_array(const struct utable *table, const char *key, int utable_get0_cstring_value_array(const struct utable *table, const char *key, char ***value_array, size_t **value_len, size_t *n_value); struct utable *utable_duplicate(const struct utable *table); -int utable_merge(struct utable *dst, const struct utable *src); +int utable_union(struct utable *dst, const struct utable *src); void utable_serialize(const struct utable *table, char **blob, size_t *blob_len); struct utable *utable_deserialize(const char *blob, size_t blob_len); +struct utable_stat +{ + size_t n_item; + size_t n_item_size; + size_t n_blob; + size_t n_blob_size; + size_t n_cstring; + size_t n_cstring_size; + size_t n_integer; + size_t n_integer_size; + size_t n_integer_array; + size_t n_integer_array_size; + size_t n_cstring_array; + size_t n_cstring_array_size; +}; + +void utable_stat(struct utable *table, struct utable_stat *stat); + +/*********************************** + * utable exporter API * + ***********************************/ + struct ipfix_exporter_schema; -struct ipfix_exporter_schema *utable_ipfix_exporter_schema_new(const char *ipfix_schema_json_path, uint16_t domain_id, uint16_t n_worker); // |domain_id|work_id|=source_id (16+16) domain_id 是进程唯一标识 + +// |domain_id|work_id|=source_id (16+16) domain_id is identifier of exporter instance +struct ipfix_exporter_schema *utable_ipfix_exporter_schema_new(const char *ipfix_schema_json_path, uint16_t domain_id, uint16_t n_worker); void utable_ipfix_exporter_schema_free(struct ipfix_exporter_schema *ipfix_schema); uint32_t utable_ipfix_template_flow_refresh_interval_s(struct ipfix_exporter_schema *ipfix_schema); |
