class factory
In Java it is possible to create an object by knowing its class name in runtime. Replication strategies are created this way (I presume class name comes from configuration somehow), so when I translated the code to urchin I wrote replication_strategy_registry class to map a class name to a factory function. Now I see that this is used in other places too (I see that snitch class created in the same way), so instead of repeating the same code for each class hierarchy that is created from its name in origin this patch tries to introduce an infrastructure to do that easily. Signed-off-by: Avi Kivity <avi@cloudius-systems.com>
This commit is contained in:
@@ -3,14 +3,15 @@
|
||||
*/
|
||||
|
||||
#include "abstract_replication_strategy.hh"
|
||||
#include "utils/class_registrator.hh"
|
||||
|
||||
namespace locator {
|
||||
|
||||
abstract_replication_strategy::abstract_replication_strategy(const sstring& ks_name, token_metadata& token_metadata, std::unordered_map<sstring, sstring>& config_options) :
|
||||
_ks_name(ks_name), _config_options(config_options), _token_metadata(token_metadata) {}
|
||||
|
||||
std::unique_ptr<abstract_replication_strategy> abstract_replication_strategy::create_replication_strategy(const sstring& ks_name, const sstring& strategy_name, token_metadata& token_metadata, std::unordered_map<sstring, sstring>& config_options) {
|
||||
return replication_strategy_registry::create(strategy_name, ks_name, token_metadata, config_options);
|
||||
std::unique_ptr<abstract_replication_strategy> abstract_replication_strategy::create_replication_strategy(const sstring& ks_name, const sstring& strategy_name, token_metadata& tk_metadata, std::unordered_map<sstring, sstring>& config_options) {
|
||||
return create_object<abstract_replication_strategy>(strategy_name, ks_name, tk_metadata, config_options);
|
||||
}
|
||||
|
||||
std::vector<inet_address> abstract_replication_strategy::get_natural_endpoints(token& search_token) {
|
||||
@@ -18,18 +19,4 @@ std::vector<inet_address> abstract_replication_strategy::get_natural_endpoints(t
|
||||
return calculate_natural_endpoints(key_token);
|
||||
}
|
||||
|
||||
std::unordered_map<sstring, strategy_creator_type> replication_strategy_registry::_strategies;
|
||||
|
||||
void replication_strategy_registry::register_strategy(sstring name, strategy_creator_type creator) {
|
||||
_strategies.emplace(name, std::move(creator));
|
||||
}
|
||||
|
||||
std::unique_ptr<abstract_replication_strategy> replication_strategy_registry::create(const sstring& name, const sstring& keyspace_name, token_metadata& token_metadata, std::unordered_map<sstring, sstring>& config_options) {
|
||||
return _strategies[name](keyspace_name, token_metadata, config_options);
|
||||
}
|
||||
|
||||
replication_strategy_registrator::replication_strategy_registrator(sstring name, strategy_creator_type creator) {
|
||||
replication_strategy_registry::register_strategy(name, creator);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,18 +33,4 @@ public:
|
||||
std::vector<inet_address> get_natural_endpoints(token& search_token);
|
||||
};
|
||||
|
||||
using strategy_creator_type = std::function<std::unique_ptr<abstract_replication_strategy>(const sstring&, token_metadata&, std::unordered_map<sstring, sstring>&)>;
|
||||
|
||||
class replication_strategy_registry {
|
||||
static std::unordered_map<sstring, strategy_creator_type> _strategies;
|
||||
public:
|
||||
static void register_strategy(sstring name, strategy_creator_type creator);
|
||||
static std::unique_ptr<abstract_replication_strategy> create(const sstring& name, const sstring& keyspace_name, token_metadata& token_metadata, std::unordered_map<sstring, sstring>& config_options);
|
||||
};
|
||||
|
||||
class replication_strategy_registrator {
|
||||
public:
|
||||
explicit replication_strategy_registrator(sstring name, strategy_creator_type creator);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include "simple_strategy.hh"
|
||||
#include "utils/class_registrator.hh"
|
||||
|
||||
namespace locator {
|
||||
|
||||
@@ -45,9 +46,7 @@ size_t simple_strategy::get_replication_factor() const {
|
||||
return std::stol(it->second);
|
||||
}
|
||||
|
||||
static replication_strategy_registrator registerator("org.apache.cassandra.locator.SimpleStrategy",
|
||||
[] (const sstring& keyspace_name, token_metadata& token_metadata, std::unordered_map<sstring, sstring>& config_options) {
|
||||
return std::make_unique<simple_strategy>(keyspace_name, token_metadata, config_options);
|
||||
});
|
||||
using registry = class_registrator<abstract_replication_strategy, simple_strategy, const sstring&, token_metadata&, std::unordered_map<sstring, sstring>&>;
|
||||
static registry registrator("org.apache.cassandra.locator.SimpleStrategy");
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user