void StrategyChoice::changeStrategy(Entry& entry, Strategy& oldStrategy, Strategy& newStrategy) { const Name& oldInstanceName = oldStrategy.getInstanceName(); const Name& newInstanceName = newStrategy.getInstanceName(); if (Strategy::areSameType(oldInstanceName, newInstanceName)) { // same Strategy subclass type: no need to clear StrategyInfo NFD_LOG_INFO("changeStrategy(" << entry.getPrefix() << ") " << oldInstanceName << " -> " << newInstanceName << " same-type"); return; } NFD_LOG_INFO("changeStrategy(" << entry.getPrefix() << ") " << oldInstanceName << " -> " << newInstanceName); // reset StrategyInfo on a portion of NameTree, // where entry's effective strategy is covered by the changing StrategyChoice entry const name_tree::Entry* rootNte = m_nameTree.getEntry(entry); BOOST_ASSERT(rootNte != nullptr); const auto& ntChanged = m_nameTree.partialEnumerate(entry.getPrefix(), [&rootNte] (const name_tree::Entry& nte) -> std::pair<bool, bool> { if (&nte == rootNte) { return {true, true}; } if (nte.getStrategyChoiceEntry() != nullptr) { return {false, false}; } return {true, true}; }); for (const auto& nte : ntChanged) { clearStrategyInfo(nte); } }
void StrategyChoice::changeStrategy(Entry& entry, Strategy& oldStrategy, Strategy& newStrategy) { ///\todo #3868 don't clear StrategyInfo if only parameter differs if (&oldStrategy == &newStrategy) { return; } NFD_LOG_INFO("changeStrategy(" << entry.getPrefix() << ")" << " from " << oldStrategy.getInstanceName() << " to " << newStrategy.getInstanceName()); // reset StrategyInfo on a portion of NameTree, // where entry's effective strategy is covered by the changing StrategyChoice entry const name_tree::Entry* rootNte = m_nameTree.getEntry(entry); BOOST_ASSERT(rootNte != nullptr); auto&& ntChanged = m_nameTree.partialEnumerate(entry.getPrefix(), [&rootNte] (const name_tree::Entry& nte) -> std::pair<bool, bool> { if (&nte == rootNte) { return {true, true}; } if (nte.getStrategyChoiceEntry() != nullptr) { return {false, false}; } return {true, true}; }); for (const name_tree::Entry& nte : ntChanged) { clearStrategyInfo(nte); } }
StrategyChoice::InsertResult StrategyChoice::insert(const Name& prefix, const Name& strategyName) { if (prefix.size() > NameTree::getMaxDepth()) { return InsertResult::DEPTH_EXCEEDED; } unique_ptr<Strategy> strategy; try { strategy = Strategy::create(strategyName, m_forwarder); } catch (const std::invalid_argument& e) { NFD_LOG_ERROR("insert(" << prefix << "," << strategyName << ") cannot create strategy: " << e.what()); return InsertResult(InsertResult::EXCEPTION, e.what()); } if (strategy == nullptr) { NFD_LOG_ERROR("insert(" << prefix << "," << strategyName << ") strategy not registered"); return InsertResult::NOT_REGISTERED; } name_tree::Entry& nte = m_nameTree.lookup(prefix); Entry* entry = nte.getStrategyChoiceEntry(); Strategy* oldStrategy = nullptr; if (entry != nullptr) { if (entry->getStrategyInstanceName() == strategy->getInstanceName()) { NFD_LOG_TRACE("insert(" << prefix << ") not changing " << strategy->getInstanceName()); return InsertResult::OK; } oldStrategy = &entry->getStrategy(); NFD_LOG_TRACE("insert(" << prefix << ") changing from " << oldStrategy->getInstanceName() << " to " << strategy->getInstanceName()); } else { oldStrategy = &this->findEffectiveStrategy(prefix); auto newEntry = make_unique<Entry>(prefix); entry = newEntry.get(); nte.setStrategyChoiceEntry(std::move(newEntry)); ++m_nItems; NFD_LOG_TRACE("insert(" << prefix << ") new entry " << strategy->getInstanceName()); } this->changeStrategy(*entry, *oldStrategy, *strategy); entry->setStrategy(std::move(strategy)); return InsertResult::OK; }