blob: 04e504e0224e54929cd3f27d200ef52e4d6ce5bc [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/*
3 * Copyright (c) 2014-2017, 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
31namespace nfd {
32namespace name_tree {
33
Junxiao Shie3cf2852016-08-09 03:50:56 +000034/** \brief a common index structure for FIB, PIT, StrategyChoice, and Measurements
35 */
HYuana9b85752014-02-26 02:32:30 -060036class NameTree : noncopyable
37{
38public:
39 explicit
Haowei Yuanf52dac72014-03-24 23:35:03 -050040 NameTree(size_t nBuckets = 1024);
HYuana9b85752014-02-26 02:32:30 -060041
Alexander Afanasyevb3033242014-08-04 11:09:05 -070042public: // information
Junxiao Shif54d0302017-09-07 18:16:38 +000043 /** \brief Maximum depth of the name tree.
44 *
45 * Calling NameTree::lookup with a name with many components would cause the creation of many
46 * NameTree entries, which could take very long time. This constant limits the maximum number of
47 * name components in the name of a NameTree entry. Thus, it limits the number of NameTree
48 * entries created from a long name, bounding the processing complexity.
49 *
50 * This constant is currently advisory. It is enforced in NameTree::lookup only if
51 * \p enforceMaxDepth is set to true. This will become mandatory later.
52 */
53 static size_t
54 getMaxDepth()
55 {
56 return 32;
57 }
58
Junxiao Shie3cf2852016-08-09 03:50:56 +000059 /** \return number of name tree entries
HYuana9b85752014-02-26 02:32:30 -060060 */
61 size_t
Junxiao Shib660b4c2016-08-06 20:47:44 +000062 size() const
63 {
64 return m_ht.size();
65 }
HYuana9b85752014-02-26 02:32:30 -060066
Junxiao Shie3cf2852016-08-09 03:50:56 +000067 /** \return number of hashtable buckets
HYuana9b85752014-02-26 02:32:30 -060068 */
69 size_t
Junxiao Shib660b4c2016-08-06 20:47:44 +000070 getNBuckets() const
71 {
72 return m_ht.getNBuckets();
73 }
HYuana9b85752014-02-26 02:32:30 -060074
Junxiao Shif2420fc2016-08-11 13:18:21 +000075 /** \return name tree entry on which a table entry is attached,
76 * or nullptr if the table entry is detached
Junxiao Shib184e532016-05-26 18:09:57 +000077 */
Davide Pesaventoc0a5a392017-08-19 16:49:30 -040078 template<typename EntryT>
Junxiao Shi7f358432016-08-11 17:06:33 +000079 Entry*
Davide Pesaventoc0a5a392017-08-19 16:49:30 -040080 getEntry(const EntryT& tableEntry) const
Junxiao Shib660b4c2016-08-06 20:47:44 +000081 {
Junxiao Shi340d5532016-08-13 04:00:35 +000082 return Entry::get(tableEntry);
Junxiao Shib660b4c2016-08-06 20:47:44 +000083 }
Alexander Afanasyevb3033242014-08-04 11:09:05 -070084
85public: // mutation
Junxiao Shie3cf2852016-08-09 03:50:56 +000086 /** \brief find or insert an entry with specified name
87 * \param name a name prefix
Junxiao Shif54d0302017-09-07 18:16:38 +000088 * \param enforceMaxDepth if true, use \p name.getPrefix(getMaxDepth()) in place of \p name
Junxiao Shie3cf2852016-08-09 03:50:56 +000089 * \return an entry with \p name
90 * \post an entry with \p name and all ancestors are created
Junxiao Shi2570f3e2016-07-27 02:48:29 +000091 * \note Existing iterators are unaffected.
HYuana9b85752014-02-26 02:32:30 -060092 */
Junxiao Shi7f358432016-08-11 17:06:33 +000093 Entry&
Junxiao Shif54d0302017-09-07 18:16:38 +000094 lookup(const Name& name, bool enforceMaxDepth = false);
HYuana9b85752014-02-26 02:32:30 -060095
Junxiao Shie3cf2852016-08-09 03:50:56 +000096 /** \brief equivalent to .lookup(fibEntry.getPrefix())
Junxiao Shif2420fc2016-08-11 13:18:21 +000097 * \param fibEntry a FIB entry attached to this name tree, or Fib::s_emptyEntry
Junxiao Shie3cf2852016-08-09 03:50:56 +000098 * \note This overload is more efficient than .lookup(const Name&) in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +000099 */
Junxiao Shi7f358432016-08-11 17:06:33 +0000100 Entry&
Junxiao Shif2420fc2016-08-11 13:18:21 +0000101 lookup(const fib::Entry& fibEntry);
Junxiao Shib184e532016-05-26 18:09:57 +0000102
Junxiao Shie3cf2852016-08-09 03:50:56 +0000103 /** \brief equivalent to .lookup(pitEntry.getName()).
Junxiao Shif2420fc2016-08-11 13:18:21 +0000104 * \param pitEntry a PIT entry attached to this name tree
Junxiao Shie3cf2852016-08-09 03:50:56 +0000105 * \note This overload is more efficient than .lookup(const Name&) in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +0000106 */
Junxiao Shi7f358432016-08-11 17:06:33 +0000107 Entry&
Junxiao Shib184e532016-05-26 18:09:57 +0000108 lookup(const pit::Entry& pitEntry);
109
Junxiao Shie3cf2852016-08-09 03:50:56 +0000110 /** \brief equivalent to .lookup(measurementsEntry.getName())
Junxiao Shif2420fc2016-08-11 13:18:21 +0000111 * \param measurementsEntry a Measurements entry attached to this name tree
Junxiao Shie3cf2852016-08-09 03:50:56 +0000112 * \note This overload is more efficient than .lookup(const Name&) in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +0000113 */
Junxiao Shi7f358432016-08-11 17:06:33 +0000114 Entry&
Junxiao Shif2420fc2016-08-11 13:18:21 +0000115 lookup(const measurements::Entry& measurementsEntry);
Junxiao Shib184e532016-05-26 18:09:57 +0000116
Junxiao Shidd8f6612016-08-12 15:42:52 +0000117 /** \brief equivalent to .lookup(strategyChoiceEntry.getPrefix())
Junxiao Shif2420fc2016-08-11 13:18:21 +0000118 * \param strategyChoiceEntry a StrategyChoice entry attached to this name tree
Junxiao Shie3cf2852016-08-09 03:50:56 +0000119 * \note This overload is more efficient than .lookup(const Name&) in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +0000120 */
Junxiao Shi7f358432016-08-11 17:06:33 +0000121 Entry&
Junxiao Shif2420fc2016-08-11 13:18:21 +0000122 lookup(const strategy_choice::Entry& strategyChoiceEntry);
Junxiao Shib184e532016-05-26 18:09:57 +0000123
Junxiao Shie3cf2852016-08-09 03:50:56 +0000124 /** \brief delete the entry if it is empty
125 * \param entry a valid entry
Junxiao Shie7258ff2016-08-12 23:55:47 +0000126 * \param canEraseAncestors whether ancestors should be deleted if they become empty
Junxiao Shie3cf2852016-08-09 03:50:56 +0000127 * \return number of deleted entries
128 * \sa Entry::isEmpty()
Junxiao Shie7258ff2016-08-12 23:55:47 +0000129 * \post If the entry is empty, it's deleted. If canEraseAncestors is true,
130 * ancestors of the entry are also deleted if they become empty.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000131 * \note This function must be called after detaching a table entry from a name tree entry,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000132 * \note Existing iterators, except those pointing to deleted entries, are unaffected.
HYuana9b85752014-02-26 02:32:30 -0600133 */
Junxiao Shib660b4c2016-08-06 20:47:44 +0000134 size_t
Junxiao Shie7258ff2016-08-12 23:55:47 +0000135 eraseIfEmpty(Entry* entry, bool canEraseAncestors = true);
HYuana9b85752014-02-26 02:32:30 -0600136
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700137public: // matching
Junxiao Shie3cf2852016-08-09 03:50:56 +0000138 /** \brief exact match lookup
Junxiao Shi042a3312017-09-15 02:51:20 +0000139 * \return entry with \p name.getPrefix(prefixLen), or nullptr if it does not exist
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700140 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000141 Entry*
Junxiao Shi042a3312017-09-15 02:51:20 +0000142 findExactMatch(const Name& name, size_t prefixLen = std::numeric_limits<size_t>::max()) const;
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700143
Junxiao Shie3cf2852016-08-09 03:50:56 +0000144 /** \brief longest prefix matching
145 * \return entry whose name is a prefix of \p name and passes \p entrySelector,
146 * where no other entry with a longer name satisfies those requirements;
147 * or nullptr if no entry satisfying those requirements exists
HYuana9b85752014-02-26 02:32:30 -0600148 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000149 Entry*
Junxiao Shib660b4c2016-08-06 20:47:44 +0000150 findLongestPrefixMatch(const Name& name,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000151 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600152
Junxiao Shi811c0102016-08-10 04:12:45 +0000153 /** \brief equivalent to .findLongestPrefixMatch(entry.getName(), entrySelector)
Junxiao Shif2420fc2016-08-11 13:18:21 +0000154 * \note This overload is more efficient than
155 * .findLongestPrefixMatch(const Name&, const EntrySelector&) in common cases.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000156 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000157 Entry*
158 findLongestPrefixMatch(const Entry& entry,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000159 const EntrySelector& entrySelector = AnyEntry()) const;
HangZhangcb4fc832014-03-11 16:57:11 +0800160
Junxiao Shidd8f6612016-08-12 15:42:52 +0000161 /** \brief equivalent to .findLongestPrefixMatch(getEntry(tableEntry)->getName(), entrySelector)
Davide Pesaventoc0a5a392017-08-19 16:49:30 -0400162 * \tparam EntryT fib::Entry or measurements::Entry or strategy_choice::Entry
Junxiao Shif2420fc2016-08-11 13:18:21 +0000163 * \note This overload is more efficient than
164 * .findLongestPrefixMatch(const Name&, const EntrySelector&) in common cases.
Junxiao Shidd8f6612016-08-12 15:42:52 +0000165 * \warning Undefined behavior may occur if tableEntry is not attached to this name tree.
166 */
Davide Pesaventoc0a5a392017-08-19 16:49:30 -0400167 template<typename EntryT>
Junxiao Shidd8f6612016-08-12 15:42:52 +0000168 Entry*
Davide Pesaventoc0a5a392017-08-19 16:49:30 -0400169 findLongestPrefixMatch(const EntryT& tableEntry,
170 const EntrySelector& entrySelector = AnyEntry()) const
171 {
172 const Entry* nte = this->getEntry(tableEntry);
173 BOOST_ASSERT(nte != nullptr);
174 return this->findLongestPrefixMatch(*nte, entrySelector);
175 }
Junxiao Shidd8f6612016-08-12 15:42:52 +0000176
177 /** \brief equivalent to .findLongestPrefixMatch(pitEntry.getName(), entrySelector)
178 * \note This overload is more efficient than
179 * .findLongestPrefixMatch(const Name&, const EntrySelector&) in common cases.
180 * \warning Undefined behavior may occur if pitEntry is not attached to this name tree.
Junxiao Shi4370fde2016-02-24 12:20:46 -0700181 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000182 Entry*
Junxiao Shif2420fc2016-08-11 13:18:21 +0000183 findLongestPrefixMatch(const pit::Entry& pitEntry,
184 const EntrySelector& entrySelector = AnyEntry()) const;
Junxiao Shi4370fde2016-02-24 12:20:46 -0700185
Junxiao Shie3cf2852016-08-09 03:50:56 +0000186 /** \brief all-prefixes match lookup
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000187 * \return a range where every entry has a name that is a prefix of \p name ,
Junxiao Shie3cf2852016-08-09 03:50:56 +0000188 * and matches \p entrySelector.
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700189 *
190 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000191 * \code
192 * Name name("/A/B/C");
193 * auto&& allMatches = nt.findAllMatches(name);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000194 * for (const Entry& nte : allMatches) {
Junxiao Shie3cf2852016-08-09 03:50:56 +0000195 * BOOST_ASSERT(nte.getName().isPrefixOf(name));
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700196 * ...
197 * }
198 * \endcode
Junxiao Shib30863e2016-08-15 21:32:01 +0000199 * \note Iteration order is implementation-defined.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000200 * \warning If a name tree entry whose name is a prefix of \p name is inserted
201 * during the enumeration, it may or may not be visited.
202 * If a name tree entry whose name is a prefix of \p name is deleted
203 * during the enumeration, undefined behavior may occur.
HYuana9b85752014-02-26 02:32:30 -0600204 */
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000205 Range
Junxiao Shie3cf2852016-08-09 03:50:56 +0000206 findAllMatches(const Name& name,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000207 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600208
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700209public: // enumeration
Junxiao Shif54d0302017-09-07 18:16:38 +0000210 using const_iterator = Iterator;
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000211
Junxiao Shie3cf2852016-08-09 03:50:56 +0000212 /** \brief enumerate all entries
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000213 * \return a range where every entry matches \p entrySelector
Junxiao Shi60607c72014-11-26 22:40:36 -0700214 *
215 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000216 * \code
Junxiao Shi60607c72014-11-26 22:40:36 -0700217 * auto&& enumerable = nt.fullEnumerate();
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000218 * for (const Entry& nte : enumerable) {
Junxiao Shi60607c72014-11-26 22:40:36 -0700219 * ...
220 * }
221 * \endcode
Junxiao Shib30863e2016-08-15 21:32:01 +0000222 * \note Iteration order is implementation-defined.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000223 * \warning If a name tree entry is inserted or deleted during the enumeration,
224 * it may cause the enumeration to skip entries or visit some entries twice.
HYuana9b85752014-02-26 02:32:30 -0600225 */
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000226 Range
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000227 fullEnumerate(const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600228
Junxiao Shie3cf2852016-08-09 03:50:56 +0000229 /** \brief enumerate all entries under a prefix
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000230 * \return a range where every entry has a name that starts with \p prefix,
Junxiao Shie3cf2852016-08-09 03:50:56 +0000231 * and matches \p entrySubTreeSelector.
Junxiao Shi60607c72014-11-26 22:40:36 -0700232 *
233 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000234 * \code
235 * Name name("/A/B/C");
236 * auto&& enumerable = nt.partialEnumerate(name);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000237 * for (const Entry& nte : enumerable) {
Junxiao Shie3cf2852016-08-09 03:50:56 +0000238 * BOOST_ASSERT(name.isPrefixOf(nte.getName()));
Junxiao Shi60607c72014-11-26 22:40:36 -0700239 * ...
240 * }
241 * \endcode
Junxiao Shib30863e2016-08-15 21:32:01 +0000242 * \note Iteration order is implementation-defined.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000243 * \warning If a name tree entry under \p prefix is inserted or deleted during the enumeration,
244 * it may cause the enumeration to skip entries or visit some entries twice.
Junxiao Shi60607c72014-11-26 22:40:36 -0700245 */
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000246 Range
Junxiao Shi40631842014-03-01 13:52:37 -0700247 partialEnumerate(const Name& prefix,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000248 const EntrySubTreeSelector& entrySubTreeSelector = AnyEntrySubTree()) const;
HYuana9b85752014-02-26 02:32:30 -0600249
Junxiao Shib30863e2016-08-15 21:32:01 +0000250 /** \return an iterator to the beginning
Junxiao Shie3cf2852016-08-09 03:50:56 +0000251 * \sa fullEnumerate
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800252 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600253 const_iterator
Junxiao Shib660b4c2016-08-06 20:47:44 +0000254 begin() const
255 {
256 return fullEnumerate().begin();
257 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600258
Junxiao Shib30863e2016-08-15 21:32:01 +0000259 /** \return an iterator to the end
260 * \sa begin()
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800261 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600262 const_iterator
Junxiao Shib660b4c2016-08-06 20:47:44 +0000263 end() const
264 {
265 return Iterator();
266 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600267
HYuana9b85752014-02-26 02:32:30 -0600268private:
Junxiao Shib660b4c2016-08-06 20:47:44 +0000269 Hashtable m_ht;
Junxiao Shib184e532016-05-26 18:09:57 +0000270
Junxiao Shib660b4c2016-08-06 20:47:44 +0000271 friend class EnumerationImpl;
HYuana9b85752014-02-26 02:32:30 -0600272};
273
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000274} // namespace name_tree
275
276using name_tree::NameTree;
277
HYuana9b85752014-02-26 02:32:30 -0600278} // namespace nfd
279
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700280#endif // NFD_DAEMON_TABLE_NAME_TREE_HPP