blob: 1038cfb215729d13337f5fedeea0c44a068abd9c [file] [log] [blame]
Junxiao Shibb5105f2014-03-03 12:06:45 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shiff10da62016-07-13 17:57:43 +00003 * Copyright (c) 2014-2016, Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070010 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Junxiao Shie93d6a32014-09-07 16:13:22 -070024 */
Junxiao Shibb5105f2014-03-03 12:06:45 -070025
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070026#ifndef NFD_DAEMON_TABLE_STRATEGY_CHOICE_HPP
27#define NFD_DAEMON_TABLE_STRATEGY_CHOICE_HPP
Junxiao Shibb5105f2014-03-03 12:06:45 -070028
29#include "strategy-choice-entry.hpp"
30#include "name-tree.hpp"
31
Junxiao Shib30863e2016-08-15 21:32:01 +000032#include <boost/range/adaptor/transformed.hpp>
33
Junxiao Shibb5105f2014-03-03 12:06:45 -070034namespace nfd {
Junxiao Shiff10da62016-07-13 17:57:43 +000035namespace strategy_choice {
Junxiao Shibb5105f2014-03-03 12:06:45 -070036
Junxiao Shie93d6a32014-09-07 16:13:22 -070037/** \brief represents the Strategy Choice table
38 *
39 * The Strategy Choice table maintains available Strategy types,
40 * and associates Name prefixes with Strategy types.
41 *
42 * Each strategy is identified by a strategyName.
43 * It's recommended to include a version number as the last component of strategyName.
44 *
45 * A Name prefix is owned by a strategy if a longest prefix match on the
46 * Strategy Choice table returns that strategy.
47 */
Junxiao Shibb5105f2014-03-03 12:06:45 -070048class StrategyChoice : noncopyable
49{
50public:
Junxiao Shia49a1ab2016-07-15 18:24:36 +000051 StrategyChoice(NameTree& nameTree, unique_ptr<fw::Strategy> defaultStrategy);
Junxiao Shibb5105f2014-03-03 12:06:45 -070052
Junxiao Shib30863e2016-08-15 21:32:01 +000053 size_t
54 size() const
55 {
56 return m_nItems;
57 }
58
Junxiao Shibb5105f2014-03-03 12:06:45 -070059public: // available Strategy types
Junxiao Shie93d6a32014-09-07 16:13:22 -070060 /** \brief determines if a strategy is installed
Alexander Afanasyevb755e9d2015-10-20 17:35:51 -050061 * \param strategyName name of the strategy
Junxiao Shie93d6a32014-09-07 16:13:22 -070062 * \param isExact true to require exact match, false to permit unversioned strategyName
63 * \return true if strategy is installed
Junxiao Shibb5105f2014-03-03 12:06:45 -070064 */
65 bool
Junxiao Shie93d6a32014-09-07 16:13:22 -070066 hasStrategy(const Name& strategyName, bool isExact = false) const;
Junxiao Shibb5105f2014-03-03 12:06:45 -070067
68 /** \brief install a strategy
Junxiao Shia49a1ab2016-07-15 18:24:36 +000069 * \return if installed, true, and a pointer to the strategy instance;
70 * if not installed due to duplicate strategyName, false,
71 * and a pointer to the existing strategy instance
Junxiao Shibb5105f2014-03-03 12:06:45 -070072 */
Junxiao Shia49a1ab2016-07-15 18:24:36 +000073 std::pair<bool, fw::Strategy*>
74 install(unique_ptr<fw::Strategy> strategy);
Junxiao Shibb5105f2014-03-03 12:06:45 -070075
76public: // Strategy Choice table
77 /** \brief set strategy of prefix to be strategyName
Alexander Afanasyevb755e9d2015-10-20 17:35:51 -050078 * \param prefix the name prefix for which \p strategyName should be used
Junxiao Shie93d6a32014-09-07 16:13:22 -070079 * \param strategyName the strategy to be used
Junxiao Shibb5105f2014-03-03 12:06:45 -070080 * \return true on success
Junxiao Shie93d6a32014-09-07 16:13:22 -070081 *
82 * This method set a strategy onto a Name prefix.
83 * The strategy must have been installed.
84 * The strategyName can either be exact (contains version component),
85 * or omit the version component to pick the latest version.
Junxiao Shibb5105f2014-03-03 12:06:45 -070086 */
87 bool
88 insert(const Name& prefix, const Name& strategyName);
89
90 /** \brief make prefix to inherit strategy from its parent
91 *
92 * not allowed for root prefix (ndn:/)
93 */
94 void
95 erase(const Name& prefix);
96
97 /** \brief get strategy Name of prefix
Junxiao Shi838c4f12014-11-03 18:55:24 -070098 * \return true and strategyName at exact match, or false
Junxiao Shibb5105f2014-03-03 12:06:45 -070099 */
Junxiao Shi838c4f12014-11-03 18:55:24 -0700100 std::pair<bool, Name>
Junxiao Shibb5105f2014-03-03 12:06:45 -0700101 get(const Name& prefix) const;
102
Junxiao Shib5888d22014-05-26 07:35:22 -0700103public: // effective strategy
Junxiao Shia49a1ab2016-07-15 18:24:36 +0000104 /** \brief get effective strategy for prefix
105 */
Junxiao Shibb5105f2014-03-03 12:06:45 -0700106 fw::Strategy&
107 findEffectiveStrategy(const Name& prefix) const;
108
Junxiao Shia49a1ab2016-07-15 18:24:36 +0000109 /** \brief get effective strategy for pitEntry
Junxiao Shib30863e2016-08-15 21:32:01 +0000110 *
111 * This is equivalent to .findEffectiveStrategy(pitEntry.getName())
Junxiao Shia49a1ab2016-07-15 18:24:36 +0000112 */
Junxiao Shibb5105f2014-03-03 12:06:45 -0700113 fw::Strategy&
114 findEffectiveStrategy(const pit::Entry& pitEntry) const;
115
Junxiao Shia49a1ab2016-07-15 18:24:36 +0000116 /** \brief get effective strategy for measurementsEntry
Junxiao Shib30863e2016-08-15 21:32:01 +0000117 *
118 * This is equivalent to .findEffectiveStrategy(measurementsEntry.getName())
Junxiao Shia49a1ab2016-07-15 18:24:36 +0000119 */
Junxiao Shi7bb01512014-03-05 21:34:09 -0700120 fw::Strategy&
121 findEffectiveStrategy(const measurements::Entry& measurementsEntry) const;
122
Junxiao Shib5888d22014-05-26 07:35:22 -0700123public: // enumeration
Junxiao Shib30863e2016-08-15 21:32:01 +0000124 typedef boost::transformed_range<name_tree::GetTableEntry<Entry>, const name_tree::Range> Range;
125 typedef boost::range_iterator<Range>::type const_iterator;
Junxiao Shib5888d22014-05-26 07:35:22 -0700126
Junxiao Shib30863e2016-08-15 21:32:01 +0000127 /** \return an iterator to the beginning
128 * \note Iteration order is implementation-defined.
129 * \warning Undefined behavior may occur if a FIB/PIT/Measurements/StrategyChoice entry
130 * is inserted or erased during enumeration.
Junxiao Shia49a1ab2016-07-15 18:24:36 +0000131 */
Junxiao Shib5888d22014-05-26 07:35:22 -0700132 const_iterator
Junxiao Shib30863e2016-08-15 21:32:01 +0000133 begin() const
134 {
135 return this->getRange().begin();
136 }
Junxiao Shib5888d22014-05-26 07:35:22 -0700137
Junxiao Shib30863e2016-08-15 21:32:01 +0000138 /** \return an iterator to the end
139 * \sa begin()
140 */
Junxiao Shib5888d22014-05-26 07:35:22 -0700141 const_iterator
Junxiao Shib30863e2016-08-15 21:32:01 +0000142 end() const
143 {
144 return this->getRange().end();
145 }
Junxiao Shib5888d22014-05-26 07:35:22 -0700146
Junxiao Shibb5105f2014-03-03 12:06:45 -0700147private:
Junxiao Shie93d6a32014-09-07 16:13:22 -0700148 /** \brief get Strategy instance by strategyName
149 * \param strategyName a versioned or unversioned strategyName
150 */
Junxiao Shi838c4f12014-11-03 18:55:24 -0700151 fw::Strategy*
Junxiao Shie93d6a32014-09-07 16:13:22 -0700152 getStrategy(const Name& strategyName) const;
Junxiao Shibb5105f2014-03-03 12:06:45 -0700153
154 void
Junxiao Shia49a1ab2016-07-15 18:24:36 +0000155 setDefaultStrategy(unique_ptr<fw::Strategy> strategy);
Junxiao Shibb5105f2014-03-03 12:06:45 -0700156
157 void
Junxiao Shiff10da62016-07-13 17:57:43 +0000158 changeStrategy(Entry& entry,
Junxiao Shi838c4f12014-11-03 18:55:24 -0700159 fw::Strategy& oldStrategy,
160 fw::Strategy& newStrategy);
Junxiao Shibb5105f2014-03-03 12:06:45 -0700161
Junxiao Shidd8f6612016-08-12 15:42:52 +0000162 /** \tparam K a parameter acceptable to NameTree::findLongestPrefixMatch
163 */
164 template<typename K>
HangZhangcb4fc832014-03-11 16:57:11 +0800165 fw::Strategy&
Junxiao Shidd8f6612016-08-12 15:42:52 +0000166 findEffectiveStrategyImpl(const K& key) const;
HangZhangcb4fc832014-03-11 16:57:11 +0800167
Junxiao Shib30863e2016-08-15 21:32:01 +0000168 Range
169 getRange() const;
170
Junxiao Shibb5105f2014-03-03 12:06:45 -0700171private:
172 NameTree& m_nameTree;
173 size_t m_nItems;
174
Junxiao Shia49a1ab2016-07-15 18:24:36 +0000175 typedef std::map<Name, unique_ptr<fw::Strategy>> StrategyInstanceTable;
Junxiao Shibb5105f2014-03-03 12:06:45 -0700176 StrategyInstanceTable m_strategyInstances;
177};
178
Junxiao Shiff10da62016-07-13 17:57:43 +0000179} // namespace strategy_choice
180
181using strategy_choice::StrategyChoice;
182
Junxiao Shibb5105f2014-03-03 12:06:45 -0700183} // namespace nfd
184
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700185#endif // NFD_DAEMON_TABLE_STRATEGY_CHOICE_HPP