1 // Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 //
6 // This file demonstrates how to use the utility functions defined in
7 // rocksdb/utilities/options_util.h to open a rocksdb database without
8 // remembering all the rocksdb options.
9 #include <cstdio>
10 #include <string>
11 #include <vector>
12 
13 #include "rocksdb/cache.h"
14 #include "rocksdb/compaction_filter.h"
15 #include "rocksdb/db.h"
16 #include "rocksdb/options.h"
17 #include "rocksdb/slice.h"
18 #include "rocksdb/table.h"
19 #include "rocksdb/utilities/options_util.h"
20 
21 using namespace ROCKSDB_NAMESPACE;
22 
23 std::string kDBPath = "/tmp/rocksdb_options_file_example";
24 
25 namespace {
26 // A dummy compaction filter
27 class DummyCompactionFilter : public CompactionFilter {
28  public:
~DummyCompactionFilter()29   virtual ~DummyCompactionFilter() {}
Filter(int level,const Slice & key,const Slice & existing_value,std::string * new_value,bool * value_changed) const30   virtual bool Filter(int level, const Slice& key, const Slice& existing_value,
31                       std::string* new_value, bool* value_changed) const {
32     return false;
33   }
Name() const34   virtual const char* Name() const { return "DummyCompactionFilter"; }
35 };
36 
37 }  // namespace
38 
main()39 int main() {
40   DBOptions db_opt;
41   db_opt.create_if_missing = true;
42 
43   std::vector<ColumnFamilyDescriptor> cf_descs;
44   cf_descs.push_back({kDefaultColumnFamilyName, ColumnFamilyOptions()});
45   cf_descs.push_back({"new_cf", ColumnFamilyOptions()});
46 
47   // initialize BlockBasedTableOptions
48   auto cache = NewLRUCache(1 * 1024 * 1024 * 1024);
49   BlockBasedTableOptions bbt_opts;
50   bbt_opts.block_size = 32 * 1024;
51   bbt_opts.block_cache = cache;
52 
53   // initialize column families options
54   std::unique_ptr<CompactionFilter> compaction_filter;
55   compaction_filter.reset(new DummyCompactionFilter());
56   cf_descs[0].options.table_factory.reset(NewBlockBasedTableFactory(bbt_opts));
57   cf_descs[0].options.compaction_filter = compaction_filter.get();
58   cf_descs[1].options.table_factory.reset(NewBlockBasedTableFactory(bbt_opts));
59 
60   // destroy and open DB
61   DB* db;
62   Status s = DestroyDB(kDBPath, Options(db_opt, cf_descs[0].options));
63   assert(s.ok());
64   s = DB::Open(Options(db_opt, cf_descs[0].options), kDBPath, &db);
65   assert(s.ok());
66 
67   // Create column family, and rocksdb will persist the options.
68   ColumnFamilyHandle* cf;
69   s = db->CreateColumnFamily(ColumnFamilyOptions(), "new_cf", &cf);
70   assert(s.ok());
71 
72   // close DB
73   delete cf;
74   delete db;
75 
76   // In the following code, we will reopen the rocksdb instance using
77   // the options file stored in the db directory.
78 
79   // Load the options file.
80   DBOptions loaded_db_opt;
81   std::vector<ColumnFamilyDescriptor> loaded_cf_descs;
82   s = LoadLatestOptions(kDBPath, Env::Default(), &loaded_db_opt,
83                         &loaded_cf_descs);
84   assert(s.ok());
85   assert(loaded_db_opt.create_if_missing == db_opt.create_if_missing);
86 
87   // Initialize pointer options for each column family
88   for (size_t i = 0; i < loaded_cf_descs.size(); ++i) {
89     auto* loaded_bbt_opt = reinterpret_cast<BlockBasedTableOptions*>(
90         loaded_cf_descs[0].options.table_factory->GetOptions());
91     // Expect the same as BlockBasedTableOptions will be loaded form file.
92     assert(loaded_bbt_opt->block_size == bbt_opts.block_size);
93     // However, block_cache needs to be manually initialized as documented
94     // in rocksdb/utilities/options_util.h.
95     loaded_bbt_opt->block_cache = cache;
96   }
97   // In addition, as pointer options are initialized with default value,
98   // we need to properly initialized all the pointer options if non-defalut
99   // values are used before calling DB::Open().
100   assert(loaded_cf_descs[0].options.compaction_filter == nullptr);
101   loaded_cf_descs[0].options.compaction_filter = compaction_filter.get();
102 
103   // reopen the db using the loaded options.
104   std::vector<ColumnFamilyHandle*> handles;
105   s = DB::Open(loaded_db_opt, kDBPath, loaded_cf_descs, &handles, &db);
106   assert(s.ok());
107 
108   // close DB
109   for (auto* handle : handles) {
110     delete handle;
111   }
112   delete db;
113 }
114