blob: b3c7da46efef21d6bc8aa97c09bb73d318b70249 [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/*
Davide Pesavento50a6af32019-02-21 00:04:40 -05003 * Copyright (c) 2014-2019, 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
Davide Pesavento50a6af32019-02-21 00:04:40 -050034/** \brief A common index structure for FIB, PIT, StrategyChoice, and Measurements
Junxiao Shie3cf2852016-08-09 03:50:56 +000035 */
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
Davide Pesavento50a6af32019-02-21 00:04:40 -050043 /** \brief Maximum depth of the name tree
Junxiao Shif54d0302017-09-07 18:16:38 +000044 *
Junxiao Shi057d1492018-03-20 17:14:18 +000045 * Calling \c NameTree::lookup with a name with many components would cause the creation of many
Junxiao Shif54d0302017-09-07 18:16:38 +000046 * 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.
Junxiao Shif54d0302017-09-07 18:16:38 +000049 */
Junxiao Shi75306352018-02-01 21:59:44 +000050 static constexpr size_t
Junxiao Shif54d0302017-09-07 18:16:38 +000051 getMaxDepth()
52 {
Davide Pesavento2cae8ca2019-04-18 20:48:05 -040053 return 32;
Junxiao Shif54d0302017-09-07 18:16:38 +000054 }
55
Junxiao Shie3cf2852016-08-09 03:50:56 +000056 /** \return number of name tree entries
HYuana9b85752014-02-26 02:32:30 -060057 */
58 size_t
Junxiao Shib660b4c2016-08-06 20:47:44 +000059 size() const
60 {
61 return m_ht.size();
62 }
HYuana9b85752014-02-26 02:32:30 -060063
Junxiao Shie3cf2852016-08-09 03:50:56 +000064 /** \return number of hashtable buckets
HYuana9b85752014-02-26 02:32:30 -060065 */
66 size_t
Junxiao Shib660b4c2016-08-06 20:47:44 +000067 getNBuckets() const
68 {
69 return m_ht.getNBuckets();
70 }
HYuana9b85752014-02-26 02:32:30 -060071
Junxiao Shif2420fc2016-08-11 13:18:21 +000072 /** \return name tree entry on which a table entry is attached,
73 * or nullptr if the table entry is detached
Junxiao Shib184e532016-05-26 18:09:57 +000074 */
Davide Pesaventoc0a5a392017-08-19 16:49:30 -040075 template<typename EntryT>
Junxiao Shi7f358432016-08-11 17:06:33 +000076 Entry*
Davide Pesaventoc0a5a392017-08-19 16:49:30 -040077 getEntry(const EntryT& tableEntry) const
Junxiao Shib660b4c2016-08-06 20:47:44 +000078 {
Junxiao Shi340d5532016-08-13 04:00:35 +000079 return Entry::get(tableEntry);
Junxiao Shib660b4c2016-08-06 20:47:44 +000080 }
Alexander Afanasyevb3033242014-08-04 11:09:05 -070081
82public: // mutation
Davide Pesavento50a6af32019-02-21 00:04:40 -050083 /** \brief Find or insert an entry by name
Junxiao Shi057d1492018-03-20 17:14:18 +000084 *
85 * This method seeks a name tree entry of name \c name.getPrefix(prefixLen).
86 * If the entry does not exist, it is created along with all ancestors.
87 * Existing iterators are unaffected during this operation.
88 *
89 * \warning \p prefixLen must not exceed \c name.size().
90 * \warning \p prefixLen must not exceed \c getMaxDepth().
HYuana9b85752014-02-26 02:32:30 -060091 */
Junxiao Shi7f358432016-08-11 17:06:33 +000092 Entry&
Junxiao Shi057d1492018-03-20 17:14:18 +000093 lookup(const Name& name, size_t prefixLen);
HYuana9b85752014-02-26 02:32:30 -060094
Davide Pesavento50a6af32019-02-21 00:04:40 -050095 /** \brief Equivalent to `lookup(name, name.size())`
Junxiao Shi057d1492018-03-20 17:14:18 +000096 */
97 Entry&
98 lookup(const Name& name)
99 {
100 return this->lookup(name, name.size());
101 }
102
Davide Pesavento50a6af32019-02-21 00:04:40 -0500103 /** \brief Equivalent to `lookup(fibEntry.getPrefix())`
Junxiao Shi057d1492018-03-20 17:14:18 +0000104 * \param fibEntry a FIB entry attached to this name tree, or \c Fib::s_emptyEntry
105 * \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 Shif2420fc2016-08-11 13:18:21 +0000108 lookup(const fib::Entry& fibEntry);
Junxiao Shib184e532016-05-26 18:09:57 +0000109
Davide Pesavento50a6af32019-02-21 00:04:40 -0500110 /** \brief Equivalent to `lookup(pitEntry.getName(), std::min(pitEntry.getName().size(), getMaxDepth()))`
Junxiao Shif2420fc2016-08-11 13:18:21 +0000111 * \param pitEntry a PIT entry attached to this name tree
Junxiao Shi057d1492018-03-20 17:14:18 +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 Shib184e532016-05-26 18:09:57 +0000115 lookup(const pit::Entry& pitEntry);
116
Davide Pesavento50a6af32019-02-21 00:04:40 -0500117 /** \brief Equivalent to `lookup(measurementsEntry.getName())`
Junxiao Shif2420fc2016-08-11 13:18:21 +0000118 * \param measurementsEntry a Measurements entry attached to this name tree
Junxiao Shi057d1492018-03-20 17:14:18 +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 measurements::Entry& measurementsEntry);
Junxiao Shib184e532016-05-26 18:09:57 +0000123
Davide Pesavento50a6af32019-02-21 00:04:40 -0500124 /** \brief Equivalent to `lookup(strategyChoiceEntry.getPrefix())`
Junxiao Shif2420fc2016-08-11 13:18:21 +0000125 * \param strategyChoiceEntry a StrategyChoice entry attached to this name tree
Junxiao Shi057d1492018-03-20 17:14:18 +0000126 * \note This overload is more efficient than `lookup(const Name&)` in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +0000127 */
Junxiao Shi7f358432016-08-11 17:06:33 +0000128 Entry&
Junxiao Shif2420fc2016-08-11 13:18:21 +0000129 lookup(const strategy_choice::Entry& strategyChoiceEntry);
Junxiao Shib184e532016-05-26 18:09:57 +0000130
Davide Pesavento50a6af32019-02-21 00:04:40 -0500131 /** \brief Delete the entry if it is empty
Junxiao Shie3cf2852016-08-09 03:50:56 +0000132 * \param entry a valid entry
Junxiao Shie7258ff2016-08-12 23:55:47 +0000133 * \param canEraseAncestors whether ancestors should be deleted if they become empty
Junxiao Shie3cf2852016-08-09 03:50:56 +0000134 * \return number of deleted entries
135 * \sa Entry::isEmpty()
Junxiao Shi057d1492018-03-20 17:14:18 +0000136 * \post If the entry is empty, it's deleted. If \p canEraseAncestors is true,
Junxiao Shie7258ff2016-08-12 23:55:47 +0000137 * ancestors of the entry are also deleted if they become empty.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000138 * \note This function must be called after detaching a table entry from a name tree entry,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000139 * \note Existing iterators, except those pointing to deleted entries, are unaffected.
HYuana9b85752014-02-26 02:32:30 -0600140 */
Junxiao Shib660b4c2016-08-06 20:47:44 +0000141 size_t
Junxiao Shie7258ff2016-08-12 23:55:47 +0000142 eraseIfEmpty(Entry* entry, bool canEraseAncestors = true);
HYuana9b85752014-02-26 02:32:30 -0600143
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700144public: // matching
Davide Pesavento50a6af32019-02-21 00:04:40 -0500145 /** \brief Exact match lookup
Junxiao Shi057d1492018-03-20 17:14:18 +0000146 * \return entry with \c name.getPrefix(prefixLen), or nullptr if it does not exist
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700147 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000148 Entry*
Junxiao Shi042a3312017-09-15 02:51:20 +0000149 findExactMatch(const Name& name, size_t prefixLen = std::numeric_limits<size_t>::max()) const;
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700150
Davide Pesavento50a6af32019-02-21 00:04:40 -0500151 /** \brief Longest prefix matching
Junxiao Shie3cf2852016-08-09 03:50:56 +0000152 * \return entry whose name is a prefix of \p name and passes \p entrySelector,
153 * where no other entry with a longer name satisfies those requirements;
154 * or nullptr if no entry satisfying those requirements exists
HYuana9b85752014-02-26 02:32:30 -0600155 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000156 Entry*
Junxiao Shib660b4c2016-08-06 20:47:44 +0000157 findLongestPrefixMatch(const Name& name,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000158 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600159
Davide Pesavento50a6af32019-02-21 00:04:40 -0500160 /** \brief Equivalent to `findLongestPrefixMatch(entry.getName(), entrySelector)`
Junxiao Shif2420fc2016-08-11 13:18:21 +0000161 * \note This overload is more efficient than
Junxiao Shi057d1492018-03-20 17:14:18 +0000162 * `findLongestPrefixMatch(const Name&, const EntrySelector&)` in common cases.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000163 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000164 Entry*
165 findLongestPrefixMatch(const Entry& entry,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000166 const EntrySelector& entrySelector = AnyEntry()) const;
HangZhangcb4fc832014-03-11 16:57:11 +0800167
Davide Pesavento50a6af32019-02-21 00:04:40 -0500168 /** \brief Equivalent to `findLongestPrefixMatch(getEntry(tableEntry)->getName(), entrySelector)`
Junxiao Shi057d1492018-03-20 17:14:18 +0000169 * \tparam EntryT \c fib::Entry or \c measurements::Entry or \c strategy_choice::Entry
Junxiao Shif2420fc2016-08-11 13:18:21 +0000170 * \note This overload is more efficient than
Junxiao Shi057d1492018-03-20 17:14:18 +0000171 * `findLongestPrefixMatch(const Name&, const EntrySelector&)` in common cases.
172 * \warning Undefined behavior may occur if \p tableEntry is not attached to this name tree.
Junxiao Shidd8f6612016-08-12 15:42:52 +0000173 */
Davide Pesaventoc0a5a392017-08-19 16:49:30 -0400174 template<typename EntryT>
Junxiao Shidd8f6612016-08-12 15:42:52 +0000175 Entry*
Davide Pesaventoc0a5a392017-08-19 16:49:30 -0400176 findLongestPrefixMatch(const EntryT& tableEntry,
177 const EntrySelector& entrySelector = AnyEntry()) const
178 {
179 const Entry* nte = this->getEntry(tableEntry);
180 BOOST_ASSERT(nte != nullptr);
181 return this->findLongestPrefixMatch(*nte, entrySelector);
182 }
Junxiao Shidd8f6612016-08-12 15:42:52 +0000183
Davide Pesavento50a6af32019-02-21 00:04:40 -0500184 /** \brief Equivalent to `findLongestPrefixMatch(pitEntry.getName(), entrySelector)`
Junxiao Shidd8f6612016-08-12 15:42:52 +0000185 * \note This overload is more efficient than
Junxiao Shi057d1492018-03-20 17:14:18 +0000186 * `findLongestPrefixMatch(const Name&, const EntrySelector&)` in common cases.
187 * \warning Undefined behavior may occur if \p pitEntry is not attached to this name tree.
Junxiao Shi4370fde2016-02-24 12:20:46 -0700188 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000189 Entry*
Junxiao Shif2420fc2016-08-11 13:18:21 +0000190 findLongestPrefixMatch(const pit::Entry& pitEntry,
191 const EntrySelector& entrySelector = AnyEntry()) const;
Junxiao Shi4370fde2016-02-24 12:20:46 -0700192
Davide Pesavento50a6af32019-02-21 00:04:40 -0500193 /** \brief All-prefixes match lookup
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000194 * \return a range where every entry has a name that is a prefix of \p name ,
Junxiao Shie3cf2852016-08-09 03:50:56 +0000195 * and matches \p entrySelector.
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700196 *
197 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000198 * \code
199 * Name name("/A/B/C");
200 * auto&& allMatches = nt.findAllMatches(name);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000201 * for (const Entry& nte : allMatches) {
Junxiao Shie3cf2852016-08-09 03:50:56 +0000202 * BOOST_ASSERT(nte.getName().isPrefixOf(name));
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700203 * ...
204 * }
205 * \endcode
Junxiao Shib30863e2016-08-15 21:32:01 +0000206 * \note Iteration order is implementation-defined.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000207 * \warning If a name tree entry whose name is a prefix of \p name is inserted
208 * during the enumeration, it may or may not be visited.
209 * If a name tree entry whose name is a prefix of \p name is deleted
210 * during the enumeration, undefined behavior may occur.
HYuana9b85752014-02-26 02:32:30 -0600211 */
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000212 Range
Junxiao Shie3cf2852016-08-09 03:50:56 +0000213 findAllMatches(const Name& name,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000214 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600215
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700216public: // enumeration
Junxiao Shif54d0302017-09-07 18:16:38 +0000217 using const_iterator = Iterator;
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000218
Davide Pesavento50a6af32019-02-21 00:04:40 -0500219 /** \brief Enumerate all entries
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000220 * \return a range where every entry matches \p entrySelector
Junxiao Shi60607c72014-11-26 22:40:36 -0700221 *
222 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000223 * \code
Junxiao Shi60607c72014-11-26 22:40:36 -0700224 * auto&& enumerable = nt.fullEnumerate();
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000225 * for (const Entry& nte : enumerable) {
Junxiao Shi60607c72014-11-26 22:40:36 -0700226 * ...
227 * }
228 * \endcode
Junxiao Shib30863e2016-08-15 21:32:01 +0000229 * \note Iteration order is implementation-defined.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000230 * \warning If a name tree entry is inserted or deleted during the enumeration,
231 * it may cause the enumeration to skip entries or visit some entries twice.
HYuana9b85752014-02-26 02:32:30 -0600232 */
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000233 Range
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000234 fullEnumerate(const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600235
Davide Pesavento50a6af32019-02-21 00:04:40 -0500236 /** \brief Enumerate all entries under a prefix
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000237 * \return a range where every entry has a name that starts with \p prefix,
Junxiao Shie3cf2852016-08-09 03:50:56 +0000238 * and matches \p entrySubTreeSelector.
Junxiao Shi60607c72014-11-26 22:40:36 -0700239 *
240 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000241 * \code
242 * Name name("/A/B/C");
243 * auto&& enumerable = nt.partialEnumerate(name);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000244 * for (const Entry& nte : enumerable) {
Junxiao Shie3cf2852016-08-09 03:50:56 +0000245 * BOOST_ASSERT(name.isPrefixOf(nte.getName()));
Junxiao Shi60607c72014-11-26 22:40:36 -0700246 * ...
247 * }
248 * \endcode
Junxiao Shib30863e2016-08-15 21:32:01 +0000249 * \note Iteration order is implementation-defined.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000250 * \warning If a name tree entry under \p prefix is inserted or deleted during the enumeration,
251 * it may cause the enumeration to skip entries or visit some entries twice.
Junxiao Shi60607c72014-11-26 22:40:36 -0700252 */
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000253 Range
Junxiao Shi40631842014-03-01 13:52:37 -0700254 partialEnumerate(const Name& prefix,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000255 const EntrySubTreeSelector& entrySubTreeSelector = AnyEntrySubTree()) const;
HYuana9b85752014-02-26 02:32:30 -0600256
Junxiao Shib30863e2016-08-15 21:32:01 +0000257 /** \return an iterator to the beginning
Junxiao Shie3cf2852016-08-09 03:50:56 +0000258 * \sa fullEnumerate
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800259 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600260 const_iterator
Junxiao Shib660b4c2016-08-06 20:47:44 +0000261 begin() const
262 {
263 return fullEnumerate().begin();
264 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600265
Junxiao Shib30863e2016-08-15 21:32:01 +0000266 /** \return an iterator to the end
267 * \sa begin()
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800268 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600269 const_iterator
Junxiao Shib660b4c2016-08-06 20:47:44 +0000270 end() const
271 {
272 return Iterator();
273 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600274
HYuana9b85752014-02-26 02:32:30 -0600275private:
Junxiao Shib660b4c2016-08-06 20:47:44 +0000276 Hashtable m_ht;
Junxiao Shib184e532016-05-26 18:09:57 +0000277
Junxiao Shib660b4c2016-08-06 20:47:44 +0000278 friend class EnumerationImpl;
HYuana9b85752014-02-26 02:32:30 -0600279};
280
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000281} // namespace name_tree
282
283using name_tree::NameTree;
284
HYuana9b85752014-02-26 02:32:30 -0600285} // namespace nfd
286
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700287#endif // NFD_DAEMON_TABLE_NAME_TREE_HPP