blob: 2da1979a4c443e4d93e97999746ea9ac19992562 [file] [log] [blame]
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi2af9ca32016-08-25 21:51:02 +00003 * Copyright (c) 2014-2016, Regents of the University of California,
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -05004 * 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.
10 *
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/>.
24 */
25
26#ifndef NFD_DAEMON_TABLE_CS_POLICY_HPP
27#define NFD_DAEMON_TABLE_CS_POLICY_HPP
28
29#include "cs-internal.hpp"
30#include "cs-entry-impl.hpp"
31
32namespace nfd {
33namespace cs {
34
35class Cs;
36
37/** \brief represents a CS replacement policy
38 */
39class Policy : noncopyable
40{
Junxiao Shi52555b02016-11-25 21:39:06 +000041public: // registry
42 template<typename P>
43 static void
44 registerPolicy()
45 {
46 const std::string& key = P::POLICY_NAME;
47 Registry& registry = getRegistry();
48 BOOST_ASSERT(registry.count(key) == 0);
49 registry[key] = [] { return make_unique<P>(); };
50 }
51
52 /** \return a Policy identified by \p key, or nullptr if \p key is unknown
53 */
54 static unique_ptr<Policy>
55 create(const std::string& key);
56
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050057public:
58 explicit
59 Policy(const std::string& policyName);
60
61 virtual
Junxiao Shi2af9ca32016-08-25 21:51:02 +000062 ~Policy() = default;
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050063
64 const std::string&
65 getName() const;
66
67public:
68 /** \brief gets cs
69 */
70 Cs*
71 getCs() const;
72
73 /** \brief sets cs
74 */
75 void
76 setCs(Cs *cs);
77
78 /** \brief gets hard limit (in number of entries)
79 */
80 size_t
81 getLimit() const;
82
83 /** \brief sets hard limit (in number of entries)
84 * \post getLimit() == nMaxEntries
85 * \post cs.size() <= getLimit()
86 *
87 * The policy may evict entries if necessary.
88 */
89 void
90 setLimit(size_t nMaxEntries);
91
92 /** \brief emits when an entry is being evicted
93 *
94 * A policy implementation should emit this signal to cause CS to erase the entry from its index.
95 * CS should connect to this signal and erase the entry upon signal emission.
96 */
97 signal::Signal<Policy, iterator> beforeEvict;
98
99 /** \brief invoked by CS after a new entry is inserted
100 * \post cs.size() <= getLimit()
101 *
102 * The policy may evict entries if necessary.
103 * During this process, \p i might be evicted.
104 */
105 void
106 afterInsert(iterator i);
107
108 /** \brief invoked by CS after an existing entry is refreshed by same Data
109 *
110 * The policy may witness this refresh to make better eviction decisions in the future.
111 */
112 void
113 afterRefresh(iterator i);
114
115 /** \brief invoked by CS before an entry is erased due to management command
116 * \warning CS must not invoke this method if an entry is erased due to eviction.
117 */
118 void
119 beforeErase(iterator i);
120
121 /** \brief invoked by CS before an entry is used to match a lookup
122 *
123 * The policy may witness this usage to make better eviction decisions in the future.
124 */
125 void
126 beforeUse(iterator i);
127
128protected:
129 /** \brief invoked after a new entry is created in CS
130 *
131 * When overridden in a subclass, a policy implementation should decide whether to accept \p i.
132 * If \p i is accepted, it should be inserted into a cleanup index.
133 * Otherwise, \p beforeEvict signal should be emitted with \p i to inform CS to erase the entry.
134 * A policy implementation may decide to evict other entries by emitting \p beforeEvict signal,
135 * in order to keep CS size under limit.
136 */
137 virtual void
138 doAfterInsert(iterator i) = 0;
139
140 /** \brief invoked after an existing entry is refreshed by same Data
141 *
142 * When overridden in a subclass, a policy implementation may witness this operation
143 * and adjust its cleanup index.
144 */
145 virtual void
146 doAfterRefresh(iterator i) = 0;
147
148 /** \brief invoked before an entry is erased due to management command
149 * \note This will not be invoked for an entry being evicted by policy.
150 *
151 * When overridden in a subclass, a policy implementation should erase \p i
152 * from its cleanup index without emitted \p afterErase signal.
153 */
154 virtual void
155 doBeforeErase(iterator i) = 0;
156
157 /** \brief invoked before an entry is used to match a lookup
158 *
159 * When overridden in a subclass, a policy implementation may witness this operation
160 * and adjust its cleanup index.
161 */
162 virtual void
163 doBeforeUse(iterator i) = 0;
164
165 /** \brief evicts zero or more entries
166 * \post CS size does not exceed hard limit
167 */
168 virtual void
169 evictEntries() = 0;
170
171protected:
172 DECLARE_SIGNAL_EMIT(beforeEvict)
173
Junxiao Shi52555b02016-11-25 21:39:06 +0000174private: // registry
175 typedef std::function<unique_ptr<Policy>()> CreateFunc;
176 typedef std::map<std::string, CreateFunc> Registry; // indexed by key
177
178 static Registry&
179 getRegistry();
180
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500181private:
182 std::string m_policyName;
183 size_t m_limit;
184 Cs* m_cs;
185};
186
187inline const std::string&
188Policy::getName() const
189{
190 return m_policyName;
191}
192
193inline Cs*
194Policy::getCs() const
195{
196 return m_cs;
197}
198
199inline void
200Policy::setCs(Cs *cs)
201{
202 m_cs = cs;
203}
204
205inline size_t
206Policy::getLimit() const
207{
208 return m_limit;
209}
210
211} // namespace cs
212} // namespace nfd
213
Junxiao Shi52555b02016-11-25 21:39:06 +0000214/** \brief registers a CS policy
215 * \param P a subclass of nfd::cs::Policy
216 */
217#define NFD_REGISTER_CS_POLICY(P) \
218static class NfdAuto ## P ## CsPolicyRegistrationClass \
219{ \
220public: \
221 NfdAuto ## P ## CsPolicyRegistrationClass() \
222 { \
223 ::nfd::cs::Policy::registerPolicy<P>(); \
224 } \
225} g_nfdAuto ## P ## CsPolicyRegistrationVariable
226
Junxiao Shi2af9ca32016-08-25 21:51:02 +0000227#endif // NFD_DAEMON_TABLE_CS_POLICY_HPP