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