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