homework-jianmu/source/util/test/hashTest.cpp

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();
}