#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 */, int vsize = 0) { WriteOptions writeOptions; int key_num = data_size / value_size; 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 + vsize, 'a'); db->Put(writeOptions, std::to_string(i+1), value, ttl); // db->Put(writeOptions, key, value, ttl); } } void GetData(DB *db, int size = (1 << 30)) { ReadOptions readOptions; int key_num = data_size / value_size; // 点查 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(TestTTL,ReadWithoutTTL) { DestroyDB("testdb",Options()); DB *db; if(OpenDB("testdb", &db).ok() == false) { std::cerr << "open db failed" << std::endl; abort(); } uint64_t ttl1 = 15; uint64_t ttl2 = 0; uint64_t extra_size = 1; InsertData(db, ttl2); // sleep(1); InsertData(db, ttl1, extra_size); //后一个数据长度变化一下 //都没过期先找到后插的 Env::Default()->SleepForMicroseconds(1 * 1000000); int key_num = data_size / value_size; ReadOptions readOptions; Status status; 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; status = db->Get(readOptions, key, &value); ASSERT_TRUE(status.ok()); ASSERT_EQ(value.size(), value_size + extra_size); } //再找到前一次 Env::Default()->SleepForMicroseconds(ttl1 * 1000000); // db->CompactRange(nullptr,nullptr); 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_TRUE(status.ok()); ASSERT_EQ(value.size(), value_size); } delete db; } TEST(TestTTL, ReadTTL) { DestroyDB("testdb",Options()); DB *db; if(OpenDB("testdb", &db).ok() == false) { std::cerr << "open db failed" << std::endl; abort(); } uint64_t ttl = 15; InsertData(db, ttl); ReadOptions readOptions; Status status; int key_num = data_size / value_size; 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; status = db->Get(readOptions, key, &value); std::cout<SleepForMicroseconds((ttl+1) * 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); std::cout<SleepForMicroseconds(1 * 1000000); int key_num = data_size / value_size; ReadOptions readOptions; Status status; 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; status = db->Get(readOptions, key, &value); ASSERT_TRUE(status.ok()); ASSERT_EQ(value.size(), value_size + extra_size); } //再找到前一次 Env::Default()->SleepForMicroseconds(ttl1 * 1000000); // db->CompactRange(nullptr,nullptr); 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_TRUE(status.ok()); ASSERT_EQ(value.size(), value_size); } delete db; } TEST(TestTTL, CompactionTTL) { DestroyDB("testdb",Options()); DB *db; if(OpenDB("testdb", &db).ok() == false) { std::cerr << "open db failed" << std::endl; abort(); } uint64_t ttl = 10; InsertData(db, ttl); leveldb::Range ranges[1]; ranges[0] = leveldb::Range("-", "A"); uint64_t sizes[1]; db->GetApproximateSizes(ranges, 1, sizes); ASSERT_GT(sizes[0], 0); Env::Default()->SleepForMicroseconds((ttl+1) * 1000000); // 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); 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(); }