diff --git a/locator/abstract_replication_strategy.cc b/locator/abstract_replication_strategy.cc index 2a51b44034..6030f4a596 100644 --- a/locator/abstract_replication_strategy.cc +++ b/locator/abstract_replication_strategy.cc @@ -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& config_options) : _ks_name(ks_name), _config_options(config_options), _token_metadata(token_metadata) {} -std::unique_ptr abstract_replication_strategy::create_replication_strategy(const sstring& ks_name, const sstring& strategy_name, token_metadata& token_metadata, std::unordered_map& config_options) { - return replication_strategy_registry::create(strategy_name, ks_name, token_metadata, config_options); +std::unique_ptr abstract_replication_strategy::create_replication_strategy(const sstring& ks_name, const sstring& strategy_name, token_metadata& tk_metadata, std::unordered_map& config_options) { + return create_object(strategy_name, ks_name, tk_metadata, config_options); } std::vector abstract_replication_strategy::get_natural_endpoints(token& search_token) { @@ -18,18 +19,4 @@ std::vector abstract_replication_strategy::get_natural_endpoints(t return calculate_natural_endpoints(key_token); } -std::unordered_map 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 replication_strategy_registry::create(const sstring& name, const sstring& keyspace_name, token_metadata& token_metadata, std::unordered_map& 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); -} - } diff --git a/locator/abstract_replication_strategy.hh b/locator/abstract_replication_strategy.hh index bd4facd23a..c7f510c3df 100644 --- a/locator/abstract_replication_strategy.hh +++ b/locator/abstract_replication_strategy.hh @@ -33,18 +33,4 @@ public: std::vector get_natural_endpoints(token& search_token); }; -using strategy_creator_type = std::function(const sstring&, token_metadata&, std::unordered_map&)>; - -class replication_strategy_registry { - static std::unordered_map _strategies; -public: - static void register_strategy(sstring name, strategy_creator_type creator); - static std::unique_ptr create(const sstring& name, const sstring& keyspace_name, token_metadata& token_metadata, std::unordered_map& config_options); -}; - -class replication_strategy_registrator { -public: - explicit replication_strategy_registrator(sstring name, strategy_creator_type creator); -}; - } diff --git a/locator/simple_strategy.cc b/locator/simple_strategy.cc index 878125e034..99198e419f 100644 --- a/locator/simple_strategy.cc +++ b/locator/simple_strategy.cc @@ -4,6 +4,7 @@ #include #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& config_options) { - return std::make_unique(keyspace_name, token_metadata, config_options); -}); +using registry = class_registrator&>; +static registry registrator("org.apache.cassandra.locator.SimpleStrategy"); } diff --git a/utils/class_registrator.hh b/utils/class_registrator.hh new file mode 100644 index 0000000000..625d1a625d --- /dev/null +++ b/utils/class_registrator.hh @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2015 Cloudius Systems, Ltd. + */ + +#pragma once + +// BaseType is a base type of a type hierarchy that this registry will hold +// Args... are parameters for object's constructor +template +class class_registry { + using creator_type = std::function(Args...)>; + static std::unordered_map _classes; +public: + static void register_class(sstring name, creator_type creator); + template + static void register_class(sstring name); + static std::unique_ptr create(const sstring& name, Args...); +}; + +template +std::unordered_map::creator_type> class_registry::_classes; + +template +void class_registry::register_class(sstring name, class_registry::creator_type creator) { + _classes.emplace(name, std::move(creator)); +} + +template +template +void class_registry::register_class(sstring name) { + register_class(name, [](Args&&... args) { + return std::make_unique(std::forward(args)...); + }); +} + +template +struct class_registrator { + class_registrator(const sstring& name) { + class_registry::template register_class(name); + } + class_registrator(const sstring& name, std::function(Args...)> creator) { + class_registry::register_class(name, creator); + } +}; + +template +std::unique_ptr class_registry::create(const sstring& name, Args... args) { + return _classes[name](args...); +} + +template +std::unique_ptr create_object(const sstring& name, Args&&... args) { + return class_registry::create(name, std::forward(args)...); +} +