blob: de4c89c4420ef6403537bd57785bcf153bb5660e [file] [log] [blame]
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi5e4a02f2019-07-15 11:59:18 +00002/*
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -04003 * Copyright (c) 2014-2022, 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
Junxiao Shi5e4a02f2019-07-15 11:59:18 +000029#include "cs-entry.hpp"
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050030
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040031namespace nfd::cs {
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050032
33class Cs;
34
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -040035/**
36 * \brief Represents a CS replacement policy
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050037 */
38class Policy : noncopyable
39{
Junxiao Shi52555b02016-11-25 21:39:06 +000040public: // registry
41 template<typename P>
42 static void
Junxiao Shi7ee00fb2016-12-04 21:23:00 +000043 registerPolicy(const std::string& policyName = P::POLICY_NAME)
Junxiao Shi52555b02016-11-25 21:39:06 +000044 {
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -040045 BOOST_ASSERT(!policyName.empty());
46 auto r = getRegistry().insert_or_assign(policyName, [] { return make_unique<P>(); });
47 BOOST_VERIFY(r.second);
Junxiao Shi52555b02016-11-25 21:39:06 +000048 }
49
Junxiao Shi7ee00fb2016-12-04 21:23:00 +000050 /** \return a cs::Policy identified by \p policyName,
51 * or nullptr if \p policyName is unknown
Junxiao Shi52555b02016-11-25 21:39:06 +000052 */
53 static unique_ptr<Policy>
Junxiao Shi7ee00fb2016-12-04 21:23:00 +000054 create(const std::string& policyName);
55
56 /** \return a list of available policy names
57 */
58 static std::set<std::string>
59 getPolicyNames();
Junxiao Shi52555b02016-11-25 21:39:06 +000060
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050061public:
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050062 virtual
Junxiao Shi2af9ca32016-08-25 21:51:02 +000063 ~Policy() = default;
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050064
65 const std::string&
Junxiao Shi5e4a02f2019-07-15 11:59:18 +000066 getName() const
67 {
68 return m_policyName;
69 }
70
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050071 /** \brief gets cs
72 */
73 Cs*
Junxiao Shi5e4a02f2019-07-15 11:59:18 +000074 getCs() const
75 {
76 return m_cs;
77 }
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050078
79 /** \brief sets cs
80 */
81 void
Junxiao Shi5e4a02f2019-07-15 11:59:18 +000082 setCs(Cs* cs)
83 {
84 m_cs = cs;
85 }
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050086
87 /** \brief gets hard limit (in number of entries)
88 */
89 size_t
Junxiao Shi5e4a02f2019-07-15 11:59:18 +000090 getLimit() const
91 {
92 return m_limit;
93 }
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050094
95 /** \brief sets hard limit (in number of entries)
96 * \post getLimit() == nMaxEntries
97 * \post cs.size() <= getLimit()
98 *
99 * The policy may evict entries if necessary.
100 */
101 void
102 setLimit(size_t nMaxEntries);
103
Junxiao Shi07f2e2f2019-07-22 09:10:06 -0600104public:
105 /** \brief a reference to an CS entry
106 * \note operator< of EntryRef compares the Data name enclosed in the Entry.
107 */
108 using EntryRef = Table::const_iterator;
109
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500110 /** \brief emits when an entry is being evicted
111 *
Junxiao Shi07f2e2f2019-07-22 09:10:06 -0600112 * A policy implementation should emit this signal to cause CS to erase an entry from its index.
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500113 * CS should connect to this signal and erase the entry upon signal emission.
114 */
Junxiao Shi07f2e2f2019-07-22 09:10:06 -0600115 signal::Signal<Policy, EntryRef> beforeEvict;
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500116
117 /** \brief invoked by CS after a new entry is inserted
118 * \post cs.size() <= getLimit()
119 *
120 * The policy may evict entries if necessary.
121 * During this process, \p i might be evicted.
122 */
123 void
Junxiao Shi07f2e2f2019-07-22 09:10:06 -0600124 afterInsert(EntryRef i);
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500125
126 /** \brief invoked by CS after an existing entry is refreshed by same Data
127 *
128 * The policy may witness this refresh to make better eviction decisions in the future.
129 */
130 void
Junxiao Shi07f2e2f2019-07-22 09:10:06 -0600131 afterRefresh(EntryRef i);
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500132
133 /** \brief invoked by CS before an entry is erased due to management command
134 * \warning CS must not invoke this method if an entry is erased due to eviction.
135 */
136 void
Junxiao Shi07f2e2f2019-07-22 09:10:06 -0600137 beforeErase(EntryRef i);
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500138
139 /** \brief invoked by CS before an entry is used to match a lookup
140 *
141 * The policy may witness this usage to make better eviction decisions in the future.
142 */
143 void
Junxiao Shi07f2e2f2019-07-22 09:10:06 -0600144 beforeUse(EntryRef i);
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500145
146protected:
147 /** \brief invoked after a new entry is created in CS
148 *
149 * When overridden in a subclass, a policy implementation should decide whether to accept \p i.
150 * If \p i is accepted, it should be inserted into a cleanup index.
151 * Otherwise, \p beforeEvict signal should be emitted with \p i to inform CS to erase the entry.
152 * A policy implementation may decide to evict other entries by emitting \p beforeEvict signal,
153 * in order to keep CS size under limit.
154 */
155 virtual void
Junxiao Shi07f2e2f2019-07-22 09:10:06 -0600156 doAfterInsert(EntryRef i) = 0;
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500157
158 /** \brief invoked after an existing entry is refreshed by same Data
159 *
160 * When overridden in a subclass, a policy implementation may witness this operation
161 * and adjust its cleanup index.
162 */
163 virtual void
Junxiao Shi07f2e2f2019-07-22 09:10:06 -0600164 doAfterRefresh(EntryRef i) = 0;
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500165
166 /** \brief invoked before an entry is erased due to management command
167 * \note This will not be invoked for an entry being evicted by policy.
168 *
169 * When overridden in a subclass, a policy implementation should erase \p i
170 * from its cleanup index without emitted \p afterErase signal.
171 */
172 virtual void
Junxiao Shi07f2e2f2019-07-22 09:10:06 -0600173 doBeforeErase(EntryRef i) = 0;
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500174
175 /** \brief invoked before an entry is used to match a lookup
176 *
177 * When overridden in a subclass, a policy implementation may witness this operation
178 * and adjust its cleanup index.
179 */
180 virtual void
Junxiao Shi07f2e2f2019-07-22 09:10:06 -0600181 doBeforeUse(EntryRef i) = 0;
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500182
183 /** \brief evicts zero or more entries
184 * \post CS size does not exceed hard limit
185 */
186 virtual void
187 evictEntries() = 0;
188
189protected:
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400190 explicit
191 Policy(std::string_view policyName);
192
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500193 DECLARE_SIGNAL_EMIT(beforeEvict)
194
Junxiao Shi52555b02016-11-25 21:39:06 +0000195private: // registry
Junxiao Shi07f2e2f2019-07-22 09:10:06 -0600196 using CreateFunc = std::function<unique_ptr<Policy>()>;
197 using Registry = std::map<std::string, CreateFunc>; // indexed by policy name
Junxiao Shi52555b02016-11-25 21:39:06 +0000198
199 static Registry&
200 getRegistry();
201
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500202private:
Davide Pesaventoa3a7a4e2022-05-29 16:06:22 -0400203 const std::string m_policyName;
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500204 size_t m_limit;
205 Cs* m_cs;
206};
207
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400208} // namespace nfd::cs
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500209
Junxiao Shi52555b02016-11-25 21:39:06 +0000210/** \brief registers a CS policy
211 * \param P a subclass of nfd::cs::Policy
212 */
213#define NFD_REGISTER_CS_POLICY(P) \
214static class NfdAuto ## P ## CsPolicyRegistrationClass \
215{ \
216public: \
217 NfdAuto ## P ## CsPolicyRegistrationClass() \
218 { \
219 ::nfd::cs::Policy::registerPolicy<P>(); \
220 } \
221} g_nfdAuto ## P ## CsPolicyRegistrationVariable
222
Junxiao Shi2af9ca32016-08-25 21:51:02 +0000223#endif // NFD_DAEMON_TABLE_CS_POLICY_HPP