blob: 4ecca80919cb9e195e818c74923cc6cc484707db [file] [log] [blame]
HYuana9b85752014-02-26 02:32:30 -06001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesaventoc0a5a392017-08-19 16:49:30 -04002/*
Junxiao Shi75306352018-02-01 21:59:44 +00003 * Copyright (c) 2014-2018, Regents of the University of California,
Alexander Afanasyev319f2c82015-01-07 14:56:53 -08004 * 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 Shiee5a4442014-07-27 17:13:43 -070024 */
HYuana9b85752014-02-26 02:32:30 -060025
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070026#ifndef NFD_DAEMON_TABLE_NAME_TREE_HPP
27#define NFD_DAEMON_TABLE_NAME_TREE_HPP
HYuana9b85752014-02-26 02:32:30 -060028
Junxiao Shi029401f2016-08-05 12:55:14 +000029#include "name-tree-iterator.hpp"
HYuana9b85752014-02-26 02:32:30 -060030
Junxiao Shi057d1492018-03-20 17:14:18 +000031#include "core/fib-max-depth.hpp"
32
HYuana9b85752014-02-26 02:32:30 -060033namespace nfd {
34namespace name_tree {
35
Junxiao Shie3cf2852016-08-09 03:50:56 +000036/** \brief a common index structure for FIB, PIT, StrategyChoice, and Measurements
37 */
HYuana9b85752014-02-26 02:32:30 -060038class NameTree : noncopyable
39{
40public:
41 explicit
Haowei Yuanf52dac72014-03-24 23:35:03 -050042 NameTree(size_t nBuckets = 1024);
HYuana9b85752014-02-26 02:32:30 -060043
Alexander Afanasyevb3033242014-08-04 11:09:05 -070044public: // information
Junxiao Shi057d1492018-03-20 17:14:18 +000045 /** \brief maximum depth of the name tree
Junxiao Shif54d0302017-09-07 18:16:38 +000046 *
Junxiao Shi057d1492018-03-20 17:14:18 +000047 * Calling \c NameTree::lookup with a name with many components would cause the creation of many
Junxiao Shif54d0302017-09-07 18:16:38 +000048 * NameTree entries, which could take very long time. This constant limits the maximum number of
49 * name components in the name of a NameTree entry. Thus, it limits the number of NameTree
50 * entries created from a long name, bounding the processing complexity.
Junxiao Shif54d0302017-09-07 18:16:38 +000051 */
Junxiao Shi75306352018-02-01 21:59:44 +000052 static constexpr size_t
Junxiao Shif54d0302017-09-07 18:16:38 +000053 getMaxDepth()
54 {
Junxiao Shi057d1492018-03-20 17:14:18 +000055 return FIB_MAX_DEPTH;
Junxiao Shif54d0302017-09-07 18:16:38 +000056 }
57
Junxiao Shie3cf2852016-08-09 03:50:56 +000058 /** \return number of name tree entries
HYuana9b85752014-02-26 02:32:30 -060059 */
60 size_t
Junxiao Shib660b4c2016-08-06 20:47:44 +000061 size() const
62 {
63 return m_ht.size();
64 }
HYuana9b85752014-02-26 02:32:30 -060065
Junxiao Shie3cf2852016-08-09 03:50:56 +000066 /** \return number of hashtable buckets
HYuana9b85752014-02-26 02:32:30 -060067 */
68 size_t
Junxiao Shib660b4c2016-08-06 20:47:44 +000069 getNBuckets() const
70 {
71 return m_ht.getNBuckets();
72 }
HYuana9b85752014-02-26 02:32:30 -060073
Junxiao Shif2420fc2016-08-11 13:18:21 +000074 /** \return name tree entry on which a table entry is attached,
75 * or nullptr if the table entry is detached
Junxiao Shib184e532016-05-26 18:09:57 +000076 */
Davide Pesaventoc0a5a392017-08-19 16:49:30 -040077 template<typename EntryT>
Junxiao Shi7f358432016-08-11 17:06:33 +000078 Entry*
Davide Pesaventoc0a5a392017-08-19 16:49:30 -040079 getEntry(const EntryT& tableEntry) const
Junxiao Shib660b4c2016-08-06 20:47:44 +000080 {
Junxiao Shi340d5532016-08-13 04:00:35 +000081 return Entry::get(tableEntry);
Junxiao Shib660b4c2016-08-06 20:47:44 +000082 }
Alexander Afanasyevb3033242014-08-04 11:09:05 -070083
84public: // mutation
Junxiao Shi057d1492018-03-20 17:14:18 +000085 /** \brief find or insert an entry by name
86 *
87 * This method seeks a name tree entry of name \c name.getPrefix(prefixLen).
88 * If the entry does not exist, it is created along with all ancestors.
89 * Existing iterators are unaffected during this operation.
90 *
91 * \warning \p prefixLen must not exceed \c name.size().
92 * \warning \p prefixLen must not exceed \c getMaxDepth().
HYuana9b85752014-02-26 02:32:30 -060093 */
Junxiao Shi7f358432016-08-11 17:06:33 +000094 Entry&
Junxiao Shi057d1492018-03-20 17:14:18 +000095 lookup(const Name& name, size_t prefixLen);
HYuana9b85752014-02-26 02:32:30 -060096
Junxiao Shi057d1492018-03-20 17:14:18 +000097 /** \brief equivalent to `lookup(name, name.size())`
98 */
99 Entry&
100 lookup(const Name& name)
101 {
102 return this->lookup(name, name.size());
103 }
104
105 /** \brief equivalent to `lookup(fibEntry.getPrefix())`
106 * \param fibEntry a FIB entry attached to this name tree, or \c Fib::s_emptyEntry
107 * \note This overload is more efficient than `lookup(const Name&)` in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +0000108 */
Junxiao Shi7f358432016-08-11 17:06:33 +0000109 Entry&
Junxiao Shif2420fc2016-08-11 13:18:21 +0000110 lookup(const fib::Entry& fibEntry);
Junxiao Shib184e532016-05-26 18:09:57 +0000111
Junxiao Shi057d1492018-03-20 17:14:18 +0000112 /** \brief equivalent to
113 * `lookup(pitEntry.getName(), std::min(pitEntry.getName().size(), getMaxDepth()))`
Junxiao Shif2420fc2016-08-11 13:18:21 +0000114 * \param pitEntry a PIT entry attached to this name tree
Junxiao Shi057d1492018-03-20 17:14:18 +0000115 * \note This overload is more efficient than `lookup(const Name&)` in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +0000116 */
Junxiao Shi7f358432016-08-11 17:06:33 +0000117 Entry&
Junxiao Shib184e532016-05-26 18:09:57 +0000118 lookup(const pit::Entry& pitEntry);
119
Junxiao Shi057d1492018-03-20 17:14:18 +0000120 /** \brief equivalent to `lookup(measurementsEntry.getName())`
Junxiao Shif2420fc2016-08-11 13:18:21 +0000121 * \param measurementsEntry a Measurements entry attached to this name tree
Junxiao Shi057d1492018-03-20 17:14:18 +0000122 * \note This overload is more efficient than `lookup(const Name&)` in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +0000123 */
Junxiao Shi7f358432016-08-11 17:06:33 +0000124 Entry&
Junxiao Shif2420fc2016-08-11 13:18:21 +0000125 lookup(const measurements::Entry& measurementsEntry);
Junxiao Shib184e532016-05-26 18:09:57 +0000126
Junxiao Shi057d1492018-03-20 17:14:18 +0000127 /** \brief equivalent to `lookup(strategyChoiceEntry.getPrefix())`
Junxiao Shif2420fc2016-08-11 13:18:21 +0000128 * \param strategyChoiceEntry a StrategyChoice entry attached to this name tree
Junxiao Shi057d1492018-03-20 17:14:18 +0000129 * \note This overload is more efficient than `lookup(const Name&)` in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +0000130 */
Junxiao Shi7f358432016-08-11 17:06:33 +0000131 Entry&
Junxiao Shif2420fc2016-08-11 13:18:21 +0000132 lookup(const strategy_choice::Entry& strategyChoiceEntry);
Junxiao Shib184e532016-05-26 18:09:57 +0000133
Junxiao Shie3cf2852016-08-09 03:50:56 +0000134 /** \brief delete the entry if it is empty
135 * \param entry a valid entry
Junxiao Shie7258ff2016-08-12 23:55:47 +0000136 * \param canEraseAncestors whether ancestors should be deleted if they become empty
Junxiao Shie3cf2852016-08-09 03:50:56 +0000137 * \return number of deleted entries
138 * \sa Entry::isEmpty()
Junxiao Shi057d1492018-03-20 17:14:18 +0000139 * \post If the entry is empty, it's deleted. If \p canEraseAncestors is true,
Junxiao Shie7258ff2016-08-12 23:55:47 +0000140 * ancestors of the entry are also deleted if they become empty.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000141 * \note This function must be called after detaching a table entry from a name tree entry,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000142 * \note Existing iterators, except those pointing to deleted entries, are unaffected.
HYuana9b85752014-02-26 02:32:30 -0600143 */
Junxiao Shib660b4c2016-08-06 20:47:44 +0000144 size_t
Junxiao Shie7258ff2016-08-12 23:55:47 +0000145 eraseIfEmpty(Entry* entry, bool canEraseAncestors = true);
HYuana9b85752014-02-26 02:32:30 -0600146
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700147public: // matching
Junxiao Shie3cf2852016-08-09 03:50:56 +0000148 /** \brief exact match lookup
Junxiao Shi057d1492018-03-20 17:14:18 +0000149 * \return entry with \c name.getPrefix(prefixLen), or nullptr if it does not exist
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700150 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000151 Entry*
Junxiao Shi042a3312017-09-15 02:51:20 +0000152 findExactMatch(const Name& name, size_t prefixLen = std::numeric_limits<size_t>::max()) const;
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700153
Junxiao Shie3cf2852016-08-09 03:50:56 +0000154 /** \brief longest prefix matching
155 * \return entry whose name is a prefix of \p name and passes \p entrySelector,
156 * where no other entry with a longer name satisfies those requirements;
157 * or nullptr if no entry satisfying those requirements exists
HYuana9b85752014-02-26 02:32:30 -0600158 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000159 Entry*
Junxiao Shib660b4c2016-08-06 20:47:44 +0000160 findLongestPrefixMatch(const Name& name,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000161 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600162
Junxiao Shi057d1492018-03-20 17:14:18 +0000163 /** \brief equivalent to `findLongestPrefixMatch(entry.getName(), entrySelector)`
Junxiao Shif2420fc2016-08-11 13:18:21 +0000164 * \note This overload is more efficient than
Junxiao Shi057d1492018-03-20 17:14:18 +0000165 * `findLongestPrefixMatch(const Name&, const EntrySelector&)` in common cases.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000166 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000167 Entry*
168 findLongestPrefixMatch(const Entry& entry,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000169 const EntrySelector& entrySelector = AnyEntry()) const;
HangZhangcb4fc832014-03-11 16:57:11 +0800170
Junxiao Shi057d1492018-03-20 17:14:18 +0000171 /** \brief equivalent to `findLongestPrefixMatch(getEntry(tableEntry)->getName(), entrySelector)`
172 * \tparam EntryT \c fib::Entry or \c measurements::Entry or \c strategy_choice::Entry
Junxiao Shif2420fc2016-08-11 13:18:21 +0000173 * \note This overload is more efficient than
Junxiao Shi057d1492018-03-20 17:14:18 +0000174 * `findLongestPrefixMatch(const Name&, const EntrySelector&)` in common cases.
175 * \warning Undefined behavior may occur if \p tableEntry is not attached to this name tree.
Junxiao Shidd8f6612016-08-12 15:42:52 +0000176 */
Davide Pesaventoc0a5a392017-08-19 16:49:30 -0400177 template<typename EntryT>
Junxiao Shidd8f6612016-08-12 15:42:52 +0000178 Entry*
Davide Pesaventoc0a5a392017-08-19 16:49:30 -0400179 findLongestPrefixMatch(const EntryT& tableEntry,
180 const EntrySelector& entrySelector = AnyEntry()) const
181 {
182 const Entry* nte = this->getEntry(tableEntry);
183 BOOST_ASSERT(nte != nullptr);
184 return this->findLongestPrefixMatch(*nte, entrySelector);
185 }
Junxiao Shidd8f6612016-08-12 15:42:52 +0000186
Junxiao Shi057d1492018-03-20 17:14:18 +0000187 /** \brief equivalent to `findLongestPrefixMatch(pitEntry.getName(), entrySelector)`
Junxiao Shidd8f6612016-08-12 15:42:52 +0000188 * \note This overload is more efficient than
Junxiao Shi057d1492018-03-20 17:14:18 +0000189 * `findLongestPrefixMatch(const Name&, const EntrySelector&)` in common cases.
190 * \warning Undefined behavior may occur if \p pitEntry is not attached to this name tree.
Junxiao Shi4370fde2016-02-24 12:20:46 -0700191 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000192 Entry*
Junxiao Shif2420fc2016-08-11 13:18:21 +0000193 findLongestPrefixMatch(const pit::Entry& pitEntry,
194 const EntrySelector& entrySelector = AnyEntry()) const;
Junxiao Shi4370fde2016-02-24 12:20:46 -0700195
Junxiao Shie3cf2852016-08-09 03:50:56 +0000196 /** \brief all-prefixes match lookup
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000197 * \return a range where every entry has a name that is a prefix of \p name ,
Junxiao Shie3cf2852016-08-09 03:50:56 +0000198 * and matches \p entrySelector.
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700199 *
200 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000201 * \code
202 * Name name("/A/B/C");
203 * auto&& allMatches = nt.findAllMatches(name);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000204 * for (const Entry& nte : allMatches) {
Junxiao Shie3cf2852016-08-09 03:50:56 +0000205 * BOOST_ASSERT(nte.getName().isPrefixOf(name));
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700206 * ...
207 * }
208 * \endcode
Junxiao Shib30863e2016-08-15 21:32:01 +0000209 * \note Iteration order is implementation-defined.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000210 * \warning If a name tree entry whose name is a prefix of \p name is inserted
211 * during the enumeration, it may or may not be visited.
212 * If a name tree entry whose name is a prefix of \p name is deleted
213 * during the enumeration, undefined behavior may occur.
HYuana9b85752014-02-26 02:32:30 -0600214 */
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000215 Range
Junxiao Shie3cf2852016-08-09 03:50:56 +0000216 findAllMatches(const Name& name,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000217 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600218
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700219public: // enumeration
Junxiao Shif54d0302017-09-07 18:16:38 +0000220 using const_iterator = Iterator;
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000221
Junxiao Shie3cf2852016-08-09 03:50:56 +0000222 /** \brief enumerate all entries
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000223 * \return a range where every entry matches \p entrySelector
Junxiao Shi60607c72014-11-26 22:40:36 -0700224 *
225 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000226 * \code
Junxiao Shi60607c72014-11-26 22:40:36 -0700227 * auto&& enumerable = nt.fullEnumerate();
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000228 * for (const Entry& nte : enumerable) {
Junxiao Shi60607c72014-11-26 22:40:36 -0700229 * ...
230 * }
231 * \endcode
Junxiao Shib30863e2016-08-15 21:32:01 +0000232 * \note Iteration order is implementation-defined.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000233 * \warning If a name tree entry is inserted or deleted during the enumeration,
234 * it may cause the enumeration to skip entries or visit some entries twice.
HYuana9b85752014-02-26 02:32:30 -0600235 */
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000236 Range
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000237 fullEnumerate(const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600238
Junxiao Shie3cf2852016-08-09 03:50:56 +0000239 /** \brief enumerate all entries under a prefix
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000240 * \return a range where every entry has a name that starts with \p prefix,
Junxiao Shie3cf2852016-08-09 03:50:56 +0000241 * and matches \p entrySubTreeSelector.
Junxiao Shi60607c72014-11-26 22:40:36 -0700242 *
243 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000244 * \code
245 * Name name("/A/B/C");
246 * auto&& enumerable = nt.partialEnumerate(name);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000247 * for (const Entry& nte : enumerable) {
Junxiao Shie3cf2852016-08-09 03:50:56 +0000248 * BOOST_ASSERT(name.isPrefixOf(nte.getName()));
Junxiao Shi60607c72014-11-26 22:40:36 -0700249 * ...
250 * }
251 * \endcode
Junxiao Shib30863e2016-08-15 21:32:01 +0000252 * \note Iteration order is implementation-defined.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000253 * \warning If a name tree entry under \p prefix is inserted or deleted during the enumeration,
254 * it may cause the enumeration to skip entries or visit some entries twice.
Junxiao Shi60607c72014-11-26 22:40:36 -0700255 */
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000256 Range
Junxiao Shi40631842014-03-01 13:52:37 -0700257 partialEnumerate(const Name& prefix,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000258 const EntrySubTreeSelector& entrySubTreeSelector = AnyEntrySubTree()) const;
HYuana9b85752014-02-26 02:32:30 -0600259
Junxiao Shib30863e2016-08-15 21:32:01 +0000260 /** \return an iterator to the beginning
Junxiao Shie3cf2852016-08-09 03:50:56 +0000261 * \sa fullEnumerate
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800262 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600263 const_iterator
Junxiao Shib660b4c2016-08-06 20:47:44 +0000264 begin() const
265 {
266 return fullEnumerate().begin();
267 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600268
Junxiao Shib30863e2016-08-15 21:32:01 +0000269 /** \return an iterator to the end
270 * \sa begin()
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800271 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600272 const_iterator
Junxiao Shib660b4c2016-08-06 20:47:44 +0000273 end() const
274 {
275 return Iterator();
276 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600277
HYuana9b85752014-02-26 02:32:30 -0600278private:
Junxiao Shib660b4c2016-08-06 20:47:44 +0000279 Hashtable m_ht;
Junxiao Shib184e532016-05-26 18:09:57 +0000280
Junxiao Shib660b4c2016-08-06 20:47:44 +0000281 friend class EnumerationImpl;
HYuana9b85752014-02-26 02:32:30 -0600282};
283
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000284} // namespace name_tree
285
286using name_tree::NameTree;
287
HYuana9b85752014-02-26 02:32:30 -0600288} // namespace nfd
289
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700290#endif // NFD_DAEMON_TABLE_NAME_TREE_HPP