table: StrategyChoice uses unique_ptr instead of shared_ptr
refs #3164
Change-Id: Id3110f72aab83982b0768e596a04bad9f7336975
diff --git a/daemon/table/strategy-choice.cpp b/daemon/table/strategy-choice.cpp
index 5778237..3c701d4 100644
--- a/daemon/table/strategy-choice.cpp
+++ b/daemon/table/strategy-choice.cpp
@@ -36,11 +36,11 @@
NFD_LOG_INIT("StrategyChoice");
-StrategyChoice::StrategyChoice(NameTree& nameTree, shared_ptr<Strategy> defaultStrategy)
+StrategyChoice::StrategyChoice(NameTree& nameTree, unique_ptr<Strategy> defaultStrategy)
: m_nameTree(nameTree)
, m_nItems(0)
{
- this->setDefaultStrategy(defaultStrategy);
+ this->setDefaultStrategy(std::move(defaultStrategy));
}
bool
@@ -54,25 +54,27 @@
}
}
-bool
-StrategyChoice::install(shared_ptr<Strategy> strategy)
+std::pair<bool, Strategy*>
+StrategyChoice::install(unique_ptr<Strategy> strategy)
{
BOOST_ASSERT(strategy != nullptr);
- const Name& strategyName = strategy->getName();
+ Name strategyName = strategy->getName();
+ // copying Name, so that strategyName remains available even if strategy is deallocated
- if (this->hasStrategy(strategyName, true)) {
+ bool isInserted = false;
+ StrategyInstanceTable::iterator it;
+ std::tie(it, isInserted) = m_strategyInstances.emplace(strategyName, std::move(strategy));
+
+ if (!isInserted) {
NFD_LOG_ERROR("install(" << strategyName << ") duplicate strategyName");
- return false;
}
-
- m_strategyInstances[strategyName] = strategy;
- return true;
+ return std::make_pair(isInserted, it->second.get());
}
-fw::Strategy*
+Strategy*
StrategyChoice::getStrategy(const Name& strategyName) const
{
- fw::Strategy* candidate = nullptr;
+ Strategy* candidate = nullptr;
for (auto it = m_strategyInstances.lower_bound(strategyName);
it != m_strategyInstances.end() && strategyName.isPrefixOf(it->first); ++it) {
switch (it->first.size() - strategyName.size()) {
@@ -206,19 +208,22 @@
}
void
-StrategyChoice::setDefaultStrategy(shared_ptr<Strategy> strategy)
+StrategyChoice::setDefaultStrategy(unique_ptr<Strategy> strategy)
{
- this->install(strategy);
+ bool isInstalled = false;
+ Strategy* instance = nullptr;
+ std::tie(isInstalled, instance) = this->install(std::move(strategy));
+ BOOST_ASSERT(isInstalled);
auto entry = make_unique<Entry>(Name());
- entry->setStrategy(*strategy);
+ entry->setStrategy(*instance);
// don't use .insert here, because it will invoke findEffectiveStrategy
// which expects an existing root entry
shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(Name());
nte->setStrategyChoiceEntry(std::move(entry));
++m_nItems;
- NFD_LOG_INFO("setDefaultStrategy " << strategy->getName());
+ NFD_LOG_INFO("setDefaultStrategy " << instance->getName());
}
static inline void
@@ -241,9 +246,7 @@
}
void
-StrategyChoice::changeStrategy(Entry& entry,
- fw::Strategy& oldStrategy,
- fw::Strategy& newStrategy)
+StrategyChoice::changeStrategy(Entry& entry, Strategy& oldStrategy, Strategy& newStrategy)
{
if (&oldStrategy == &newStrategy) {
return;
diff --git a/daemon/table/strategy-choice.hpp b/daemon/table/strategy-choice.hpp
index 7082092..84b1b03 100644
--- a/daemon/table/strategy-choice.hpp
+++ b/daemon/table/strategy-choice.hpp
@@ -46,7 +46,7 @@
class StrategyChoice : noncopyable
{
public:
- StrategyChoice(NameTree& nameTree, shared_ptr<fw::Strategy> defaultStrategy);
+ StrategyChoice(NameTree& nameTree, unique_ptr<fw::Strategy> defaultStrategy);
public: // available Strategy types
/** \brief determines if a strategy is installed
@@ -58,11 +58,12 @@
hasStrategy(const Name& strategyName, bool isExact = false) const;
/** \brief install a strategy
- * \return true if installed; false if not installed due to duplicate strategyName
- * \note shared_ptr is passed by value because StrategyChoice takes ownership of strategy
+ * \return if installed, true, and a pointer to the strategy instance;
+ * if not installed due to duplicate strategyName, false,
+ * and a pointer to the existing strategy instance
*/
- bool
- install(shared_ptr<fw::Strategy> strategy);
+ std::pair<bool, fw::Strategy*>
+ install(unique_ptr<fw::Strategy> strategy);
public: // Strategy Choice table
/** \brief set strategy of prefix to be strategyName
@@ -92,15 +93,18 @@
get(const Name& prefix) const;
public: // effective strategy
- /// get effective strategy for prefix
+ /** \brief get effective strategy for prefix
+ */
fw::Strategy&
findEffectiveStrategy(const Name& prefix) const;
- /// get effective strategy for pitEntry
+ /** \brief get effective strategy for pitEntry
+ */
fw::Strategy&
findEffectiveStrategy(const pit::Entry& pitEntry) const;
- /// get effective strategy for measurementsEntry
+ /** \brief get effective strategy for measurementsEntry
+ */
fw::Strategy&
findEffectiveStrategy(const measurements::Entry& measurementsEntry) const;
@@ -136,7 +140,8 @@
NameTree::const_iterator m_nameTreeIterator;
};
- /// number of entries stored
+ /** \return number of entries stored
+ */
size_t
size() const;
@@ -154,7 +159,7 @@
getStrategy(const Name& strategyName) const;
void
- setDefaultStrategy(shared_ptr<fw::Strategy> strategy);
+ setDefaultStrategy(unique_ptr<fw::Strategy> strategy);
void
changeStrategy(Entry& entry,
@@ -168,7 +173,7 @@
NameTree& m_nameTree;
size_t m_nItems;
- typedef std::map<Name, shared_ptr<fw::Strategy>> StrategyInstanceTable;
+ typedef std::map<Name, unique_ptr<fw::Strategy>> StrategyInstanceTable;
StrategyInstanceTable m_strategyInstances;
};