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 #if defined(OS_WIN)
24 std::string kDBPath = "C:\\Windows\\TEMP\\rocksdb_options_file_example";
25 #else
26 std::string kDBPath = "/tmp/rocksdb_options_file_example";
27 #endif
28 
29 namespace {
30 // A dummy compaction filter
31 class DummyCompactionFilter : public CompactionFilter {
32  public:
~DummyCompactionFilter()33   virtual ~DummyCompactionFilter() {}
Filter(int level,const Slice & key,const Slice & existing_value,std::string * new_value,bool * value_changed) const34   virtual bool Filter(int level, const Slice& key, const Slice& existing_value,
35                       std::string* new_value, bool* value_changed) const {
36     return false;
37   }
Name() const38   virtual const char* Name() const { return "DummyCompactionFilter"; }
39 };
40 
41 }  // namespace
42 
main()43 int main() {
44   DBOptions db_opt;
45   db_opt.create_if_missing = true;
46 
47   std::vector<ColumnFamilyDescriptor> cf_descs;
48   cf_descs.push_back({kDefaultColumnFamilyName, ColumnFamilyOptions()});
49   cf_descs.push_back({"new_cf", ColumnFamilyOptions()});
50 
51   // initialize BlockBasedTableOptions
52   auto cache = NewLRUCache(1 * 1024 * 1024 * 1024);
53   BlockBasedTableOptions bbt_opts;
54   bbt_opts.block_size = 32 * 1024;
55   bbt_opts.block_cache = cache;
56 
57   // initialize column families options
58   std::unique_ptr<CompactionFilter> compaction_filter;
59   compaction_filter.reset(new DummyCompactionFilter());
60   cf_descs[0].options.table_factory.reset(NewBlockBasedTableFactory(bbt_opts));
61   cf_descs[0].options.compaction_filter = compaction_filter.get();
62   cf_descs[1].options.table_factory.reset(NewBlockBasedTableFactory(bbt_opts));
63 
64   // destroy and open DB
65   DB* db;
66   Status s = DestroyDB(kDBPath, Options(db_opt, cf_descs[0].options));
67   assert(s.ok());
68   s = DB::Open(Options(db_opt, cf_descs[0].options), kDBPath, &db);
69   assert(s.ok());
70 
71   // Create column family, and rocksdb will persist the options.
72   ColumnFamilyHandle* cf;
73   s = db->CreateColumnFamily(ColumnFamilyOptions(), "new_cf", &cf);
74   assert(s.ok());
75 
76   // close DB
77   delete cf;
78   delete db;
79 
80   // In the following code, we will reopen the rocksdb instance using
81   // the options file stored in the db directory.
82 
83   // Load the options file.
84   DBOptions loaded_db_opt;
85   std::vector<ColumnFamilyDescriptor> loaded_cf_descs;
86   ConfigOptions config_options;
87   s = LoadLatestOptions(config_options, kDBPath, &loaded_db_opt,
88                         &loaded_cf_descs);
89   assert(s.ok());
90   assert(loaded_db_opt.create_if_missing == db_opt.create_if_missing);
91 
92   // Initialize pointer options for each column family
93   for (size_t i = 0; i < loaded_cf_descs.size(); ++i) {
94     auto* loaded_bbt_opt =
95         loaded_cf_descs[0]
96             .options.table_factory->GetOptions<BlockBasedTableOptions>();
97     // Expect the same as BlockBasedTableOptions will be loaded form file.
98     assert(loaded_bbt_opt->block_size == bbt_opts.block_size);
99     // However, block_cache needs to be manually initialized as documented
100     // in rocksdb/utilities/options_util.h.
101     loaded_bbt_opt->block_cache = cache;
102   }
103   // In addition, as pointer options are initialized with default value,
104   // we need to properly initialized all the pointer options if non-defalut
105   // values are used before calling DB::Open().
106   assert(loaded_cf_descs[0].options.compaction_filter == nullptr);
107   loaded_cf_descs[0].options.compaction_filter = compaction_filter.get();
108 
109   // reopen the db using the loaded options.
110   std::vector<ColumnFamilyHandle*> handles;
111   s = DB::Open(loaded_db_opt, kDBPath, loaded_cf_descs, &handles, &db);
112   assert(s.ok());
113 
114   // close DB
115   for (auto* handle : handles) {
116     delete handle;
117   }
118   delete db;
119 }
120