Skip to content

Commit 41363d6

Browse files
committed
options: Add generic validation implementation for use cases
A UseCase class is a Configurable class which represents a specific use case in rocksdb/speedb which we can use to populate options according to the specification of that use case, and/or validate the user's options against the expected possible configurations which fit that use case. As such, we add here 2 methods in Configurable which essentially take a UseCase and a set of options, and validates that the values of these options matches the values that the use case requires.
1 parent 86a315d commit 41363d6

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

options/configurable.cc

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,4 +709,67 @@ Status Configurable::GetOptionsMap(
709709
}
710710
return status;
711711
}
712+
713+
int ConfigurableHelper::CheckSomeUseCases(
714+
const ConfigOptions& config_options, const Configurable& configurable,
715+
const std::unordered_map<std::string, OptionTypeInfo>& type_map,
716+
const void* opt_ptr,
717+
std::vector<std::pair<std::string, UseCaseConfig>>& uses,
718+
std::set<std::string>& valid, std::set<std::string>& invalid) {
719+
int found = 1;
720+
std::string elem_name;
721+
while (found > 0 && !uses.empty()) {
722+
found = 0;
723+
for (size_t idx = 0; idx < uses.size();) {
724+
const auto& it = uses[idx];
725+
const std::string& opt_name = configurable.GetOptionName(it.first);
726+
const auto opt_info =
727+
OptionTypeInfo::Find(opt_name, type_map, &elem_name);
728+
if (opt_info == nullptr) { // Did not find the option. Skip it
729+
++idx;
730+
} else {
731+
const void* addr = opt_info->GetOffset(opt_ptr);
732+
if (it.second.IsValid(addr)) {
733+
printf("MJR: Option[%s] is valid\n", opt_name.c_str());
734+
valid.insert(it.first);
735+
} else {
736+
printf("MJR: Option[%s] is invalid\n", opt_name.c_str());
737+
invalid.insert(it.first);
738+
}
739+
// Remove it from the list. Swap it with the last one
740+
// and remove the last one
741+
uses[idx] = uses.back();
742+
uses.pop_back();
743+
found++;
744+
}
745+
}
746+
}
747+
return static_cast<int>(invalid.size());
748+
}
749+
750+
bool ConfigurableHelper::CheckUseCases(
751+
const ConfigOptions& config_options, const Configurable& configurable,
752+
const std::vector<std::unordered_map<std::string, UseCaseConfig>*>& uses,
753+
std::set<std::string>& valid, std::set<std::string>& invalid,
754+
std::unordered_map<std::string, UseCaseConfig>* unused) {
755+
std::vector<std::pair<std::string, UseCaseConfig>> remaining;
756+
if (!uses.empty()) {
757+
for (const auto& uc_map : uses) {
758+
remaining.assign(uc_map->begin(), uc_map->end());
759+
}
760+
for (const auto& iter : configurable.options_) {
761+
if (iter.type_map != nullptr) {
762+
CheckSomeUseCases(config_options, configurable, *(iter.type_map),
763+
iter.opt_ptr, remaining, valid, invalid);
764+
if (remaining.empty()) { // Are there more options left?
765+
break;
766+
}
767+
}
768+
}
769+
}
770+
if (unused != nullptr && !remaining.empty()) {
771+
unused->insert(remaining.begin(), remaining.end());
772+
}
773+
return static_cast<int>(invalid.size());
774+
}
712775
} // namespace ROCKSDB_NAMESPACE

options/configurable_helper.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@
66
#pragma once
77

88
#include <map>
9+
#include <set>
910
#include <stdexcept>
1011
#include <string>
1112
#include <vector>
1213

1314
#include "rocksdb/configurable.h"
1415
#include "rocksdb/convenience.h"
16+
#include "rocksdb/use_case.h"
1517

1618
namespace ROCKSDB_NAMESPACE {
19+
class UseCaseConfig;
1720
// Helper class defining static methods for supporting the Configurable
1821
// class. The purpose of this class is to keep the Configurable class
1922
// as tight as possible and provide methods for doing the actual work
@@ -159,6 +162,19 @@ class ConfigurableHelper {
159162
const Configurable& that_one,
160163
std::string* mismatch);
161164

165+
static bool CheckUseCases(
166+
const ConfigOptions& config_options, const Configurable& configurable,
167+
const std::vector<std::unordered_map<std::string, UseCaseConfig>*>& uses,
168+
std::set<std::string>& valid, std::set<std::string>& invalid,
169+
std::unordered_map<std::string, UseCaseConfig>* unused);
170+
171+
static int CheckSomeUseCases(
172+
const ConfigOptions& config_options, const Configurable& configurable,
173+
const std::unordered_map<std::string, OptionTypeInfo>& type_map,
174+
const void* opt_ptr,
175+
std::vector<std::pair<std::string, UseCaseConfig>>& uses,
176+
std::set<std::string>& valid, std::set<std::string>& invalid);
177+
162178
private:
163179
// Looks for the option specified by name in the RegisteredOptions.
164180
// This method traverses the types in the input options vector. If an entry

0 commit comments

Comments
 (0)