#include "gtest/gtest.h"
|
|
// #include "leveldb/env.h"
|
|
// #include "leveldb/db.h"
|
|
#include "fielddb/field_db.h"
|
|
using namespace fielddb;
|
|
|
|
constexpr int value_size = 2048;
|
|
constexpr int data_size = 128 << 20;
|
|
std::vector<std::string> cities = {
|
|
"Beijing", "Shanghai", "Guangzhou", "Shenzhen", "Hangzhou",
|
|
"Chengdu", "Chongqing", "Wuhan", "Suzhou", "Tianjin"
|
|
};
|
|
std::vector<std::string> shanghaiKeys;
|
|
|
|
Status OpenDB(std::string dbName, FieldDB **db) {
|
|
Options options;
|
|
options.create_if_missing = true;
|
|
return FieldDB::OpenFieldDB(options, dbName, db);
|
|
}
|
|
|
|
void ClearDB(FieldDB *db){
|
|
//destroy和恢复没做前先用这个清理数据库,否则跑不同的数据多做几次测试会污染
|
|
WriteOptions writeOptions;
|
|
int key_num = data_size / value_size;
|
|
for (int i = 0; i < key_num; i++) {
|
|
int key_ = i+1;
|
|
std::string key = std::to_string(key_);
|
|
Status s = db->Delete(WriteOptions(), key);
|
|
ASSERT_TRUE(s.ok());
|
|
}
|
|
}
|
|
|
|
void InsertFieldData(FieldDB *db) {
|
|
WriteOptions writeOptions;
|
|
int key_num = data_size / value_size;
|
|
srand(0);
|
|
|
|
for (int i = 0; i < key_num; i++) {
|
|
int randThisTime = rand(); //确保读写一个循环只rand一次,否则随机序列会不一致
|
|
int key_ = randThisTime % key_num+1;
|
|
std::string key = std::to_string(key_);
|
|
|
|
std::string name = "customer#" + std::to_string(key_);
|
|
std::string address = cities[randThisTime % cities.size()];
|
|
FieldArray fields = {
|
|
{"name", name},
|
|
{"address", address}
|
|
};
|
|
if (address == "Shanghai") {
|
|
shanghaiKeys.push_back(key);
|
|
}
|
|
Status s = db->PutFields(WriteOptions(), key, fields);
|
|
ASSERT_TRUE(s.ok());
|
|
}
|
|
}
|
|
|
|
void GetFieldData(FieldDB *db) {
|
|
ReadOptions readOptions;
|
|
int key_num = data_size / value_size;
|
|
|
|
// 点查
|
|
srand(0);
|
|
for (int i = 0; i < 100; i++) {
|
|
int randThisTime = rand();
|
|
int key_ = randThisTime % key_num+1;
|
|
std::string key = std::to_string(key_);
|
|
FieldArray fields_ret;
|
|
Status s = db->GetFields(readOptions, key, &fields_ret);
|
|
ASSERT_TRUE(s.ok());
|
|
for (const Field& pairs : fields_ret) {
|
|
if (pairs.first == "name"){
|
|
|
|
} else if (pairs.first == "address"){
|
|
std::string city = pairs.second;
|
|
ASSERT_NE(std::find(cities.begin(), cities.end(), city), cities.end());
|
|
} else assert(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void findKeysByCity(FieldDB *db) {
|
|
Field field = {"address", "Shanghai"};
|
|
std::vector<std::string> resKeys = db->FindKeysByField(field);
|
|
std::cout << shanghaiKeys.size() << " " << resKeys.size() << std::endl;
|
|
for (const std::string &key : resKeys){
|
|
ASSERT_NE(std::find(shanghaiKeys.begin(), shanghaiKeys.end(), key), shanghaiKeys.end());
|
|
}
|
|
}
|
|
|
|
void findKeysByCityIndex(FieldDB *db, bool expect) {
|
|
Field field = {"address", "Shanghai"};
|
|
Status s;
|
|
std::vector<std::string> resKeys = db->QueryByIndex(field, &s);
|
|
if (expect) ASSERT_TRUE(s.ok());
|
|
else {
|
|
ASSERT_TRUE(s.IsNotFound());
|
|
return;
|
|
}
|
|
std::cout << shanghaiKeys.size() << " " << resKeys.size() << std::endl;
|
|
for (const std::string &key : resKeys){
|
|
ASSERT_NE(std::find(shanghaiKeys.begin(), shanghaiKeys.end(), key), shanghaiKeys.end());
|
|
}
|
|
}
|
|
|
|
TEST(TestLab1, Basic) {
|
|
// DestroyDB("testdb",Options());
|
|
FieldDB *db = new FieldDB();
|
|
|
|
if(OpenDB("testdb", &db).ok() == false) {
|
|
std::cerr << "open db failed" << std::endl;
|
|
abort();
|
|
}
|
|
// ClearDB(db);
|
|
InsertFieldData(db);
|
|
GetFieldData(db);
|
|
findKeysByCity(db);
|
|
delete db;
|
|
}
|
|
|
|
TEST(TestLab2, Basic) {
|
|
//destroy
|
|
FieldDB *db = new FieldDB();
|
|
|
|
if(OpenDB("testdb2", &db).ok() == false) {
|
|
std::cerr << "open db failed" << std::endl;
|
|
abort();
|
|
}
|
|
// ClearDB(db);
|
|
shanghaiKeys.clear();
|
|
InsertFieldData(db);
|
|
// GetFieldData(db);
|
|
// findKeysByCity(db);
|
|
db->CreateIndexOnField("address");
|
|
findKeysByCityIndex(db, true);
|
|
db->DeleteIndex("address");
|
|
findKeysByCityIndex(db, false);
|
|
|
|
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();
|
|
}
|