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 #pragma once
7 
8 #include <map>
9 #include <string>
10 #include <vector>
11 
12 #include "rocksdb/env.h"
13 #include "rocksdb/options.h"
14 
15 namespace ROCKSDB_NAMESPACE {
16 
17 #ifndef ROCKSDB_LITE
18 struct ConfigOptions;
19 class OptionTypeInfo;
20 class TableFactory;
21 
22 #define ROCKSDB_OPTION_FILE_MAJOR 1
23 #define ROCKSDB_OPTION_FILE_MINOR 1
24 
25 enum OptionSection : char {
26   kOptionSectionVersion = 0,
27   kOptionSectionDBOptions,
28   kOptionSectionCFOptions,
29   kOptionSectionTableOptions,
30   kOptionSectionUnknown
31 };
32 
33 static const std::string opt_section_titles[] = {
34     "Version", "DBOptions", "CFOptions", "TableOptions/", "Unknown"};
35 
36 Status PersistRocksDBOptions(const DBOptions& db_opt,
37                              const std::vector<std::string>& cf_names,
38                              const std::vector<ColumnFamilyOptions>& cf_opts,
39                              const std::string& file_name, FileSystem* fs);
40 Status PersistRocksDBOptions(const ConfigOptions& config_options,
41                              const DBOptions& db_opt,
42                              const std::vector<std::string>& cf_names,
43                              const std::vector<ColumnFamilyOptions>& cf_opts,
44                              const std::string& file_name, FileSystem* fs);
45 
46 class RocksDBOptionsParser {
47  public:
48   explicit RocksDBOptionsParser();
~RocksDBOptionsParser()49   ~RocksDBOptionsParser() {}
50   void Reset();
51 
52   // `file_readahead_size` is used for readahead for the option file.
53   // If 0 is given, a default value will be used.
54   Status Parse(const std::string& file_name, FileSystem* fs,
55                bool ignore_unknown_options, size_t file_readahead_size);
56 
57   Status Parse(const ConfigOptions& config_options,
58                const std::string& file_name, FileSystem* fs);
59 
60   static std::string TrimAndRemoveComment(const std::string& line,
61                                           const bool trim_only = false);
62 
db_opt()63   const DBOptions* db_opt() const { return &db_opt_; }
db_opt_map()64   const std::unordered_map<std::string, std::string>* db_opt_map() const {
65     return &db_opt_map_;
66   }
cf_opts()67   const std::vector<ColumnFamilyOptions>* cf_opts() const { return &cf_opts_; }
cf_names()68   const std::vector<std::string>* cf_names() const { return &cf_names_; }
cf_opt_maps()69   const std::vector<std::unordered_map<std::string, std::string>>* cf_opt_maps()
70       const {
71     return &cf_opt_maps_;
72   }
73 
GetCFOptions(const std::string & name)74   const ColumnFamilyOptions* GetCFOptions(const std::string& name) {
75     return GetCFOptionsImpl(name);
76   }
NumColumnFamilies()77   size_t NumColumnFamilies() { return cf_opts_.size(); }
78   static Status VerifyRocksDBOptionsFromFile(
79       const ConfigOptions& config_options, const DBOptions& db_opt,
80       const std::vector<std::string>& cf_names,
81       const std::vector<ColumnFamilyOptions>& cf_opts,
82       const std::string& file_name, FileSystem* fs);
83   static Status VerifyDBOptions(
84       const ConfigOptions& config_options, const DBOptions& base_opt,
85       const DBOptions& new_opt,
86       const std::unordered_map<std::string, std::string>* new_opt_map =
87           nullptr);
88 
89   static Status VerifyCFOptions(
90       const ConfigOptions& config_options, const ColumnFamilyOptions& base_opt,
91       const ColumnFamilyOptions& new_opt,
92       const std::unordered_map<std::string, std::string>* new_opt_map =
93           nullptr);
94 
95   static Status VerifyTableFactory(const ConfigOptions& config_options,
96                                    const TableFactory* base_tf,
97                                    const TableFactory* file_tf);
98 
99   static Status ExtraParserCheck(const RocksDBOptionsParser& input_parser);
100 
101   static Status ParseStatement(std::string* name, std::string* value,
102                                const std::string& line, const int line_num);
103 
104  protected:
105   bool IsSection(const std::string& line);
106   Status ParseSection(OptionSection* section, std::string* title,
107                       std::string* argument, const std::string& line,
108                       const int line_num);
109 
110   Status CheckSection(const OptionSection section,
111                       const std::string& section_arg, const int line_num);
112 
113   Status EndSection(
114       const ConfigOptions& config_options, const OptionSection section,
115       const std::string& title, const std::string& section_arg,
116       const std::unordered_map<std::string, std::string>& opt_map);
117 
118   Status ValidityCheck();
119 
120   static Status InvalidArgument(const int line_num, const std::string& message);
121 
122   Status ParseVersionNumber(const std::string& ver_name,
123                             const std::string& ver_string, const int max_count,
124                             int* version);
125 
GetCFOptionsImpl(const std::string & name)126   ColumnFamilyOptions* GetCFOptionsImpl(const std::string& name) {
127     assert(cf_names_.size() == cf_opts_.size());
128     for (size_t i = 0; i < cf_names_.size(); ++i) {
129       if (cf_names_[i] == name) {
130         return &cf_opts_[i];
131       }
132     }
133     return nullptr;
134   }
135 
136  private:
137   DBOptions db_opt_;
138   std::unordered_map<std::string, std::string> db_opt_map_;
139   std::vector<std::string> cf_names_;
140   std::vector<ColumnFamilyOptions> cf_opts_;
141   std::vector<std::unordered_map<std::string, std::string>> cf_opt_maps_;
142   bool has_version_section_;
143   bool has_db_options_;
144   bool has_default_cf_options_;
145   int db_version[3];
146   int opt_file_version[3];
147 };
148 
149 #endif  // !ROCKSDB_LITE
150 
151 }  // namespace ROCKSDB_NAMESPACE
152