blob: 8c810a428ca53ede7c667ffc663fde4015f57c99 [file] [log] [blame]
Junxiao Shibb5105f2014-03-03 12:06:45 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi4e837f82017-10-02 22:14:43 +00002/*
Davide Pesaventob7bfcb92022-05-22 23:55:23 -04003 * Copyright (c) 2014-2022, Regents of the University of California,
Junxiao Shiff10da62016-07-13 17:57:43 +00004 * 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 Shic34d1672016-12-09 15:57:59 +000035
36class Forwarder;
37
Junxiao Shiff10da62016-07-13 17:57:43 +000038namespace strategy_choice {
Junxiao Shibb5105f2014-03-03 12:06:45 -070039
Davide Pesavento50a6af32019-02-21 00:04:40 -050040/** \brief Represents the Strategy Choice table
Junxiao Shie93d6a32014-09-07 16:13:22 -070041 *
42 * The Strategy Choice table maintains available Strategy types,
43 * and associates Name prefixes with Strategy types.
44 *
45 * Each strategy is identified by a strategyName.
46 * It's recommended to include a version number as the last component of strategyName.
47 *
48 * A Name prefix is owned by a strategy if a longest prefix match on the
49 * Strategy Choice table returns that strategy.
50 */
Junxiao Shibb5105f2014-03-03 12:06:45 -070051class StrategyChoice : noncopyable
52{
53public:
Junxiao Shic34d1672016-12-09 15:57:59 +000054 explicit
55 StrategyChoice(Forwarder& forwarder);
Junxiao Shibb5105f2014-03-03 12:06:45 -070056
Junxiao Shib30863e2016-08-15 21:32:01 +000057 size_t
58 size() const
59 {
60 return m_nItems;
61 }
62
Davide Pesavento50a6af32019-02-21 00:04:40 -050063 /** \brief Set the default strategy
Junxiao Shic34d1672016-12-09 15:57:59 +000064 *
65 * This must be called by forwarder constructor.
66 */
67 void
68 setDefaultStrategy(const Name& strategyName);
69
Junxiao Shibb5105f2014-03-03 12:06:45 -070070public: // Strategy Choice table
Junxiao Shi530cf002017-01-03 14:43:16 +000071 class InsertResult
72 {
73 public:
74 explicit
75 operator bool() const
76 {
77 return m_status == OK;
78 }
79
80 bool
81 isRegistered() const
82 {
Junxiao Shi4e837f82017-10-02 22:14:43 +000083 return m_status == OK || m_status == EXCEPTION;
Junxiao Shi530cf002017-01-03 14:43:16 +000084 }
85
Davide Pesavento50a6af32019-02-21 00:04:40 -050086 /** \brief Get a status code for use in management command response
Junxiao Shi332783b2018-02-04 23:52:46 +000087 */
88 int
89 getStatusCode() const
90 {
91 return static_cast<int>(m_status);
92 }
93
Junxiao Shi530cf002017-01-03 14:43:16 +000094 private:
95 enum Status {
Junxiao Shi332783b2018-02-04 23:52:46 +000096 OK = 200,
97 NOT_REGISTERED = 404,
98 EXCEPTION = 409,
99 DEPTH_EXCEEDED = 414,
Junxiao Shi530cf002017-01-03 14:43:16 +0000100 };
101
102 // implicitly constructible from Status
103 InsertResult(Status status, const std::string& exceptionMessage = "");
104
105 private:
106 Status m_status;
107 std::string m_exceptionMessage;
108
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400109 friend StrategyChoice;
Junxiao Shi530cf002017-01-03 14:43:16 +0000110 friend std::ostream& operator<<(std::ostream&, const InsertResult&);
111 };
112
Davide Pesavento50a6af32019-02-21 00:04:40 -0500113 /** \brief Set strategy of \p prefix to be \p strategyName
Junxiao Shi530cf002017-01-03 14:43:16 +0000114 * \param prefix the name prefix to change strategy
115 * \param strategyName strategy instance name, may contain version and parameters;
116 * strategy must have been registered
117 * \return convertible to true on success; convertible to false on failure
Junxiao Shibb5105f2014-03-03 12:06:45 -0700118 */
Junxiao Shi530cf002017-01-03 14:43:16 +0000119 InsertResult
Junxiao Shibb5105f2014-03-03 12:06:45 -0700120 insert(const Name& prefix, const Name& strategyName);
121
Davide Pesavento50a6af32019-02-21 00:04:40 -0500122 /** \brief Make prefix to inherit strategy from its parent
123 * \note Not allowed for root prefix (ndn:/)
Junxiao Shibb5105f2014-03-03 12:06:45 -0700124 */
125 void
126 erase(const Name& prefix);
127
Davide Pesavento50a6af32019-02-21 00:04:40 -0500128 /** \brief Get strategy Name of prefix
Junxiao Shi838c4f12014-11-03 18:55:24 -0700129 * \return true and strategyName at exact match, or false
Junxiao Shibb5105f2014-03-03 12:06:45 -0700130 */
Junxiao Shi838c4f12014-11-03 18:55:24 -0700131 std::pair<bool, Name>
Junxiao Shibb5105f2014-03-03 12:06:45 -0700132 get(const Name& prefix) const;
133
Junxiao Shib5888d22014-05-26 07:35:22 -0700134public: // effective strategy
Davide Pesavento50a6af32019-02-21 00:04:40 -0500135 /** \brief Get effective strategy for \p prefix
Junxiao Shia49a1ab2016-07-15 18:24:36 +0000136 */
Junxiao Shibb5105f2014-03-03 12:06:45 -0700137 fw::Strategy&
138 findEffectiveStrategy(const Name& prefix) const;
139
Davide Pesavento50a6af32019-02-21 00:04:40 -0500140 /** \brief Get effective strategy for \p pitEntry
Junxiao Shib30863e2016-08-15 21:32:01 +0000141 *
Davide Pesavento50a6af32019-02-21 00:04:40 -0500142 * This is equivalent to `findEffectiveStrategy(pitEntry.getName())`
Junxiao Shia49a1ab2016-07-15 18:24:36 +0000143 */
Junxiao Shibb5105f2014-03-03 12:06:45 -0700144 fw::Strategy&
145 findEffectiveStrategy(const pit::Entry& pitEntry) const;
146
Davide Pesavento50a6af32019-02-21 00:04:40 -0500147 /** \brief Get effective strategy for \p measurementsEntry
Junxiao Shib30863e2016-08-15 21:32:01 +0000148 *
Davide Pesavento50a6af32019-02-21 00:04:40 -0500149 * This is equivalent to `findEffectiveStrategy(measurementsEntry.getName())`
Junxiao Shia49a1ab2016-07-15 18:24:36 +0000150 */
Junxiao Shi7bb01512014-03-05 21:34:09 -0700151 fw::Strategy&
152 findEffectiveStrategy(const measurements::Entry& measurementsEntry) const;
153
Junxiao Shib5888d22014-05-26 07:35:22 -0700154public: // enumeration
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400155 using Range = boost::transformed_range<name_tree::GetTableEntry<Entry>, const name_tree::Range>;
156 using const_iterator = boost::range_iterator<Range>::type;
Junxiao Shib5888d22014-05-26 07:35:22 -0700157
Junxiao Shib30863e2016-08-15 21:32:01 +0000158 /** \return an iterator to the beginning
159 * \note Iteration order is implementation-defined.
160 * \warning Undefined behavior may occur if a FIB/PIT/Measurements/StrategyChoice entry
161 * is inserted or erased during enumeration.
Junxiao Shia49a1ab2016-07-15 18:24:36 +0000162 */
Junxiao Shib5888d22014-05-26 07:35:22 -0700163 const_iterator
Junxiao Shib30863e2016-08-15 21:32:01 +0000164 begin() const
165 {
166 return this->getRange().begin();
167 }
Junxiao Shib5888d22014-05-26 07:35:22 -0700168
Junxiao Shib30863e2016-08-15 21:32:01 +0000169 /** \return an iterator to the end
170 * \sa begin()
171 */
Junxiao Shib5888d22014-05-26 07:35:22 -0700172 const_iterator
Junxiao Shib30863e2016-08-15 21:32:01 +0000173 end() const
174 {
175 return this->getRange().end();
176 }
Junxiao Shib5888d22014-05-26 07:35:22 -0700177
Junxiao Shibb5105f2014-03-03 12:06:45 -0700178private:
Junxiao Shibb5105f2014-03-03 12:06:45 -0700179 void
Junxiao Shiff10da62016-07-13 17:57:43 +0000180 changeStrategy(Entry& entry,
Junxiao Shi838c4f12014-11-03 18:55:24 -0700181 fw::Strategy& oldStrategy,
182 fw::Strategy& newStrategy);
Junxiao Shibb5105f2014-03-03 12:06:45 -0700183
Junxiao Shidd8f6612016-08-12 15:42:52 +0000184 /** \tparam K a parameter acceptable to NameTree::findLongestPrefixMatch
185 */
186 template<typename K>
HangZhangcb4fc832014-03-11 16:57:11 +0800187 fw::Strategy&
Junxiao Shidd8f6612016-08-12 15:42:52 +0000188 findEffectiveStrategyImpl(const K& key) const;
HangZhangcb4fc832014-03-11 16:57:11 +0800189
Junxiao Shib30863e2016-08-15 21:32:01 +0000190 Range
191 getRange() const;
192
Junxiao Shibb5105f2014-03-03 12:06:45 -0700193private:
Junxiao Shic34d1672016-12-09 15:57:59 +0000194 Forwarder& m_forwarder;
Junxiao Shibb5105f2014-03-03 12:06:45 -0700195 NameTree& m_nameTree;
Davide Pesavento50a6af32019-02-21 00:04:40 -0500196 size_t m_nItems = 0;
Junxiao Shibb5105f2014-03-03 12:06:45 -0700197};
198
Junxiao Shi530cf002017-01-03 14:43:16 +0000199std::ostream&
200operator<<(std::ostream& os, const StrategyChoice::InsertResult& res);
201
Junxiao Shiff10da62016-07-13 17:57:43 +0000202} // namespace strategy_choice
203
204using strategy_choice::StrategyChoice;
205
Junxiao Shibb5105f2014-03-03 12:06:45 -0700206} // namespace nfd
207
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700208#endif // NFD_DAEMON_TABLE_STRATEGY_CHOICE_HPP