#include #include #include #include #include #include #include #include #include #include "leveldb/env.h" #include "gtest/gtest.h" using namespace leveldb; //// 序列化函数,将字段数组编码为字符串 //std::string SerializeValue(const FieldArray& fields) { // // 创建并初始化一个字符串流 oss,用于逐步构建最终的序列化字符串 // std::ostringstream oss_temp; // std::string slot_num = "slot_num"; // oss_temp << std::setw(sizeof(size_t)) << std::setfill('0') << slot_num; // // 写入属性个数(定长,16比特),使用std::setw(16)设置宽度,使用std::setfull(0)设置填充字符,将字段数组的大小写入oss中 // oss_temp << std::setw(16) << std::setfill('0') << fields.size(); // for (const auto& field : fields) { // // 写入属性名长度(定长,16比特) // oss_temp << std::setw(16) << std::setfill('0') << field.name.size(); // // 写入属性名(变长) // oss_temp << field.name; // // 写入属性值长度(定长,16比特) // oss_temp << std::setw(16) << std::setfill('0') << field.value.size(); // // 写入属性值(变长) // oss_temp << field.value; // } // std::string temp_str = oss_temp.str(); // size_t value_length = temp_str.size(); // // std::ostringstream oss; // oss << std::setw(16) << std::setfill('0') << value_length; // oss << temp_str; // // std::cout << "value 的长度为: " << value_length << std::endl; // std::cout << "总长度为: " << oss.str().size() << std::endl; // return oss.str(); //} //// 反序列化函数,将字符串解码为字段数组 //FieldArray ParseValue(const std::string& value_str) { // // 存放解析后的字段数组 // FieldArray fields; // // 将输入字符串转换为输入流 iss, 方便读取 // std::istringstream iss(value_str); // std::string content; // // 临时存放读取的数据 // char buffer[100]; // // 读取长度(定长,16比特) // iss.read(buffer, 16); // buffer[16] = '\0'; // size_t total_length = std::stoi(buffer); // // std::cout << "读取到的总长度为: " << total_length << std::endl; // std::string value_content(value_str.begin() + 16, value_str.begin() + 16 + total_length); // // std::cout << value_content << std::endl; // std::istringstream iss_content(value_content); // iss_content.read(buffer, sizeof(size_t)); // buffer[sizeof(size_t)] = '\0'; // std::string slot_num = buffer; // // 读取属性个数 // iss_content.read(buffer, 16); // // 在第17个比特位处添加终结符,确保字符串以终结符结尾 // buffer[16] = '\0'; // // 将 buffer 中的内容转化为整数并赋值给 field_count // int field_count = std::stoi(buffer); // // std::cout << "读取到的字段个数为: " << field_count << std::endl; // // for (int i = 0; i < field_count; ++i) { // Field field; // // 读取属性名长度(定长,16比特) // iss_content.read(buffer, 16); // buffer[16] = '\0'; // int name_length = std::stoi(buffer); // // std::cout << "读取到的属性名长度为: " << name_length << std::endl; // // 读取属性名(变长) // field.name.resize(name_length); // iss_content.read(&field.name[0], name_length); // // std::cout << "读取到的属性名为: " << field.name << std::endl; // // 读取属性值长度(定长,16比特) // iss_content.read(buffer, 16); // buffer[16] = '\0'; // int value_length = std::stoi(buffer); // // std::cout << "读取到的属性值长度为: " << value_length << std::endl; // // 读取属性值(变长) // field.value.resize(value_length); // iss_content.read(&field.value[0], value_length); // // std::cout << "读取到的属性值为: " << field.value << std::endl; // fields.push_back(field); // } // return fields; //} // 根据字段值查找所有包含该字段的 key,遍历 std::vector FindKeysByField(leveldb::DB* db, const Field& field) { std::vector keys; leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions()); for (it->SeekToFirst(); it->Valid() ; it->Next()) { std::string key = it->key().ToString(); FieldArray fields; db->Get_Fields(leveldb::ReadOptions(), key, &fields); for (const auto& f : fields) { if (f.name == field.name && f.value == field.value) { keys.push_back(key); break; // 假设每个key中每个字段值唯一 } } } delete it; return keys; } Status OpenDB(std::string dbName, DB** db) { Options options; options.create_if_missing = true; return DB::Open(options, dbName, db); } // 吞吐量测试函数 void TestThroughput(leveldb::DB* db, int num_operations) { WriteOptions writeOptions; auto start_time = std::chrono::steady_clock::now(); for (int i = 0; i < num_operations; ++i) { std::string key = "key_" + std::to_string(i); FieldArray fields = {{"name", "Customer" + std::to_string(i)}, {"address", "Address" + std::to_string(i)}, {"phone", "1234567890"}}; db->Put_Fields(writeOptions, key, fields); } auto end_time = std::chrono::steady_clock::now(); auto duration = std::chrono::duration_cast(end_time - start_time).count(); std::cout << "Throughput: " << num_operations * 1000 / duration << " OPS" << std::endl; } // 延迟测试函数 void TestLatency(leveldb::DB* db, int num_operations, std::vector& lat_res) { WriteOptions writeOptions; int64_t latency = 0; auto end_time = std::chrono::steady_clock::now(); auto last_time = end_time; for (int i = 0; i < num_operations; ++i) { // 执行写入操作 std::string key = "key_" + std::to_string(i); FieldArray fields = {{"name", "Customer" + std::to_string(i)}, {"address", "Address" + std::to_string(i)}, {"phone", "1234567890"}}; db->Put_Fields(writeOptions, key, fields); db->Get_Fields(leveldb::ReadOptions(), key, &fields); end_time = std::chrono::steady_clock::now(); latency = std::chrono::duration_cast( end_time - last_time).count(); last_time = end_time; lat_res.emplace_back(latency); } // 输出延迟统计信息(可选) double avg_latency = std::accumulate(lat_res.begin(), lat_res.end(), 0.0) / lat_res.size(); std::cout << "Average Latency: " << std::fixed << std::setprecision(2) << avg_latency << " ms" << std::endl; std::cout << "Max Latency: " << *std::max_element(lat_res.begin(), lat_res.end()) << " ms" << std::endl; std::cout << "Min Latency: " << *std::min_element(lat_res.begin(), lat_res.end()) << " ms" << std::endl; } TEST(TestSchema, Basic) { DB* db; WriteOptions writeOptions; ReadOptions readOptions; if (!OpenDB("testdb", &db).ok()) { std::cerr << "open db failed" << std::endl; abort(); } std::string key1 = "k_1"; std::string key2 = "k_2"; std::string key3 = "k_3"; FieldArray fields1 = { {"name", "Customer1"}, {"address", "IVhzIApeRb"}, {"phone", "25-989-741-2988"} }; FieldArray fields2 = { {"name", "Customer1"}, {"address", "ecnu"}, {"phone", "123456789"} }; FieldArray fields3 = { {"name", "Customer2"}, {"address", "ecnu"}, {"phone", "11111"} }; db->Put_Fields(leveldb::WriteOptions(), key1, fields1); db->Put_Fields(leveldb::WriteOptions(), key2, fields2); db->Put_Fields(leveldb::WriteOptions(), key3, fields3); // 读取并反序列化 std::string value_ret; FieldArray fields_ret; db->Get_Fields(leveldb::ReadOptions(), key1, &fields_ret); // 检查反序列化结果 ASSERT_EQ(fields_ret.size(), fields1.size()); for (size_t i = 0; i < fields_ret.size(); ++i) { ASSERT_EQ(fields_ret[i].name, fields1[i].name); ASSERT_EQ(fields_ret[i].value, fields1[i].value); } // 测试查找功能 Field query_field = {"name", "Customer2"}; std::vector found_keys = FindKeysByField(db, query_field); std::cout << "找到的key有:" << found_keys.size() << "个" << std::endl; /*// 吞吐量测试 TestThroughput(db, 10000);*/ /* // 延迟测试 std::vector latency_results; TestLatency(db, 1000, latency_results);*/ // 关闭数据库 delete db; } int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }