2023-02-03 17:28:14 +08:00
|
|
|
#include "rcu_hash.h"
|
|
|
|
|
#include "maat_utils.h"
|
2022-11-17 05:05:35 +08:00
|
|
|
|
2022-11-25 16:32:29 +08:00
|
|
|
#include <gtest/gtest.h>
|
2022-11-17 05:05:35 +08:00
|
|
|
|
|
|
|
|
struct user_data {
|
|
|
|
|
int id;
|
|
|
|
|
char name[32];
|
|
|
|
|
};
|
|
|
|
|
|
2022-11-25 16:32:29 +08:00
|
|
|
void data_free(void *user_ctx, void *data)
|
2022-11-17 05:05:35 +08:00
|
|
|
{
|
2022-12-05 23:21:18 +08:00
|
|
|
FREE(data);
|
2022-11-17 05:05:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(rcu_hash_new, invalid_input_parameter) {
|
|
|
|
|
struct rcu_hash_table *htable = rcu_hash_new(nullptr);
|
|
|
|
|
EXPECT_EQ(htable, nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-25 16:32:29 +08:00
|
|
|
TEST(rcu_hash_add_one_node, single_thread) {
|
|
|
|
|
/* add one node to hash */
|
|
|
|
|
struct rcu_hash_table *htable = rcu_hash_new(data_free);
|
|
|
|
|
EXPECT_NE(htable, nullptr);
|
|
|
|
|
|
|
|
|
|
struct user_data *data = ALLOC(struct user_data, 1);
|
|
|
|
|
data->id = 101;
|
|
|
|
|
char name[64] = "www.baidu.com";
|
|
|
|
|
memcpy(data->name, name, strlen(name));
|
|
|
|
|
char key[64] = "http_url";
|
|
|
|
|
size_t key_len = strlen(key);
|
|
|
|
|
|
|
|
|
|
/* add to hash */
|
|
|
|
|
rcu_hash_add(htable, key, key_len, (void *)data);
|
|
|
|
|
|
|
|
|
|
/* find in hash before commit */
|
|
|
|
|
void *res = rcu_hash_find(htable, key, key_len);
|
|
|
|
|
EXPECT_EQ(res, nullptr);
|
|
|
|
|
|
|
|
|
|
int ret = rcu_hash_count(htable);
|
|
|
|
|
EXPECT_EQ(ret, 0);
|
|
|
|
|
|
|
|
|
|
ret = rcu_hash_garbage_queue_len(htable);
|
|
|
|
|
EXPECT_EQ(ret, 0);
|
|
|
|
|
|
2022-11-29 14:12:40 +08:00
|
|
|
void **data_array = NULL;
|
|
|
|
|
ret = rcu_hash_list_updating_data(htable, &data_array);
|
|
|
|
|
EXPECT_EQ(ret, 1);
|
|
|
|
|
|
2022-11-25 16:32:29 +08:00
|
|
|
rcu_hash_commit(htable);
|
|
|
|
|
|
|
|
|
|
/* find in hash after commit */
|
|
|
|
|
res = rcu_hash_find(htable, key, key_len);
|
|
|
|
|
EXPECT_NE(res, nullptr);
|
|
|
|
|
|
|
|
|
|
struct user_data *res_data = (struct user_data *)res;
|
|
|
|
|
EXPECT_EQ(res_data->id, 101);
|
|
|
|
|
EXPECT_STREQ(res_data->name, "www.baidu.com");
|
|
|
|
|
|
|
|
|
|
ret = rcu_hash_count(htable);
|
|
|
|
|
EXPECT_EQ(ret, 1);
|
|
|
|
|
|
|
|
|
|
ret = rcu_hash_garbage_queue_len(htable);
|
|
|
|
|
EXPECT_EQ(ret, 0);
|
|
|
|
|
|
2022-11-29 14:12:40 +08:00
|
|
|
ret = rcu_hash_list_updating_data(htable, &data_array);
|
|
|
|
|
EXPECT_EQ(ret, 0);
|
|
|
|
|
|
2022-11-25 16:32:29 +08:00
|
|
|
rcu_hash_free(htable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(rcu_hash_add_multi_node, single_thread) {
|
|
|
|
|
/* add multi node to hash */
|
|
|
|
|
struct rcu_hash_table *htable = rcu_hash_new(data_free);
|
|
|
|
|
EXPECT_NE(htable, nullptr);
|
|
|
|
|
|
|
|
|
|
struct user_data *data0 = ALLOC(struct user_data, 1);
|
|
|
|
|
data0->id = 101;
|
|
|
|
|
char name0[64] = "www.baidu.com";
|
|
|
|
|
memcpy(data0->name, name0, strlen(name0));
|
|
|
|
|
char key0[64] = "http_url";
|
|
|
|
|
size_t key0_len = strlen(key0);
|
|
|
|
|
rcu_hash_add(htable, key0, key0_len, (void *)data0);
|
|
|
|
|
|
|
|
|
|
struct user_data *data1 = ALLOC(struct user_data, 1);
|
|
|
|
|
data1->id = 102;
|
|
|
|
|
char name1[64] = "127.0.0.1";
|
|
|
|
|
memcpy(data1->name, name1, strlen(name1));
|
|
|
|
|
char key1[64] = "http_host";
|
|
|
|
|
size_t key1_len = strlen(key1);
|
|
|
|
|
rcu_hash_add(htable, key1, key1_len, (void *)data1);
|
|
|
|
|
|
|
|
|
|
/* find in hash before commit */
|
|
|
|
|
void *res = rcu_hash_find(htable, key0, key0_len);
|
|
|
|
|
EXPECT_EQ(res, nullptr);
|
|
|
|
|
res = rcu_hash_find(htable, key1, key1_len);
|
|
|
|
|
EXPECT_EQ(res, nullptr);
|
|
|
|
|
|
|
|
|
|
int ret = rcu_hash_count(htable);
|
|
|
|
|
EXPECT_EQ(ret, 0);
|
|
|
|
|
|
|
|
|
|
ret = rcu_hash_garbage_queue_len(htable);
|
|
|
|
|
EXPECT_EQ(ret, 0);
|
|
|
|
|
|
2022-11-29 14:12:40 +08:00
|
|
|
void **data_array = NULL;
|
|
|
|
|
ret = rcu_hash_list_updating_data(htable, &data_array);
|
|
|
|
|
EXPECT_EQ(ret, 2);
|
|
|
|
|
|
2022-11-25 16:32:29 +08:00
|
|
|
rcu_hash_commit(htable);
|
|
|
|
|
|
|
|
|
|
/* find in hash after commit */
|
|
|
|
|
res = rcu_hash_find(htable, key0, key0_len);
|
|
|
|
|
EXPECT_NE(res, nullptr);
|
|
|
|
|
|
|
|
|
|
struct user_data *res_data0 = (struct user_data *)res;
|
|
|
|
|
EXPECT_EQ(res_data0->id, 101);
|
|
|
|
|
EXPECT_STREQ(res_data0->name, "www.baidu.com");
|
|
|
|
|
|
|
|
|
|
res = rcu_hash_find(htable, key1, key1_len);
|
|
|
|
|
EXPECT_NE(res, nullptr);
|
|
|
|
|
|
|
|
|
|
struct user_data *res_data1 = (struct user_data *)res;
|
|
|
|
|
EXPECT_EQ(res_data1->id, 102);
|
|
|
|
|
EXPECT_STREQ(res_data1->name, "127.0.0.1");
|
|
|
|
|
|
|
|
|
|
ret = rcu_hash_count(htable);
|
|
|
|
|
EXPECT_EQ(ret, 2);
|
|
|
|
|
|
|
|
|
|
ret = rcu_hash_garbage_queue_len(htable);
|
|
|
|
|
EXPECT_EQ(ret, 0);
|
|
|
|
|
|
2022-11-29 14:12:40 +08:00
|
|
|
ret = rcu_hash_list_updating_data(htable, &data_array);
|
|
|
|
|
EXPECT_EQ(ret, 0);
|
|
|
|
|
|
2022-11-25 16:32:29 +08:00
|
|
|
rcu_hash_free(htable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(rcu_hash_del_one_node, single_thread) {
|
|
|
|
|
/* case1: add and del before commit */
|
2022-11-17 05:05:35 +08:00
|
|
|
struct rcu_hash_table *htable = rcu_hash_new(data_free);
|
|
|
|
|
EXPECT_NE(htable, nullptr);
|
|
|
|
|
|
|
|
|
|
struct user_data *data = ALLOC(struct user_data, 1);
|
|
|
|
|
data->id = 101;
|
2022-11-25 16:32:29 +08:00
|
|
|
char name[64] = "www.baidu.com";
|
2022-11-17 05:05:35 +08:00
|
|
|
memcpy(data->name, name, strlen(name));
|
2022-11-25 16:32:29 +08:00
|
|
|
char key[64] = "http_url";
|
2022-11-17 05:05:35 +08:00
|
|
|
size_t key_len = strlen(key);
|
|
|
|
|
|
2022-11-25 16:32:29 +08:00
|
|
|
/* add to hash */
|
2022-11-17 05:05:35 +08:00
|
|
|
rcu_hash_add(htable, key, key_len, (void *)data);
|
|
|
|
|
|
2022-11-29 14:12:40 +08:00
|
|
|
void **data_array = NULL;
|
|
|
|
|
int ret = rcu_hash_list_updating_data(htable, &data_array);
|
|
|
|
|
EXPECT_EQ(ret, 1);
|
|
|
|
|
|
2022-11-25 16:32:29 +08:00
|
|
|
/* find in hash before commit */
|
2022-11-17 05:05:35 +08:00
|
|
|
void *res = rcu_hash_find(htable, key, key_len);
|
|
|
|
|
EXPECT_EQ(res, nullptr);
|
|
|
|
|
|
2022-11-29 14:12:40 +08:00
|
|
|
ret = rcu_hash_count(htable);
|
2022-11-25 16:32:29 +08:00
|
|
|
EXPECT_EQ(ret, 0);
|
|
|
|
|
|
|
|
|
|
ret = rcu_hash_garbage_queue_len(htable);
|
|
|
|
|
EXPECT_EQ(ret, 0);
|
|
|
|
|
|
|
|
|
|
rcu_hash_del(htable, key, key_len);
|
|
|
|
|
|
2022-11-29 14:12:40 +08:00
|
|
|
ret = rcu_hash_list_updating_data(htable, &data_array);
|
|
|
|
|
EXPECT_EQ(ret, 0);
|
|
|
|
|
|
2022-11-17 05:05:35 +08:00
|
|
|
rcu_hash_commit(htable);
|
|
|
|
|
|
2022-11-25 16:32:29 +08:00
|
|
|
/* find in hash after commit */
|
2022-11-17 05:05:35 +08:00
|
|
|
res = rcu_hash_find(htable, key, key_len);
|
2022-11-25 16:32:29 +08:00
|
|
|
EXPECT_EQ(res, nullptr);
|
|
|
|
|
|
|
|
|
|
/* case2: add && commit, and del */
|
|
|
|
|
struct user_data *data1 = ALLOC(struct user_data, 1);
|
|
|
|
|
data1->id = 102;
|
|
|
|
|
char name1[64] = "127.0.0.1";
|
|
|
|
|
memcpy(data1->name, name1, strlen(name1));
|
|
|
|
|
char key1[64] = "http_host";
|
|
|
|
|
size_t key1_len = strlen(key1);
|
|
|
|
|
rcu_hash_add(htable, key1, key1_len, (void *)data1);
|
|
|
|
|
|
|
|
|
|
/* add commit */
|
|
|
|
|
rcu_hash_commit(htable);
|
|
|
|
|
|
|
|
|
|
rcu_hash_del(htable, key1, key1_len);
|
|
|
|
|
|
|
|
|
|
res = rcu_hash_find(htable, key1, key1_len);
|
2022-11-17 05:05:35 +08:00
|
|
|
EXPECT_NE(res, nullptr);
|
2022-11-25 16:32:29 +08:00
|
|
|
|
|
|
|
|
struct user_data *res_data = (struct user_data *)res;
|
|
|
|
|
EXPECT_EQ(res_data->id, 102);
|
|
|
|
|
EXPECT_STREQ(res_data->name, "127.0.0.1");
|
|
|
|
|
|
|
|
|
|
ret = rcu_hash_count(htable);
|
|
|
|
|
EXPECT_EQ(ret, 1);
|
|
|
|
|
|
|
|
|
|
ret = rcu_hash_garbage_queue_len(htable);
|
|
|
|
|
EXPECT_EQ(ret, 1);
|
2022-11-17 05:05:35 +08:00
|
|
|
|
2022-11-25 16:32:29 +08:00
|
|
|
/* delete commit */
|
|
|
|
|
rcu_hash_commit(htable);
|
|
|
|
|
res = rcu_hash_find(htable, key1, key1_len);
|
|
|
|
|
EXPECT_EQ(res, nullptr);
|
|
|
|
|
|
|
|
|
|
ret = rcu_hash_count(htable);
|
|
|
|
|
EXPECT_EQ(ret, 0);
|
|
|
|
|
|
|
|
|
|
ret = rcu_hash_garbage_queue_len(htable);
|
|
|
|
|
EXPECT_EQ(ret, 0);
|
|
|
|
|
|
|
|
|
|
rcu_hash_free(htable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST(rcu_hash_del_multi_node, single_thread) {
|
|
|
|
|
/* case1: add and del before commit */
|
|
|
|
|
struct rcu_hash_table *htable = rcu_hash_new(data_free);
|
|
|
|
|
EXPECT_NE(htable, nullptr);
|
|
|
|
|
|
|
|
|
|
struct user_data *data1 = ALLOC(struct user_data, 1);
|
|
|
|
|
data1->id = 101;
|
|
|
|
|
char name1[64] = "www.baidu.com";
|
|
|
|
|
memcpy(data1->name, name1, strlen(name1));
|
|
|
|
|
char key1[64] = "http_url";
|
|
|
|
|
size_t key1_len = strlen(key1);
|
|
|
|
|
rcu_hash_add(htable, key1, key1_len, (void *)data1);
|
|
|
|
|
|
|
|
|
|
struct user_data *data2 = ALLOC(struct user_data, 1);
|
|
|
|
|
data2->id = 102;
|
|
|
|
|
char name2[64] = "127.0.0.1";
|
|
|
|
|
memcpy(data2->name, name2, strlen(name2));
|
|
|
|
|
char key2[64] = "http_host";
|
|
|
|
|
size_t key2_len = strlen(key2);
|
|
|
|
|
rcu_hash_add(htable, key2, key2_len, (void *)data2);
|
|
|
|
|
|
|
|
|
|
/* find in hash before commit */
|
|
|
|
|
void *res = rcu_hash_find(htable, key1, key1_len);
|
|
|
|
|
EXPECT_EQ(res, nullptr);
|
|
|
|
|
|
|
|
|
|
int ret = rcu_hash_count(htable);
|
|
|
|
|
EXPECT_EQ(ret, 0);
|
|
|
|
|
|
|
|
|
|
ret = rcu_hash_garbage_queue_len(htable);
|
|
|
|
|
EXPECT_EQ(ret, 0);
|
|
|
|
|
|
|
|
|
|
/* add del, then commit */
|
|
|
|
|
rcu_hash_del(htable, key1, key1_len);
|
|
|
|
|
|
|
|
|
|
ret = rcu_hash_garbage_queue_len(htable);
|
|
|
|
|
EXPECT_EQ(ret, 1);
|
|
|
|
|
|
|
|
|
|
rcu_hash_commit(htable);
|
|
|
|
|
|
|
|
|
|
/* find in hash after commit */
|
|
|
|
|
res = rcu_hash_find(htable, key1, key1_len);
|
|
|
|
|
EXPECT_EQ(res, nullptr);
|
|
|
|
|
|
|
|
|
|
res = rcu_hash_find(htable, key2, key2_len);
|
|
|
|
|
EXPECT_NE(res, nullptr);
|
|
|
|
|
|
|
|
|
|
ret = rcu_hash_count(htable);
|
|
|
|
|
EXPECT_EQ(ret, 1);
|
|
|
|
|
|
|
|
|
|
ret = rcu_hash_garbage_queue_len(htable);
|
|
|
|
|
EXPECT_EQ(ret, 0);
|
|
|
|
|
|
|
|
|
|
rcu_hash_free(htable);
|
2022-11-17 05:05:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(int argc, char ** argv)
|
|
|
|
|
{
|
|
|
|
|
int ret=0;
|
|
|
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
|
|
|
ret=RUN_ALL_TESTS();
|
|
|
|
|
return ret;
|
|
|
|
|
}
|