1+ #include < memory>
2+ #include < set>
3+ #include < string>
4+ #include < vector>
5+ #include < iostream>
6+
7+ #include " rocksdb/db_crashtest_use_case.h"
8+ #include " rocksdb/options.h"
9+ #include " rocksdb/use_case.h"
10+ #include " rocksdb/utilities/customizable_util.h"
11+ #include " rocksdb/utilities/options_type.h"
12+
13+ namespace ROCKSDB_NAMESPACE {
14+ Status ToUseCases (const ConfigOptions& cfg_opts, const std::string& value,
15+ std::vector<std::shared_ptr<UseCase>>& use_cases) {
16+ Status status;
17+ for (size_t start = 0 , end = 0 ;
18+ status.ok () && start < value.size () && end != std::string::npos;
19+ start = end + 1 ) {
20+ std::string token;
21+ status = OptionTypeInfo::NextToken (value, ' ,' , start, &end, &token);
22+ if (status.ok ()) {
23+ if (token.find (' *' ) == std::string::npos) {
24+ std::shared_ptr<UseCase> use_case;
25+ status = UseCase::CreateFromString (cfg_opts, token, &use_case);
26+ if (status.ok () && use_case) {
27+ use_cases.push_back (use_case);
28+ }
29+ } else {
30+ // TODO: Pattern match on the factory names in factories to match the
31+ // token
32+ // std::vector<std::string> factories;
33+ // ObjectRegistry::Default()->GetFactoryNames(UseCase::Type(), &factories);
34+ // return bad status (some sort)
35+ }
36+ }
37+ }
38+ return status;
39+ }
40+
41+ static int RegisterBuiltinDBCrashtestUseCases (ObjectLibrary& library,
42+ const std::string& arg) {
43+ library.AddFactory <UseCase>(
44+ SimpleDefaultParams::kClassName (),
45+ [](const std::string& /* uri*/ ,
46+ std::unique_ptr<UseCase>* guard,
47+ std::string* /* errmsg*/ ) {
48+ guard->reset (new SimpleDefaultParams ());
49+ return guard->get ();
50+ });
51+ library.AddFactory <UseCase>(
52+ TxnParams::kClassName (),
53+ [](const std::string& /* uri*/ ,
54+ std::unique_ptr<UseCase>* guard,
55+ std::string* /* errmsg*/ ) {
56+ guard->reset (new TxnParams ());
57+ return guard->get ();
58+ });
59+ library.AddFactory <UseCase>(
60+ BestEffortsRecoveryParams::kClassName (),
61+ [](const std::string& /* uri*/ ,
62+ std::unique_ptr<UseCase>* guard,
63+ std::string* /* errmsg*/ ) {
64+ guard->reset (new BestEffortsRecoveryParams ());
65+ return guard->get ();
66+ });
67+ library.AddFactory <UseCase>(
68+ BlobParams::kClassName (),
69+ [](const std::string& /* uri*/ ,
70+ std::unique_ptr<UseCase>* guard,
71+ std::string* /* errmsg*/ ) {
72+ guard->reset (new BlobParams ());
73+ return guard->get ();
74+ });
75+ library.AddFactory <UseCase>(
76+ TieredParams::kClassName (),
77+ [](const std::string& /* uri*/ ,
78+ std::unique_ptr<UseCase>* guard,
79+ std::string* /* errmsg*/ ) {
80+ guard->reset (new TieredParams ());
81+ return guard->get ();
82+ });
83+ library.AddFactory <DBCrashtestUseCase>(
84+ MultiopsTxnDefaultParams::kClassName (),
85+ [](const std::string& /* uri*/ ,
86+ std::unique_ptr<DBCrashtestUseCase>* guard,
87+ std::string* /* errmsg*/ ) {
88+ guard->reset (new MultiopsTxnDefaultParams ());
89+ return guard->get ();
90+ });
91+ return 1 ;
92+ }
93+
94+ static int RegisterBuiltinUseCases (ObjectLibrary& library,
95+ const std::string& arg) {
96+ library.AddFactory <UseCase>(
97+ DBCrashtestUseCase::kClassName (),
98+ [](const std::string& /* uri*/ ,
99+ std::unique_ptr<UseCase>* guard,
100+ std::string* /* errmsg*/ ) {
101+ guard->reset (new DBCrashtestUseCase ());
102+ return guard->get ();
103+ });
104+ RegisterBuiltinDBCrashtestUseCases (library, arg);
105+ return 1 ;
106+ }
107+
108+ Status UseCase::CreateFromString (const ConfigOptions& cfg_opts,
109+ const std::string& value,
110+ std::shared_ptr<UseCase>* result) {
111+ static std::once_flag once;
112+ std::call_once (once, [&]() {
113+ RegisterBuiltinUseCases (*(ObjectLibrary::Default ().get ()), " " );
114+ });
115+ Status status =
116+ LoadSharedObject<UseCase>(cfg_opts, value, result);
117+ return status;
118+ }
119+
120+ Status UseCase::ValidateOptions (const ConfigOptions& cfg_opts,
121+ const std::string& validate_against,
122+ const DBOptions& db_opts,
123+ std::set<std::string>& valid_opts,
124+ std::set<std::string>& invalid_opts) {
125+ std::vector<std::shared_ptr<UseCase>> use_cases;
126+ Status s = ToUseCases (cfg_opts, validate_against, use_cases);
127+ if (s.ok ()) {
128+ for (const auto & use_case : use_cases) {
129+ use_case->Validate (cfg_opts, db_opts, valid_opts, invalid_opts);
130+ }
131+ if (!invalid_opts.empty ()) {
132+ s = Status::InvalidArgument ();
133+ }
134+ }
135+ return s;
136+ }
137+
138+ Status UseCase::ValidateOptions (const ConfigOptions& cfg_opts,
139+ const std::string& validate_against,
140+ const ColumnFamilyOptions& cf_opts,
141+ std::set<std::string>& valid_opts,
142+ std::set<std::string>& invalid_opts) {
143+ std::vector<std::shared_ptr<UseCase>> use_cases;
144+ Status s = ToUseCases (cfg_opts, validate_against, use_cases);
145+ if (s.ok ()) {
146+ for (const auto & use_case : use_cases) {
147+ use_case->Validate (cfg_opts, cf_opts, valid_opts, invalid_opts);
148+ }
149+ if (!invalid_opts.empty ()) {
150+ s = Status::InvalidArgument ();
151+ }
152+ }
153+ return s;
154+ }
155+
156+ Status UseCase::ValidateOptions (const ConfigOptions& cfg_opts,
157+ const std::string& validate_against,
158+ const Options& opts,
159+ std::set<std::string>& valid_opts,
160+ std::set<std::string>& invalid_opts) {
161+ const DBOptions* db_opts = &opts;
162+ const ColumnFamilyOptions* cf_opts = &opts;
163+ Status s = ValidateOptions (cfg_opts, validate_against, *db_opts, valid_opts, invalid_opts);
164+ if (s.ok ()) {
165+ s = ValidateOptions (cfg_opts, validate_against, *cf_opts, valid_opts, invalid_opts);
166+ }
167+ return s;
168+ }
169+ } // namespace ROCKSDB_NAMESPACE
0 commit comments