| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
- // This source code is licensed under both the GPLv2 (found in the
- // COPYING file in the root directory) and Apache 2.0 License
- // (found in the LICENSE.Apache file in the root directory).
- //
- #ifndef ROCKSDB_LITE
- #include "db/db_impl/db_impl.h"
- #include "db/version_set.h"
- #include "rocksdb/db.h"
- #include "rocksdb/utilities/ldb_cmd.h"
- #include "test_util/testharness.h"
- #include "test_util/testutil.h"
- #include "tools/ldb_cmd_impl.h"
- #include "util/string_util.h"
- namespace ROCKSDB_NAMESPACE {
- class ReduceLevelTest : public testing::Test {
- public:
- ReduceLevelTest() {
- dbname_ = test::PerThreadDBPath("db_reduce_levels_test");
- DestroyDB(dbname_, Options());
- db_ = nullptr;
- }
- Status OpenDB(bool create_if_missing, int levels);
- Status Put(const std::string& k, const std::string& v) {
- return db_->Put(WriteOptions(), k, v);
- }
- std::string Get(const std::string& k) {
- ReadOptions options;
- std::string result;
- Status s = db_->Get(options, k, &result);
- if (s.IsNotFound()) {
- result = "NOT_FOUND";
- } else if (!s.ok()) {
- result = s.ToString();
- }
- return result;
- }
- Status Flush() {
- if (db_ == nullptr) {
- return Status::InvalidArgument("DB not opened.");
- }
- DBImpl* db_impl = reinterpret_cast<DBImpl*>(db_);
- return db_impl->TEST_FlushMemTable();
- }
- void MoveL0FileToLevel(int level) {
- DBImpl* db_impl = reinterpret_cast<DBImpl*>(db_);
- for (int i = 0; i < level; ++i) {
- ASSERT_OK(db_impl->TEST_CompactRange(i, nullptr, nullptr));
- }
- }
- void CloseDB() {
- if (db_ != nullptr) {
- delete db_;
- db_ = nullptr;
- }
- }
- bool ReduceLevels(int target_level);
- int FilesOnLevel(int level) {
- std::string property;
- EXPECT_TRUE(db_->GetProperty(
- "rocksdb.num-files-at-level" + NumberToString(level), &property));
- return atoi(property.c_str());
- }
- private:
- std::string dbname_;
- DB* db_;
- };
- Status ReduceLevelTest::OpenDB(bool create_if_missing, int num_levels) {
- ROCKSDB_NAMESPACE::Options opt;
- opt.num_levels = num_levels;
- opt.create_if_missing = create_if_missing;
- ROCKSDB_NAMESPACE::Status st =
- ROCKSDB_NAMESPACE::DB::Open(opt, dbname_, &db_);
- if (!st.ok()) {
- fprintf(stderr, "Can't open the db:%s\n", st.ToString().c_str());
- }
- return st;
- }
- bool ReduceLevelTest::ReduceLevels(int target_level) {
- std::vector<std::string> args =
- ROCKSDB_NAMESPACE::ReduceDBLevelsCommand::PrepareArgs(
- dbname_, target_level, false);
- LDBCommand* level_reducer = LDBCommand::InitFromCmdLineArgs(
- args, Options(), LDBOptions(), nullptr, LDBCommand::SelectCommand);
- level_reducer->Run();
- bool is_succeed = level_reducer->GetExecuteState().IsSucceed();
- delete level_reducer;
- return is_succeed;
- }
- TEST_F(ReduceLevelTest, Last_Level) {
- ASSERT_OK(OpenDB(true, 4));
- ASSERT_OK(Put("aaaa", "11111"));
- Flush();
- MoveL0FileToLevel(3);
- ASSERT_EQ(FilesOnLevel(3), 1);
- CloseDB();
- ASSERT_TRUE(ReduceLevels(3));
- ASSERT_OK(OpenDB(true, 3));
- ASSERT_EQ(FilesOnLevel(2), 1);
- CloseDB();
- ASSERT_TRUE(ReduceLevels(2));
- ASSERT_OK(OpenDB(true, 2));
- ASSERT_EQ(FilesOnLevel(1), 1);
- CloseDB();
- }
- TEST_F(ReduceLevelTest, Top_Level) {
- ASSERT_OK(OpenDB(true, 5));
- ASSERT_OK(Put("aaaa", "11111"));
- Flush();
- ASSERT_EQ(FilesOnLevel(0), 1);
- CloseDB();
- ASSERT_TRUE(ReduceLevels(4));
- ASSERT_OK(OpenDB(true, 4));
- CloseDB();
- ASSERT_TRUE(ReduceLevels(3));
- ASSERT_OK(OpenDB(true, 3));
- CloseDB();
- ASSERT_TRUE(ReduceLevels(2));
- ASSERT_OK(OpenDB(true, 2));
- CloseDB();
- }
- TEST_F(ReduceLevelTest, All_Levels) {
- ASSERT_OK(OpenDB(true, 5));
- ASSERT_OK(Put("a", "a11111"));
- ASSERT_OK(Flush());
- MoveL0FileToLevel(4);
- ASSERT_EQ(FilesOnLevel(4), 1);
- CloseDB();
- ASSERT_OK(OpenDB(true, 5));
- ASSERT_OK(Put("b", "b11111"));
- ASSERT_OK(Flush());
- MoveL0FileToLevel(3);
- ASSERT_EQ(FilesOnLevel(3), 1);
- ASSERT_EQ(FilesOnLevel(4), 1);
- CloseDB();
- ASSERT_OK(OpenDB(true, 5));
- ASSERT_OK(Put("c", "c11111"));
- ASSERT_OK(Flush());
- MoveL0FileToLevel(2);
- ASSERT_EQ(FilesOnLevel(2), 1);
- ASSERT_EQ(FilesOnLevel(3), 1);
- ASSERT_EQ(FilesOnLevel(4), 1);
- CloseDB();
- ASSERT_OK(OpenDB(true, 5));
- ASSERT_OK(Put("d", "d11111"));
- ASSERT_OK(Flush());
- MoveL0FileToLevel(1);
- ASSERT_EQ(FilesOnLevel(1), 1);
- ASSERT_EQ(FilesOnLevel(2), 1);
- ASSERT_EQ(FilesOnLevel(3), 1);
- ASSERT_EQ(FilesOnLevel(4), 1);
- CloseDB();
- ASSERT_TRUE(ReduceLevels(4));
- ASSERT_OK(OpenDB(true, 4));
- ASSERT_EQ("a11111", Get("a"));
- ASSERT_EQ("b11111", Get("b"));
- ASSERT_EQ("c11111", Get("c"));
- ASSERT_EQ("d11111", Get("d"));
- CloseDB();
- ASSERT_TRUE(ReduceLevels(3));
- ASSERT_OK(OpenDB(true, 3));
- ASSERT_EQ("a11111", Get("a"));
- ASSERT_EQ("b11111", Get("b"));
- ASSERT_EQ("c11111", Get("c"));
- ASSERT_EQ("d11111", Get("d"));
- CloseDB();
- ASSERT_TRUE(ReduceLevels(2));
- ASSERT_OK(OpenDB(true, 2));
- ASSERT_EQ("a11111", Get("a"));
- ASSERT_EQ("b11111", Get("b"));
- ASSERT_EQ("c11111", Get("c"));
- ASSERT_EQ("d11111", Get("d"));
- CloseDB();
- }
- } // namespace ROCKSDB_NAMESPACE
- int main(int argc, char** argv) {
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
- }
- #else
- #include <stdio.h>
- int main(int /*argc*/, char** /*argv*/) {
- fprintf(stderr, "SKIPPED as LDBCommand is not supported in ROCKSDB_LITE\n");
- return 0;
- }
- #endif // !ROCKSDB_LITE
|