blob: 16e28a5e600183d12bc36db81bd5971758929e6a [file] [log] [blame]
Junxiao Shi0fcb41e2014-01-24 10:29:43 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento84c65c02017-07-05 18:40:34 +00002/*
Davide Pesavento3dade002019-03-19 11:29:56 -06003 * Copyright (c) 2014-2019, Regents of the University of California,
Junxiao Shi5640ec82015-01-07 21:51:19 -07004 * 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.
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -080010 *
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -070011 * 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 Shia9388182014-12-13 23:16:09 -070024 */
25
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070026#ifndef NFD_DAEMON_TABLE_CS_HPP
27#define NFD_DAEMON_TABLE_CS_HPP
Alexander Afanasyevb927a3a2014-01-24 10:41:47 -080028
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050029#include "cs-policy.hpp"
30#include "cs-internal.hpp"
Junxiao Shifc206962015-01-16 11:12:22 -070031#include "cs-entry-impl.hpp"
Davide Pesavento3dade002019-03-19 11:29:56 -060032
Junxiao Shifc206962015-01-16 11:12:22 -070033#include <boost/iterator/transform_iterator.hpp>
Ilya Moiseenko96b80bb2014-04-05 20:53:27 -040034
Alexander Afanasyev18bbf812014-01-29 01:40:23 -080035namespace nfd {
Junxiao Shia9388182014-12-13 23:16:09 -070036namespace cs {
Junxiao Shi0fcb41e2014-01-24 10:29:43 -070037
Junxiao Shi30c37ab2018-04-09 14:26:47 +000038/** \brief implements the Content Store
39 *
40 * This Content Store implementation consists of a Table and a replacement policy.
41 *
42 * The Table is a container ( \c std::set ) sorted by full Names of stored Data packets.
43 * Data packets are wrapped in Entry objects. Each Entry contains the Data packet itself,
44 * and a few additional attributes such as when the Data becomes non-fresh.
45 *
46 * The replacement policy is implemented in a subclass of \c Policy.
Junxiao Shi0fcb41e2014-01-24 10:29:43 -070047 */
Alexander Afanasyevb927a3a2014-01-24 10:41:47 -080048class Cs : noncopyable
Junxiao Shi0fcb41e2014-01-24 10:29:43 -070049{
50public:
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -080051 explicit
Junxiao Shib4a5acd2016-12-07 19:59:18 +000052 Cs(size_t nMaxPackets = 10);
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -080053
Junxiao Shi0fcb41e2014-01-24 10:29:43 -070054 /** \brief inserts a Data packet
Junxiao Shi0fcb41e2014-01-24 10:29:43 -070055 */
Minsheng Zhangffe8bbb2016-03-10 13:40:37 -070056 void
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -080057 insert(const Data& data, bool isUnsolicited = false);
58
Junxiao Shi30c37ab2018-04-09 14:26:47 +000059 using AfterEraseCallback = std::function<void(size_t nErased)>;
60
61 /** \brief asynchronously erases entries under \p prefix
62 * \param prefix name prefix of entries
63 * \param limit max number of entries to erase
64 * \param cb callback to receive the actual number of erased entries; it may be empty;
65 * it may be invoked either before or after erase() returns
66 */
67 void
68 erase(const Name& prefix, size_t limit, const AfterEraseCallback& cb);
69
70 using HitCallback = std::function<void(const Interest&, const Data&)>;
71 using MissCallback = std::function<void(const Interest&)>;
mzhang4eab72492015-02-25 11:16:09 -060072
Junxiao Shia9388182014-12-13 23:16:09 -070073 /** \brief finds the best matching Data packet
mzhang4eab72492015-02-25 11:16:09 -060074 * \param interest the Interest for lookup
75 * \param hitCallback a callback if a match is found; must not be empty
76 * \param missCallback a callback if there's no match; must not be empty
77 * \note A lookup invokes either callback exactly once.
78 * The callback may be invoked either before or after find() returns
Junxiao Shi0fcb41e2014-01-24 10:29:43 -070079 */
mzhang4eab72492015-02-25 11:16:09 -060080 void
81 find(const Interest& interest,
82 const HitCallback& hitCallback,
83 const MissCallback& missCallback) const;
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -080084
Junxiao Shi3d2049f2018-01-26 23:46:06 +000085 /** \brief get number of stored packets
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -080086 */
87 size_t
Junxiao Shifc206962015-01-16 11:12:22 -070088 size() const
89 {
90 return m_table.size();
91 }
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -080092
Junxiao Shi3d2049f2018-01-26 23:46:06 +000093public: // configuration
94 /** \brief get capacity (in number of packets)
95 */
96 size_t
97 getLimit() const
98 {
99 return m_policy->getLimit();
100 }
101
102 /** \brief change capacity (in number of packets)
103 */
Junxiao Shia9388182014-12-13 23:16:09 -0700104 void
Junxiao Shi3d2049f2018-01-26 23:46:06 +0000105 setLimit(size_t nMaxPackets)
106 {
107 return m_policy->setLimit(nMaxPackets);
108 }
109
110 /** \brief get replacement policy
111 */
112 Policy*
113 getPolicy() const
114 {
115 return m_policy.get();
116 }
117
118 /** \brief change replacement policy
119 * \pre size() == 0
120 */
121 void
122 setPolicy(unique_ptr<Policy> policy);
123
124 /** \brief get CS_ENABLE_ADMIT flag
125 * \sa https://redmine.named-data.net/projects/nfd/wiki/CsMgmt#Update-config
126 */
127 bool
128 shouldAdmit() const
129 {
130 return m_shouldAdmit;
131 }
132
133 /** \brief set CS_ENABLE_ADMIT flag
134 * \sa https://redmine.named-data.net/projects/nfd/wiki/CsMgmt#Update-config
135 */
136 void
137 enableAdmit(bool shouldAdmit);
138
139 /** \brief get CS_ENABLE_SERVE flag
140 * \sa https://redmine.named-data.net/projects/nfd/wiki/CsMgmt#Update-config
141 */
142 bool
143 shouldServe() const
144 {
145 return m_shouldServe;
146 }
147
148 /** \brief set CS_ENABLE_SERVE flag
149 * \sa https://redmine.named-data.net/projects/nfd/wiki/CsMgmt#Update-config
150 */
151 void
152 enableServe(bool shouldServe);
Junxiao Shia9388182014-12-13 23:16:09 -0700153
Junxiao Shifc206962015-01-16 11:12:22 -0700154public: // enumeration
155 struct EntryFromEntryImpl
156 {
157 typedef const Entry& result_type;
158
159 const Entry&
160 operator()(const EntryImpl& entry) const
161 {
162 return entry;
163 }
Junxiao Shia9388182014-12-13 23:16:09 -0700164 };
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800165
Junxiao Shifc206962015-01-16 11:12:22 -0700166 /** \brief ContentStore iterator (public API)
167 */
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500168 typedef boost::transform_iterator<EntryFromEntryImpl, iterator, const Entry&> const_iterator;
Junxiao Shifc206962015-01-16 11:12:22 -0700169
170 const_iterator
171 begin() const
172 {
173 return boost::make_transform_iterator(m_table.begin(), EntryFromEntryImpl());
174 }
175
176 const_iterator
177 end() const
178 {
179 return boost::make_transform_iterator(m_table.end(), EntryFromEntryImpl());
180 }
181
182private: // find
Junxiao Shi5640ec82015-01-07 21:51:19 -0700183 /** \brief find leftmost match in [first,last)
184 * \return the leftmost match, or last if not found
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800185 */
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500186 iterator
187 findLeftmost(const Interest& interest, iterator left, iterator right) const;
Junxiao Shi5640ec82015-01-07 21:51:19 -0700188
189 /** \brief find rightmost match in [first,last)
190 * \return the rightmost match, or last if not found
191 */
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500192 iterator
193 findRightmost(const Interest& interest, iterator first, iterator last) const;
Junxiao Shi5640ec82015-01-07 21:51:19 -0700194
195 /** \brief find rightmost match among entries with exact Names in [first,last)
196 * \return the rightmost match, or last if not found
197 */
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500198 iterator
199 findRightmostAmongExact(const Interest& interest, iterator first, iterator last) const;
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800200
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800201 void
Junxiao Shi52555b02016-11-25 21:39:06 +0000202 setPolicyImpl(unique_ptr<Policy> policy);
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800203
Junxiao Shi3d2049f2018-01-26 23:46:06 +0000204PUBLIC_WITH_TESTS_ELSE_PRIVATE:
205 void
206 dump();
207
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800208private:
Junxiao Shia9388182014-12-13 23:16:09 -0700209 Table m_table;
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500210 unique_ptr<Policy> m_policy;
Junxiao Shi3d2049f2018-01-26 23:46:06 +0000211 signal::ScopedConnection m_beforeEvictConnection;
212
Davide Pesavento3dade002019-03-19 11:29:56 -0600213 bool m_shouldAdmit = true; ///< if false, no Data will be admitted
214 bool m_shouldServe = true; ///< if false, all lookups will miss
Junxiao Shi0fcb41e2014-01-24 10:29:43 -0700215};
216
Junxiao Shia9388182014-12-13 23:16:09 -0700217} // namespace cs
218
219using cs::Cs;
220
Alexander Afanasyev18bbf812014-01-29 01:40:23 -0800221} // namespace nfd
Alexander Afanasyevb927a3a2014-01-24 10:41:47 -0800222
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700223#endif // NFD_DAEMON_TABLE_CS_HPP