diff options
| author | 刘学利 <[email protected]> | 2023-10-24 06:23:44 +0000 |
|---|---|---|
| committer | 刘学利 <[email protected]> | 2023-10-24 06:23:44 +0000 |
| commit | 5f60ecfcec55bc6aeaeaf54dd70552db32961a9a (patch) | |
| tree | 49262a7fd45a1baad5e80b50026b27848d92a92c | |
| parent | 6a506928a6e9674583c8e3dce2bfe9b6a219ac87 (diff) | |
Feature utable add integer api
| -rw-r--r-- | deps/utable/test/unit_test_utable.cpp | 54 | ||||
| -rw-r--r-- | deps/utable/utable.c | 100 | ||||
| -rw-r--r-- | deps/utable/utable.h | 10 |
3 files changed, 116 insertions, 48 deletions
diff --git a/deps/utable/test/unit_test_utable.cpp b/deps/utable/test/unit_test_utable.cpp index dd1e04f..4c15f2a 100644 --- a/deps/utable/test/unit_test_utable.cpp +++ b/deps/utable/test/unit_test_utable.cpp @@ -8,9 +8,9 @@ -void test_utable_assert_arr(const struct utable *table, const char *key, long long expected_arr[], size_t n_expected_arr) +void test_utable_assert_arr(const struct utable *table, const char *key, int64_t expected_arr[], size_t n_expected_arr) { - long long *arr = NULL; + int64_t *arr = NULL; size_t n_arr = 0; EXPECT_EQ(utable_get_value_type(table, key), utable_value_type_integer_array); utable_get0_integer_value_array(table, key, &arr, &n_arr); @@ -53,7 +53,7 @@ TEST(utable_test, new_del_when_empty) TEST(utable_test, add_1_int_and_query) { struct utable *table = utable_new(); - long long int_array[] = { 1 }; + int64_t int_array[] = { 1 }; utable_add_integer_array(table, "key", int_array, 1); test_utable_assert_arr(table, "key", int_array, 1); @@ -63,7 +63,7 @@ TEST(utable_test, add_1_int_and_query) TEST(utable_test, add_2_int_and_query) { struct utable *table = utable_new(); - long long int_array[] = { 1, 2 }; + int64_t int_array[] = { 1, 2 }; utable_add_integer_array(table, "key", int_array, 2); test_utable_assert_arr(table, "key", int_array, 2); @@ -74,7 +74,7 @@ TEST(utable_test, add_string_and_query) { struct utable *table = utable_new(); const char *str = "hello world"; - utable_add_cstring(table, "key", str); + utable_add_cstring(table, "key", str, strlen(str)); test_utable_assert_str(table, "key", str); utable_free(table); @@ -98,7 +98,7 @@ void test_utable_check_if_value_in_json(cJSON *tag_obj, const char *key, std::st EXPECT_STREQ(tag_val->valuestring, value.c_str()); } -void test_utable_check_if_value_in_json(cJSON *tag_obj, const char *key, long long value[], size_t n_value) +void test_utable_check_if_value_in_json(cJSON *tag_obj, const char *key, int64_t value[], size_t n_value) { cJSON *tag_val = cJSON_GetObjectItem(tag_obj, key); EXPECT_NE(tag_val, nullptr); @@ -127,11 +127,11 @@ void test_utable_check_if_value_in_json(cJSON *tag_obj, const char *key, const c TEST(utable_test, export_json) { struct utable *table = utable_new(); - long long int_array[] = { 1, 2 }; + int64_t int_array[] = { 1, 2 }; const char *str = "hello world"; const char *blob = "bin hello world"; utable_add_integer_array(table, "key1", int_array, 2); - utable_add_cstring(table, "key2", str); + utable_add_cstring(table, "key2", str, strlen(str)); utable_add_blob(table, "key3", blob, strlen(blob)); char *json = NULL; @@ -176,7 +176,7 @@ void test_utable_check_if_value_in_mpack(mpack_node_t item, const char *key, std free(value_tmp); } -void test_utable_check_if_value_in_mpack(mpack_node_t item, const char *key, long long value[], size_t n_value) +void test_utable_check_if_value_in_mpack(mpack_node_t item, const char *key, int64_t value[], size_t n_value) { mpack_node_t key_node = mpack_node_map_cstr(item, "key"); mpack_node_t type_node = mpack_node_map_cstr(item, "type"); @@ -214,11 +214,11 @@ void test_utable_check_if_value_in_mpack(mpack_node_t item, const char *key, con TEST(utable_test, export_mpack) { struct utable *table = utable_new(); - long long int_array[] = { 1, 2 }; + int64_t int_array[] = { 1, 2 }; const char *str = "hello world"; const char *blob = "bin hello world"; utable_add_integer_array(table, "key1", int_array, 2); - utable_add_cstring(table, "key2", str); + utable_add_cstring(table, "key2", str, strlen(str)); utable_add_blob(table, "key3", blob, strlen(blob)); char *mpack = NULL; @@ -251,7 +251,7 @@ TEST(utable_test, query_on_wrong_key) size_t value_len; EXPECT_EQ(utable_get0_blob_value(table, "key", &value, &value_len), -1); EXPECT_EQ(utable_get0_cstring_value(table, "key", &value, &value_len), -1); - long long *value_array; + int64_t *value_array; size_t n_value; EXPECT_EQ(utable_get0_integer_value_array(table, "key", &value_array, &n_value), -1); EXPECT_EQ(utable_get_value_type(table, "key"), utable_value_type_undefined); @@ -262,10 +262,10 @@ TEST(utable_test, query_on_wrong_key) TEST(utable_test, add_on_dup_key) { struct utable *table = utable_new(); - long long int_array[] = { 1, 2 }; + int64_t int_array[] = { 1, 2 }; const char *str = "hello world"; utable_add_integer_array(table, "key", int_array, 2); - utable_add_cstring(table, "key", str); + utable_add_cstring(table, "key", str, strlen(str)); test_utable_assert_arr(table, "key", int_array, 2); @@ -276,10 +276,10 @@ TEST(utable_test, iter_and_query) { struct utable *table = utable_new(); - long long int_array[] = { 1, 2 }; + int64_t int_array[] = { 1, 2 }; const char *str = "hello world"; utable_add_integer_array(table, "key1", int_array, 2); - utable_add_cstring(table, "key2", str); + utable_add_cstring(table, "key2", str, strlen(str)); utable_add_integer_array(table, "key3", int_array, 2); EXPECT_STREQ(utable_next_key(table), "key1"); @@ -311,8 +311,8 @@ TEST(utable_test, dup_and_query) struct utable *table = utable_new(); const char *str = "hello world"; - utable_add_cstring(table, "key1", str); - long long int_array[] = { 1, 2 }; + utable_add_cstring(table, "key1", str, strlen(str)); + int64_t int_array[] = { 1, 2 }; utable_add_integer_array(table, "key2", int_array, 2); const char *blob = "bin hello world"; utable_add_blob(table, "key3", blob, strlen(blob)); @@ -343,8 +343,8 @@ TEST(utable_test, merge_all_new) struct utable *table2 = utable_new(); const char *str = "hello world"; - utable_add_cstring(table, "key1", str); - long long int_array[] = { 1, 2 }; + utable_add_cstring(table, "key1", str, strlen(str)); + int64_t int_array[] = { 1, 2 }; utable_add_integer_array(table, "key2", int_array, 2); const char *blob = "bin hello world"; @@ -363,8 +363,8 @@ TEST(utable_test, merge_all_skip) { struct utable *table = utable_new(); const char *str = "hello world"; - utable_add_cstring(table, "key1", str); - long long int_array[] = { 1, 2 }; + utable_add_cstring(table, "key1", str, strlen(str)); + int64_t int_array[] = { 1, 2 }; utable_add_integer_array(table, "key2", int_array, 2); struct utable *table2 = utable_duplicate(table); @@ -384,11 +384,11 @@ TEST(utable_test, merge_some_skip_some_new) struct utable *table2 = utable_new(); const char *str = "val on tbl1"; - utable_add_cstring(table, "key_share", str); + utable_add_cstring(table, "key_share", str, strlen(str)); const char *str2 = "val on tbl2"; - utable_add_cstring(table2, "key_share", str2); + utable_add_cstring(table2, "key_share", str2, strlen(str2)); const char *str3 = "val on tbl1"; - utable_add_cstring(table, "key1", str3); + utable_add_cstring(table, "key1", str3, strlen(str3)); utable_merge(table2, table); @@ -402,11 +402,11 @@ TEST(utable_test, merge_some_skip_some_new) TEST(utable_test, serialize_and_deserialize) { struct utable *table = utable_new(); - long long int_array[] = { 1, 2 }; + int64_t int_array[] = { 1, 2 }; const char *str = "hello world"; const char *blob = "bin hello world"; utable_add_integer_array(table, "key1", int_array, 2); - utable_add_cstring(table, "key2", str); + utable_add_cstring(table, "key2", str, strlen(str)); utable_add_blob(table, "key3", blob, strlen(blob)); char *blob_out; diff --git a/deps/utable/utable.c b/deps/utable/utable.c index 6d23acb..81c3983 100644 --- a/deps/utable/utable.c +++ b/deps/utable/utable.c @@ -13,7 +13,11 @@ struct utable_item { char *key; enum utable_value_type value_type; union { - char *cstring; + struct + { + char *cstring; + size_t cstring_sz; + }; struct { char *blob; @@ -21,9 +25,10 @@ struct utable_item { }; struct { - long long *value_array; + int64_t *value_array; size_t n_value; }; + int64_t integer; }; UT_hash_handle hh; }; @@ -64,7 +69,7 @@ void utable_free(struct utable *table) free(table); } -void utable_add_cstring(struct utable *table, const char *key, const char *value) +void utable_add_cstring(struct utable *table, const char *key, const char *value, size_t value_sz) { // check if key already exists struct utable_item *item; @@ -77,7 +82,9 @@ void utable_add_cstring(struct utable *table, const char *key, const char *value item = calloc(1, sizeof(struct utable_item)); item->key = strdup(key); item->value_type = utable_value_type_cstring; - item->cstring = strdup(value); + item->cstring = malloc(value_sz); + memcpy(item->cstring, value, value_sz); + item->cstring_sz = value_sz; HASH_ADD_KEYPTR(hh, table->items, item->key, strlen(item->key), item); } @@ -100,7 +107,24 @@ void utable_add_blob(struct utable *table, const char *key, const char *blob, si HASH_ADD_KEYPTR(hh, table->items, item->key, strlen(item->key), item); } -void utable_add_integer_array(struct utable *table, const char *key, long long value_array[], size_t n_value) +void utable_add_integer(struct utable *table, const char *key, int64_t value) +{ + // check if key already exists + struct utable_item *item; + HASH_FIND_STR(table->items, key, item); + if (item) { + printf("ERR: key %s already exists\n", key); + return; + } + + item = calloc(1, sizeof(struct utable_item)); + item->key = strdup(key); + item->value_type = utable_value_type_integer; + item->integer = value; + HASH_ADD_KEYPTR(hh, table->items, item->key, strlen(item->key), item); +} + +void utable_add_integer_array(struct utable *table, const char *key, int64_t value_array[], size_t n_value) { // check if key already exists struct utable_item *item; @@ -113,8 +137,8 @@ void utable_add_integer_array(struct utable *table, const char *key, long long v item = calloc(1, sizeof(struct utable_item)); item->key = strdup(key); item->value_type = utable_value_type_integer_array; - item->value_array = malloc(sizeof(long long) * n_value); - memcpy(item->value_array, value_array, sizeof(long long) * n_value); + item->value_array = malloc(sizeof(int64_t) * n_value); + memcpy(item->value_array, value_array, sizeof(int64_t) * n_value); item->n_value = n_value; HASH_ADD_KEYPTR(hh, table->items, item->key, strlen(item->key), item); } @@ -193,22 +217,37 @@ int utable_get0_cstring_value(const struct utable *table, const char *key, char HASH_FIND_STR(table->items, key, item); if (item) { if (item->value_type == utable_value_type_cstring) { - *value = strdup(item->cstring); - *value_len = strlen(item->cstring); + char *cstring = malloc(item->cstring_sz); + *value = cstring; + *value_len = item->cstring_sz; + memcpy(cstring, item->cstring, item->cstring_sz); return 0; } } return -1; } -int utable_get0_integer_value_array(const struct utable *table, const char *key, long long **value_array, size_t *n_value) +int utable_get0_integer_value(const struct utable *table, const char *key, int64_t *value) +{ + struct utable_item *item; + HASH_FIND_STR(table->items, key, item); + if (item) { + if (item->value_type == utable_value_type_integer) { + *value = item->integer; + return 0; + } + } + return -1; +} + +int utable_get0_integer_value_array(const struct utable *table, const char *key, int64_t **value_array, size_t *n_value) { struct utable_item *item; HASH_FIND_STR(table->items, key, item); if (item) { if (item->value_type == utable_value_type_integer_array) { - *value_array = malloc(sizeof(long long) * item->n_value); - memcpy(*value_array, item->value_array, sizeof(long long) * item->n_value); + *value_array = malloc(sizeof(int64_t) * item->n_value); + memcpy(*value_array, item->value_array, sizeof(int64_t) * item->n_value); *n_value = item->n_value; return 0; } @@ -223,16 +262,21 @@ struct utable_item *utable_item_dup(const struct utable_item *item) new_item->value_type = item->value_type; switch (item->value_type) { case utable_value_type_cstring: - new_item->cstring = strdup(item->cstring); + new_item->cstring = malloc(item->cstring_sz); + memcpy(new_item->cstring, item->cstring, item->cstring_sz); + new_item->cstring_sz = item->cstring_sz; break; case utable_value_type_blob: new_item->blob = malloc(item->blob_sz); 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->value_array = malloc(sizeof(long long) * item->n_value); - memcpy(new_item->value_array, item->value_array, sizeof(long long) * item->n_value); + new_item->value_array = malloc(sizeof(int64_t) * item->n_value); + memcpy(new_item->value_array, item->value_array, sizeof(int64_t) * item->n_value); new_item->n_value = item->n_value; break; default: @@ -280,7 +324,13 @@ int utable_json_export(const struct utable *table, char **blob, size_t *blob_len HASH_ITER(hh, table->items, item, tmp) { switch (item->value_type) { case utable_value_type_cstring: - cJSON_AddStringToObject(cjson_root, item->key, item->cstring); + { + char *cstring=malloc(item->cstring_sz+1); + memcpy(cstring, item->cstring, item->cstring_sz); + cstring[item->cstring_sz] = '\0'; + cJSON_AddStringToObject(cjson_root, item->key, cstring); + free(cstring); + } break; case utable_value_type_blob: { char *enc = b64_encode((unsigned char *)item->blob, item->blob_sz); @@ -288,6 +338,9 @@ int utable_json_export(const struct utable *table, char **blob, size_t *blob_len free(enc); } break; + case utable_value_type_integer: + cJSON_AddNumberToObject(cjson_root, item->key, item->integer); + break; case utable_value_type_integer_array: { cJSON *cjson_array = cJSON_CreateArray(); for (size_t i = 0; i < item->n_value; i++) { @@ -336,6 +389,9 @@ int utable_msgpack_export(const struct utable *table, char **blob, size_t *blob_ case utable_value_type_blob: mpack_write_cstr(&writer, "blob"); break; + case utable_value_type_integer: + mpack_write_cstr(&writer, "i"); + break; case utable_value_type_integer_array: mpack_write_cstr(&writer, "i_arr"); break; @@ -346,11 +402,14 @@ int utable_msgpack_export(const struct utable *table, char **blob, size_t *blob_ mpack_write_cstr(&writer, "value"); switch (item->value_type) { case utable_value_type_cstring: - mpack_write_cstr(&writer, item->cstring); + mpack_write_bin(&writer, item->cstring, item->cstring_sz); break; case utable_value_type_blob: mpack_write_bin(&writer, item->blob, item->blob_sz); break; + case utable_value_type_integer: + mpack_write_i64(&writer, item->integer); + break; case utable_value_type_integer_array: mpack_start_array(&writer, item->n_value); for (size_t i = 0; i < item->n_value; i++) { @@ -411,12 +470,17 @@ struct utable *utable_deserialize(const char *blob, size_t blob_len) if (strcmp(type_str, "c_str") == 0) { new_item->value_type = utable_value_type_cstring; - new_item->cstring = get_cstring_from_mpack_node(value); + new_item->cstring = malloc(mpack_node_bin_size(value)); + new_item->cstring_sz = mpack_node_bin_size(value); + memcpy(new_item->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 = malloc(mpack_node_bin_size(value)); new_item->blob_sz = mpack_node_bin_size(value); memcpy(new_item->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); } else if (strcmp(type_str, "i_arr") == 0) { new_item->value_type = utable_value_type_integer_array; new_item->n_value = mpack_node_array_length(value); diff --git a/deps/utable/utable.h b/deps/utable/utable.h index b061f3b..25576f0 100644 --- a/deps/utable/utable.h +++ b/deps/utable/utable.h @@ -1,5 +1,6 @@ #pragma once +#include <stdint.h> #include <stddef.h> #ifdef __cplusplus @@ -11,9 +12,10 @@ struct utable; struct utable *utable_new(void); void utable_free(struct utable *table); -void utable_add_cstring(struct utable *table, const char *key, const char *value); +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_array(struct utable *table, const char *key, long long value_array[], size_t n_value); +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_delete_item(struct utable *table, const char *key); enum utable_value_type @@ -21,6 +23,7 @@ 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 }; @@ -29,7 +32,8 @@ const char *utable_next_key(struct utable *table); enum utable_value_type utable_get_value_type(const struct utable *table, const char *key); int utable_get0_blob_value(const struct utable *table, const char *key, char **value, size_t *value_len); int utable_get0_cstring_value(const struct utable *table, const char *key, char **value, size_t *value_len); -int utable_get0_integer_value_array(const struct utable *table, const char *key, long long **value_array, size_t *n_value); +int utable_get0_integer_value(const struct utable *table, const char *key, int64_t *value); +int utable_get0_integer_value_array(const struct utable *table, const char *key, int64_t **value_array, size_t *n_value); struct utable *utable_duplicate(const struct utable *table); int utable_merge(struct utable *dst, const struct utable *src); |
