Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bring the Configurable options together #5753

Closed
wants to merge 28 commits into from

Conversation

mrambacher
Copy link
Contributor

This PR merges the functionality of making the ColumnFamilyOptions, TableFactory, and DBOptions into Configurable into a single PR, resolving any merge conflicts

@riversand963
Copy link
Contributor

Hi @mrambacher , starting to look at the configurable PRs. I noticed that #5753 seems to be a combination of #5362, #5497, #5752 and https://github.com/facebook/rocksdb/pull/5574/files
Should we be looking at just #5753 and close the others?

@mrambacher
Copy link
Contributor Author

#5574 is the base PR, which adds more functionality to the OptionTypeInfo class. #5361 (Configurable class) uses #5574 to implement a base configurable class.

#5362, #5497, and #5752 use the Configurable class to configure their respective pieces whereas #5753 merges those respective pieces into one chunk.

I would recommend reviewing #5574 then #5361. If you are comfortable with the classes, #5753 is what you really want and not the other three PRs (as they are subsumed eventually by this one anway).

@mrambacher
Copy link
Contributor Author

Just to clarify, those three PRs (#5574, #5361, and #5753) build on each other. You could start with just the last one and that would hit all of the functionality. They were broken up into the littler pieces in an attempt to make it easier to review, but it is your choice how you want to tackle them.

@riversand963
Copy link
Contributor

Thanks @mrambacher for the clarification. I will start with #5753. In case I need more context, I can use the preceding PRs as a reference to help understand.

@riversand963
Copy link
Contributor

I am looking at your PR, and there is one thing I am not following. In Configurable::SetOptions, we already know the option name, why can't we use the name to do a point lookup in options_? Currently we iterate over all entries options_ until we find a match in the option map associated with that entry. Could you point me to an example to show how this works? Thanks

@riversand963
Copy link
Contributor

riversand963 commented Sep 13, 2019

Chatted offline. Thanks @mrambacher for clarifying some aspects of his design.

With recursion put aside, each Configurable object has a two-level mapping. The first level maps named parts of the object to a corresponding memory address plus another map. This second map is the second layer mapping from named fields to metadata, e.g. OptionTypeInfo, of the field's type. An object has one entry in the options_ map (first level mapping) iff. RegisterOptionsMap(...) is called once. It is possible for an object to have more entries in options_ iff. RegisterOptionsMap(...) multiple times. This can happen in multiple cases. One case is object B has object A, but the user does not specify a unified option_type_map for B. Another case is that object B is a subclass of A with some extra configurable members, and the user does not specify a unified options_type_map for B.
I also notice that the mapping can be recursive, i.e. an entry in options_type_map can correspond to another configurable object, thus having its own levels of mappings.
Whether a programmer defines a single, unified options_type_map for a Configurable object, or multiple separate maps, is a choice up to the programmer.

input_strings_escaped);
} else {
status = ParseOption(opt_info, db_opts, opt_ptr,
name.substr(opt_iter->first.size() + 1), value,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If name is "test.simple.int", and opt_iter->first is "int", then name.substr(opt_iter->first.size() + 1) does not seem right.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think that can happen. If name is "test.simple.int", then opt_iter->first would either be "test.simple.int" (match completely) or "test" (matches to the first "."). This case is handling the latter, and would pass "simple.int" to the next layer to be matched.

Also note that any options prefix is stripped off before this point. So if the class had an option prefix of "test.simple" and the names passed in originally are "test.simple.int", test.simple.struct.double", and "test.bool", then the options processed here would be "int", "struct.double", and "test.bool" as the prefix would have already been removed.

Copy link
Contributor

@riversand963 riversand963 Sep 23, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to simple_options_info in configurable_test.cc, this can happen. Specifically in the example in configurable.cc, the opt_iter->first is "int", "bool", etc. and I believe the name can be "test.simple.int" or "test.simple.bool" if long form is used. @mrambacher

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the confusion now. Here is how it works and why I do not think it is an issue:

  • In ConfigureOption, the option name is turned into the short name by removing any option prefix. So "test.simple.int" becomes "int" if the class has "test.simple." as its prefix. This is meant to normalize all of the names.
  • In FindOption (called from SetOption), it looks for the option name ("int" in this example) in the map. It would find the exact match and process it.

The case you are pointing out is meant to handle Configurables that have nested Configurable objects in them (has-a relationship). In this case the OptionMap would have "nested" in it and the option name passed in might be "nested" (in which case we were configuring the entire nested object) or "nested.int" (in which case we would configure the "int" property inside of "nested". (Note that since ConfigureOption stripped off the prefix, this name could have been passed in as "test.simple.nested", but the code here only sees "nested".) . In this case, the FindOption needs to find "nested" even if the option name passed in is "nested.int" (and there is code in FindOption to do exactly that). So "FindOption" matches "nested.int" and "nested" to the same option in the map. If the option passed in is "nested.int", we need to pass to the embedded option that we are configuring "int" since it has no idea that it is "nested".

Note that I think it is also possible that the nested option has a prefix on it (prefix-1.nested.prefix-2.int), in which case the "prefix-1" would be stripped off at the first level, we would look for "nested" in the map and pass "prefix-2.int" to the nested ConfigureOption and the nested class would strip off prefix-2.

@riversand963 Does that clear it up? If you think it would be helpful, I can attempt to add comments to that affect, but the comments would be de-centralized as different places are doing different parts of the processing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is worthwhile documenting the configurable object naming you just described with examples. As you mentioned, different functions do different parts. Therefore, it may be a good idea to add a page to the Github wiki after this PR is merged.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zhichao-cao has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

C++ has no great way of guaranteeing the order of initialization of statics across compilation units.  This was causing some ASAN issues with the introduction/extended use of class and option names (e.g. TableFactory::kBlockBasedTableName/Opts).  To solve this problem, the static constant members were changed to static constant functions.  With this change, there should be no "order of initialization issue" as there is no variable being initialized.

By moving the kName values closer to home, some of the methods (like RegisterOptions and GetOptions) could be templatized/parameterized differently.
@facebook-github-bot
Copy link
Contributor

@mrambacher has updated the pull request. You must reimport the pull request before landing.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zhichao-cao has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@mrambacher has updated the pull request. You must reimport the pull request before landing.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zhichao-cao has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@mrambacher has updated the pull request. You must reimport the pull request before landing.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zhichao-cao has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@zhichao-cao merged this pull request in 7d472ac.

camelboat added a commit to camelboat/my_rocksdb that referenced this pull request Oct 29, 2020
Summary:
This PR merges the functionality of making the ColumnFamilyOptions, TableFactory, and DBOptions into Configurable into a single PR, resolving any merge conflicts

Pull Request resolved: facebook#5753

Reviewed By: ajkr

Differential Revision: D23385030

Pulled By: zhichao-cao

fbshipit-source-id: 8b977a7731556230b9b8c5a081b98e49ee4f160a
codingrhythm pushed a commit to SafetyCulture/rocksdb that referenced this pull request Mar 5, 2021
Summary:
This PR merges the functionality of making the ColumnFamilyOptions, TableFactory, and DBOptions into Configurable into a single PR, resolving any merge conflicts

Pull Request resolved: facebook#5753

Reviewed By: ajkr

Differential Revision: D23385030

Pulled By: zhichao-cao

fbshipit-source-id: 8b977a7731556230b9b8c5a081b98e49ee4f160a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants