From 6c0b64cfa391ac5b17d2ea3ecd4d6a94c8947d02 Mon Sep 17 00:00:00 2001 From: augurier <14434658+augurier@user.noreply.gitee.com> Date: Sun, 22 Dec 2024 20:13:50 +0800 Subject: [PATCH] =?UTF-8?q?=E6=AD=A3=E5=B8=B8=E9=80=80=E5=87=BA=E7=9A=84?= =?UTF-8?q?=E6=81=A2=E5=A4=8D=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 5 +++ fielddb/field_db.cpp | 13 +++++--- fielddb/field_db.h | 1 + test/recover_test.cc | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 test/recover_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index fa7468f..aadc1cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -535,3 +535,8 @@ add_executable(parallel_test "${PROJECT_SOURCE_DIR}/test/parallel_test.cc" ) target_link_libraries(parallel_test PRIVATE leveldb gtest) + +add_executable(recover_test + "${PROJECT_SOURCE_DIR}/test/recover_test.cc" +) +target_link_libraries(recover_test PRIVATE leveldb gtest) diff --git a/fielddb/field_db.cpp b/fielddb/field_db.cpp index c7e094e..a83960f 100644 --- a/fielddb/field_db.cpp +++ b/fielddb/field_db.cpp @@ -60,11 +60,11 @@ Status FieldDB::Recover() { std::string IndexKey; Iter->SeekToFirst(); while(Iter->Valid()) { - IndexKey = Iter->value().ToString(); + IndexKey = Iter->key().ToString(); ParsedInternalIndexKey ParsedIndex; ParseInternalIndexKey(Slice(IndexKey),&ParsedIndex); index_[ParsedIndex.name_.ToString()] = {Exist,nullptr}; - std::cout << "Existed Index : " << ParsedIndex.name_.ToString() << std::endl; + //std::cout << "Existed Index : " << ParsedIndex.name_.ToString() << std::endl; //构建下一个搜索的对象,在原来的fieldname的基础上加一个最大的ascii字符(不可见字符) //TODO:不知道这个做法有没有道理 @@ -183,8 +183,7 @@ Again: // return status; } - -//这里把一个空串作为常规put的name +// 这里把一个空串作为常规put的name Status FieldDB::Put(const WriteOptions &options, const Slice &key, const Slice &value) { FieldArray FA = {{"",value.ToString()}}; return PutFields(options, key, FA); @@ -364,4 +363,10 @@ Status DestroyDB(const std::string& name, const Options& options) { return s; } +FieldDB::~FieldDB() { + delete indexDB_; + delete kvDB_; + delete metaDB_; +} + } // namespace fielddb diff --git a/fielddb/field_db.h b/fielddb/field_db.h index 684a820..f0fe5f2 100644 --- a/fielddb/field_db.h +++ b/fielddb/field_db.h @@ -33,6 +33,7 @@ public: //用的时候必须FieldDB *db = new FieldDB()再open,不能像之前一样DB *db FieldDB() : indexDB_(nullptr), kvDB_(nullptr), metaDB_(nullptr) {}; + ~FieldDB(); /*lab1的要求,作为db派生类要实现的虚函数*/ Status Put(const WriteOptions &options, const Slice &key, const Slice &value) override; Status PutFields(const WriteOptions &, const Slice &key, const FieldArray &fields) override; diff --git a/test/recover_test.cc b/test/recover_test.cc new file mode 100644 index 0000000..4b05c1d --- /dev/null +++ b/test/recover_test.cc @@ -0,0 +1,86 @@ +#include "gtest/gtest.h" +// #include "leveldb/env.h" +// #include "leveldb/db.h" +#include "fielddb/field_db.h" +#include "test/helper.cc" +#include +#include +#include +using namespace fielddb; + +// std::atomic thread_has_error(false); + +// void signalHandler(int signum) { +// // 捕捉段错误 +// } + +TEST(TestNormalRecover, Recover) { + fielddb::DestroyDB("testdb3.1",Options()); + FieldDB *db = new FieldDB(); + + if(OpenDB("testdb3.1", &db).ok() == false) { + std::cerr << "open db failed" << std::endl; + abort(); + } + db->CreateIndexOnField("address"); + db->CreateIndexOnField("age"); + InsertFieldData(db); + bool allowNotFound = false; + GetFieldData(db, allowNotFound); + findKeysByCityIndex(db, true); + findKeysByAgeIndex(db, true); + + delete db; + db = new FieldDB(); + if(OpenDB("testdb3.1", &db).ok() == false) { + std::cerr << "open db failed" << std::endl; + abort(); + } + //仍然能读到之前写入的数据和索引 + GetFieldData(db, allowNotFound); + findKeysByCityIndex(db, true); + findKeysByAgeIndex(db, true); +} + +// TEST(TestParalPutRecover, Recover) { +// signal(SIGSEGV, signalHandler); +// fielddb::DestroyDB("testdb3.2",Options()); +// FieldDB *db = new FieldDB(); + +// if(OpenDB("testdb3.2", &db).ok() == false) { +// std::cerr << "open db failed" << std::endl; +// abort(); +// } +// db->CreateIndexOnField("address"); +// db->CreateIndexOnField("age"); +// shanghaiKeys.clear(); +// age20Keys.clear(); +// int thread_num_ = 2; +// std::vector threads(thread_num_); +// threads[0] = std::thread([db](){ +// InsertFieldData(db); +// }); +// threads[1] = std::thread([db](){ +// InsertOneField(db); +// delete db; +// }); + + +// if (threads[1].joinable()) { +// threads[1].join(); +// } + +// db = new FieldDB(); +// if(OpenDB("testdb3.2", &db).ok() == false) { +// std::cerr << "open db failed" << std::endl; +// abort(); +// } +// GetOneField(db); +// checkDataInKVAndIndex(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(); +} \ No newline at end of file