214 lines
5.6 KiB
C++
214 lines
5.6 KiB
C++
#include <gtest/gtest.h>
|
|
#include <limits.h>
|
|
#include <iostream>
|
|
|
|
#include "os.h"
|
|
#include "taosdef.h"
|
|
#include "thash.h"
|
|
#include "taos.h"
|
|
|
|
namespace {
|
|
|
|
typedef struct TESTSTRUCT {
|
|
char *p;
|
|
}TESTSTRUCT;
|
|
|
|
// the simple test code for basic operations
|
|
void simpleTest() {
|
|
SHashObj* hashTable = (SHashObj*) taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_ENTRY_LOCK);
|
|
ASSERT_EQ(taosHashGetSize(hashTable), 0);
|
|
|
|
// put 400 elements in the hash table
|
|
for(int32_t i = -200; i < 200; ++i) {
|
|
taosHashPut(hashTable, (const char*) &i, sizeof(int32_t), (char*) &i, sizeof(int32_t));
|
|
}
|
|
|
|
ASSERT_EQ(taosHashGetSize(hashTable), 400);
|
|
|
|
for(int32_t i = 0; i < 200; ++i) {
|
|
char* p = (char*) taosHashGet(hashTable, (const char*) &i, sizeof(int32_t));
|
|
ASSERT_TRUE(p != nullptr);
|
|
ASSERT_EQ(*reinterpret_cast<int32_t*>(p), i);
|
|
}
|
|
|
|
for(int32_t i = 1000; i < 2000; ++i) {
|
|
taosHashRemove(hashTable, (const char*) &i, sizeof(int32_t));
|
|
}
|
|
|
|
ASSERT_EQ(taosHashGetSize(hashTable), 400);
|
|
|
|
for(int32_t i = 0; i < 100; ++i) {
|
|
taosHashRemove(hashTable, (const char*) &i, sizeof(int32_t));
|
|
}
|
|
|
|
ASSERT_EQ(taosHashGetSize(hashTable), 300);
|
|
|
|
for(int32_t i = 100; i < 150; ++i) {
|
|
taosHashRemove(hashTable, (const char*) &i, sizeof(int32_t));
|
|
}
|
|
|
|
ASSERT_EQ(taosHashGetSize(hashTable), 250);
|
|
taosHashCleanup(hashTable);
|
|
}
|
|
|
|
void stringKeyTest() {
|
|
auto* hashTable = (SHashObj*) taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
|
|
ASSERT_EQ(taosHashGetSize(hashTable), 0);
|
|
|
|
char key[128] = {0};
|
|
|
|
// put 200 elements in the hash table
|
|
for(int32_t i = 0; i < 1000; ++i) {
|
|
int32_t len = sprintf(key, "%d_1_%dabcefg_", i, i + 10);
|
|
taosHashPut(hashTable, key, len, (char*) &i, sizeof(int32_t));
|
|
}
|
|
|
|
ASSERT_EQ(taosHashGetSize(hashTable), 1000);
|
|
|
|
for(int32_t i = 0; i < 1000; ++i) {
|
|
int32_t len = sprintf(key, "%d_1_%dabcefg_", i, i + 10);
|
|
|
|
char* p = (char*) taosHashGet(hashTable, key, len);
|
|
ASSERT_TRUE(p != nullptr);
|
|
|
|
ASSERT_EQ(*reinterpret_cast<int32_t*>(p), i);
|
|
}
|
|
|
|
for(int32_t i = 500; i < 1000; ++i) {
|
|
int32_t len = sprintf(key, "%d_1_%dabcefg_", i, i + 10);
|
|
|
|
taosHashRemove(hashTable, key, len);
|
|
}
|
|
|
|
ASSERT_EQ(taosHashGetSize(hashTable), 500);
|
|
|
|
for(int32_t i = 0; i < 499; ++i) {
|
|
int32_t len = sprintf(key, "%d_1_%dabcefg_", i, i + 10);
|
|
|
|
taosHashRemove(hashTable, key, len);
|
|
}
|
|
|
|
ASSERT_EQ(taosHashGetSize(hashTable), 1);
|
|
|
|
taosHashCleanup(hashTable);
|
|
}
|
|
|
|
void functionTest() {
|
|
|
|
}
|
|
|
|
/**
|
|
* evaluate the performance issue, by add 10million elements in to hash table in
|
|
* a single threads situation
|
|
*/
|
|
void noLockPerformanceTest() {
|
|
auto* hashTable = (SHashObj*) taosHashInit(4096, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
|
|
ASSERT_EQ(taosHashGetSize(hashTable), 0);
|
|
|
|
char key[128] = {0};
|
|
int32_t num = 5000;
|
|
|
|
int64_t st = taosGetTimestampUs();
|
|
|
|
// put 10M elements in the hash table
|
|
for(int32_t i = 0; i < num; ++i) {
|
|
int32_t len = sprintf(key, "%d_1_%dabcefg_", i, i + 10);
|
|
taosHashPut(hashTable, key, len, (char*) &i, sizeof(int32_t));
|
|
}
|
|
|
|
ASSERT_EQ(taosHashGetSize(hashTable), num);
|
|
|
|
int64_t et = taosGetTimestampUs();
|
|
printf("Elpased time:%" PRId64 " us to add %d elements, avg cost:%lf us\n", et - st, num, (et - st)/(double) num);
|
|
|
|
st = taosGetTimestampUs();
|
|
for(int32_t i = 0; i < num; ++i) {
|
|
int32_t len = sprintf(key, "%d_1_%dabcefg_", i, i + 10);
|
|
char* p = (char*) taosHashGet(hashTable, key, len);
|
|
ASSERT_TRUE(p != nullptr);
|
|
|
|
ASSERT_EQ(*reinterpret_cast<int32_t*>(p), i);
|
|
}
|
|
|
|
et = taosGetTimestampUs();
|
|
printf("Elpased time:%" PRId64 " us to fetch all %d elements, avg cost:%lf us\n", et - st, num, (et - st)/(double) num);
|
|
|
|
printf("The maximum length of overflow linklist in hash table is:%d\n", taosHashGetMaxOverflowLinkLength(hashTable));
|
|
taosHashCleanup(hashTable);
|
|
}
|
|
|
|
void multithreadsTest() {
|
|
//todo
|
|
}
|
|
|
|
// check the function robustness
|
|
void invalidOperationTest() {
|
|
|
|
}
|
|
|
|
void acquireRleaseTest() {
|
|
SHashObj* hashTable = (SHashObj*) taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
|
|
ASSERT_EQ(taosHashGetSize(hashTable), 0);
|
|
|
|
int32_t key = 2;
|
|
int32_t code = 0;
|
|
int32_t num = 0;
|
|
TESTSTRUCT data = {0};
|
|
const char *str1 = "abcdefg";
|
|
const char *str2 = "aaaaaaa";
|
|
const char *str3 = "123456789";
|
|
|
|
data.p = (char *)taosMemoryMalloc(10);
|
|
strcpy(data.p, str1);
|
|
|
|
code = taosHashPut(hashTable, &key, sizeof(key), &data, sizeof(data));
|
|
ASSERT_EQ(code, 0);
|
|
|
|
TESTSTRUCT* pdata = (TESTSTRUCT*)taosHashAcquire(hashTable, &key, sizeof(key));
|
|
ASSERT_TRUE(pdata != nullptr);
|
|
ASSERT_TRUE(strcmp(pdata->p, str1) == 0);
|
|
|
|
code = taosHashRemove(hashTable, &key, sizeof(key));
|
|
ASSERT_EQ(code, 0);
|
|
ASSERT_TRUE(strcmp(pdata->p, str1) == 0);
|
|
|
|
num = taosHashGetSize(hashTable);
|
|
ASSERT_EQ(num, 1);
|
|
|
|
strcpy(pdata->p, str3);
|
|
|
|
data.p = (char *)taosMemoryMalloc(10);
|
|
strcpy(data.p, str2);
|
|
code = taosHashPut(hashTable, &key, sizeof(key), &data, sizeof(data));
|
|
ASSERT_EQ(code, 0);
|
|
num = taosHashGetSize(hashTable);
|
|
ASSERT_EQ(num, 2);
|
|
|
|
printf("%s,expect:%s", pdata->p, str3);
|
|
ASSERT_TRUE(strcmp(pdata->p, str3) == 0);
|
|
|
|
taosMemoryFreeClear(pdata->p);
|
|
|
|
taosHashRelease(hashTable, pdata);
|
|
num = taosHashGetSize(hashTable);
|
|
ASSERT_EQ(num, 1);
|
|
|
|
taosHashCleanup(hashTable);
|
|
taosMemoryFreeClear(data.p);
|
|
}
|
|
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
}
|
|
|
|
TEST(testCase, hashTest) {
|
|
simpleTest();
|
|
stringKeyTest();
|
|
noLockPerformanceTest();
|
|
multithreadsTest();
|
|
acquireRleaseTest();
|
|
}
|