@ -0,0 +1,94 @@ | |||||
#include "gtest/gtest.h" | |||||
#include "db/NewDB.h" // NewDB 的头文件 | |||||
#include "leveldb/env.h" | |||||
#include "leveldb/db.h" | |||||
#include "db/write_batch_internal.h" | |||||
#include <iostream> | |||||
#include <random> | |||||
#include <ctime> | |||||
#include <thread> | |||||
using namespace leveldb; | |||||
Status OpenNewDB(std::string dbName, NewDB** db) { | |||||
Options options = Options(); | |||||
options.create_if_missing = true; | |||||
return NewDB::Open(options, dbName, db); | |||||
} | |||||
Status OpenDB(std::string dbName, DB **db) { | |||||
Options options; | |||||
options.create_if_missing = true; | |||||
return DB::Open(options, dbName, db); | |||||
} | |||||
// 全局的随机数引擎 | |||||
std::default_random_engine rng; | |||||
// 设置随机种子 | |||||
void SetGlobalSeed(unsigned seed) { | |||||
rng.seed(seed); | |||||
} | |||||
// 生成随机字符串 | |||||
std::string GenerateRandomString(size_t length) { | |||||
static const char alphanum[] = | |||||
"0123456789" | |||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" | |||||
"abcdefghijklmnopqrstuvwxyz"; | |||||
std::uniform_int_distribution<int> dist(0, sizeof(alphanum) - 2); | |||||
std::string str(length, 0); | |||||
for (size_t i = 0; i < length; ++i) { | |||||
str[i] = alphanum[dist(rng)]; | |||||
} | |||||
return str; | |||||
} | |||||
std::string testdbname = "dbtest1"; | |||||
TEST(TestNewDB, ConstancyTest) { | |||||
// 创建 NewDB 实例 | |||||
NewDB* db; | |||||
ASSERT_TRUE(OpenNewDB(testdbname, &db).ok()); | |||||
db->CreateIndexOnField("address"); | |||||
delete db; | |||||
// 创建 NewDB 实例 | |||||
NewDB* db_2; | |||||
ASSERT_TRUE(OpenNewDB(testdbname, &db_2).ok()); | |||||
std::string key = "k_" + GenerateRandomString(10); | |||||
FieldArray fields = { | |||||
{"name", GenerateRandomString(5)}, | |||||
{"address", GenerateRandomString(15)}, | |||||
{"phone", GenerateRandomString(11)} | |||||
}; | |||||
std::string index_key = db->ConstructIndexKey(key, fields[1]); | |||||
db->Put_fields(WriteOptions(), key, fields); | |||||
delete db_2; | |||||
// 创建 DB 实例 | |||||
DB* index_db; | |||||
ASSERT_TRUE(OpenDB(testdbname + "_index", &index_db).ok()); | |||||
std::string prefix = index_key; | |||||
leveldb::Iterator* iter = index_db->NewIterator(leveldb::ReadOptions()); | |||||
for(iter->Seek(prefix); iter->Valid() && iter->key().starts_with(prefix); iter->Next()){ | |||||
Slice find_key = iter->key(); | |||||
EXPECT_EQ(find_key.ToString(), index_key); | |||||
} | |||||
delete iter; | |||||
delete index_db; | |||||
} | |||||
int main(int argc, char** argv) { | |||||
// 设置全局随机种子 | |||||
SetGlobalSeed(static_cast<unsigned>(time(nullptr))); | |||||
testing::InitGoogleTest(&argc, argv); | |||||
return RUN_ALL_TESTS(); | |||||
} |
@ -0,0 +1,26 @@ | |||||
#include "leveldb/db.h" | |||||
#include <iostream> | |||||
using namespace std; | |||||
using namespace leveldb; | |||||
int main() { | |||||
DB* db = nullptr; | |||||
Options op; | |||||
op.create_if_missing = true; | |||||
Status status = DB::Open(op, "testdb", &db); | |||||
assert(status.ok()); | |||||
db->Put(WriteOptions(), "001", "leveldb"); | |||||
string s; | |||||
db->Get(ReadOptions(), "001", &s); | |||||
cout<<s<<endl; | |||||
db->Put(WriteOptions(), "002", "world"); | |||||
string s1; | |||||
db->Delete(WriteOptions(), "002"); | |||||
db->Get(ReadOptions(), "002", &s1); | |||||
cout<<s1<<endl; | |||||
delete db; | |||||
return 0; | |||||
} |
@ -0,0 +1,96 @@ | |||||
#include "gtest/gtest.h" | |||||
#include "leveldb/env.h" | |||||
#include "leveldb/db.h" | |||||
// 这个头文件是为了EncodeFixed32 | |||||
#include "util/coding.h" | |||||
using namespace leveldb; | |||||
constexpr int value_size = 2048; | |||||
constexpr int data_size = 128 << 20; | |||||
Status OpenDB(std::string dbName, DB **db) { | |||||
Options options; | |||||
options.create_if_missing = true; | |||||
return DB::Open(options, dbName, db); | |||||
} | |||||
//测试多字段-橙 | |||||
TEST(TestSchema, Basic) { | |||||
DB *db; | |||||
if(OpenDB("testdb", &db).ok() == false) { | |||||
std::cerr << "open db failed" << std::endl; | |||||
abort(); | |||||
} | |||||
std::string key = "k_1"; | |||||
FieldArray fields = { | |||||
{"name", "Customer#000000001"}, | |||||
{"address", "IVhzIApeRb"}, | |||||
{"phone", "25-989-741-2988"} | |||||
}; | |||||
db->Put_fields(WriteOptions(), key, fields); | |||||
db->Get_fields(ReadOptions(), key, &fields); | |||||
//清理数据库 | |||||
delete db; | |||||
} | |||||
// 测试 FindKeysByField 函数 | |||||
/* | |||||
1.在测试中创建多个键值对,验证 FindKeysByField 能否正确地查找并返回匹配的键。 | |||||
2.使用 FindKeysByField 查找字段值,检查它是否能够找到匹配的键。 | |||||
*/ | |||||
TEST(TestSchema, FindKeysByFieldTest) { | |||||
DB *db; | |||||
if (OpenDB("testdb", &db).ok() == false) { | |||||
std::cerr << "open db failed" << std::endl; | |||||
abort(); | |||||
} | |||||
// 插入多个键值对 | |||||
std::string key1 = "k_1"; | |||||
FieldArray fields1 = { | |||||
{"name", "Customer#000000001"}, | |||||
{"address", "IVhzIApeRb"}, | |||||
{"phone", "25-989-741-2988"} | |||||
}; | |||||
db->Put_fields(WriteOptions(), key1, fields1); | |||||
std::string key2 = "k_2"; | |||||
FieldArray fields2 = { | |||||
{"name", "Customer#000000002"}, | |||||
{"address", "IVhzIApeRb"}, | |||||
{"phone", "25-123-456-7890"} | |||||
}; | |||||
db->Put_fields(WriteOptions(), key2, fields2); | |||||
std::string key3 = "k_3"; | |||||
FieldArray fields3 = { | |||||
{"name", "Customer#000000003"}, | |||||
{"address", "TXkjZEdIrZ"}, | |||||
{"phone", "25-555-888-1234"} | |||||
}; | |||||
db->Put_fields(WriteOptions(), key3, fields3); | |||||
// 测试 FindKeysByField | |||||
Field search_field = {"address", "IVhzIApeRb"}; | |||||
std::vector<std::string> matching_keys = db->FindKeysByField(db, search_field); | |||||
EXPECT_EQ(matching_keys.size(), 2); | |||||
EXPECT_TRUE(std::find(matching_keys.begin(), matching_keys.end(), key1) != matching_keys.end()); | |||||
EXPECT_TRUE(std::find(matching_keys.begin(), matching_keys.end(), key2) != matching_keys.end()); | |||||
// 清理数据库 | |||||
delete db; | |||||
} | |||||
int main(int argc, char** argv) { | |||||
// All tests currently run with the same read-only file limits. | |||||
testing::InitGoogleTest(&argc, argv); | |||||
return RUN_ALL_TESTS(); | |||||
} |
@ -1,119 +0,0 @@ | |||||
#include "gtest/gtest.h" | |||||
#include "leveldb/env.h" | |||||
#include "leveldb/db.h" | |||||
using namespace leveldb; | |||||
constexpr int value_size = 2048; | |||||
constexpr int data_size = 128 << 20; | |||||
Status OpenDB(std::string dbName, DB **db) { | |||||
Options options; | |||||
options.create_if_missing = true; | |||||
return DB::Open(options, dbName, db); | |||||
} | |||||
void InsertData(DB *db, uint64_t ttl/* second */) { | |||||
WriteOptions writeOptions; | |||||
int key_num = data_size / value_size; | |||||
srand(static_cast<unsigned int>(time(0))); | |||||
//srand(0); | |||||
for (int i = 0; i < key_num; i++) { | |||||
int key_ = rand() % key_num+1; | |||||
std::string key = std::to_string(key_); | |||||
std::string value(value_size, 'a'); | |||||
db->Put(writeOptions, key, value, ttl); | |||||
} | |||||
} | |||||
void GetData(DB *db, int size = (1 << 30)) { | |||||
ReadOptions readOptions; | |||||
int key_num = data_size / value_size; | |||||
// 点查 | |||||
srand(static_cast<unsigned int>(time(0))); | |||||
//srand(0); | |||||
for (int i = 0; i < 100; i++) { | |||||
int key_ = rand() % key_num+1; | |||||
std::string key = std::to_string(key_); | |||||
std::string value; | |||||
db->Get(readOptions, key, &value); | |||||
} | |||||
} | |||||
//暂时先注释掉写入Test-橙 | |||||
TEST(TestTTL, ReadTTL) { | |||||
DB *db; | |||||
if(OpenDB("testdb", &db).ok() == false) { | |||||
std::cerr << "open db failed" << std::endl; | |||||
abort(); | |||||
} | |||||
uint64_t ttl = 20; | |||||
InsertData(db, ttl); | |||||
ReadOptions readOptions; | |||||
Status status; | |||||
int key_num = data_size / value_size; | |||||
srand(static_cast<unsigned int>(time(0))); | |||||
for (int i = 0; i < 100; i++) { | |||||
int key_ = rand() % key_num+1; | |||||
std::string key = std::to_string(key_); | |||||
std::string value; | |||||
status = db->Get(readOptions, key, &value); | |||||
// 输出 key 值 | |||||
// std::cout << "Key: " << key << std::endl; | |||||
ASSERT_TRUE(status.ok()); | |||||
} | |||||
Env::Default()->SleepForMicroseconds(ttl * 1000000); | |||||
for (int i = 0; i < 100; i++) { | |||||
int key_ = rand() % key_num+1; | |||||
std::string key = std::to_string(key_); | |||||
std::string value; | |||||
status = db->Get(readOptions, key, &value); | |||||
ASSERT_FALSE(status.ok()); | |||||
} | |||||
delete db; | |||||
} | |||||
TEST(TestTTL, CompactionTTL) { | |||||
DB *db; | |||||
if(OpenDB("testdb", &db).ok() == false) { | |||||
std::cerr << "open db failed" << std::endl; | |||||
abort(); | |||||
} | |||||
uint64_t ttl = 20; | |||||
InsertData(db, ttl); | |||||
//这里为什么要定义两个ranges1?-橙 | |||||
leveldb::Range ranges[1]; | |||||
ranges[0] = leveldb::Range("-", "A"); | |||||
uint64_t sizes[1]; | |||||
db->GetApproximateSizes(ranges, 1, sizes); | |||||
// printf("part1\n"); | |||||
ASSERT_GT(sizes[0], 0); | |||||
Env::Default()->SleepForMicroseconds(ttl * 1000000); | |||||
db->CompactRange(nullptr, nullptr); | |||||
// 先注释掉重复定义的-橙 | |||||
// leveldb::Range ranges[1]; | |||||
ranges[0] = leveldb::Range("-", "A"); | |||||
// uint64_t sizes[1]; | |||||
db->GetApproximateSizes(ranges, 1, sizes); | |||||
ASSERT_EQ(sizes[0], 0); | |||||
} | |||||
int main(int argc, char** argv) { | |||||
// All tests currently run with the same read-only file limits. | |||||
testing::InitGoogleTest(&argc, argv); | |||||
return RUN_ALL_TESTS(); | |||||
} |