blob: 1cb5f3174fc1f063fb31b25886c3eacf77f2f0b5 [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
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
Davide Pesavento50a6af32019-02-21 00:04:40 -050036/** \brief A common index structure for FIB, PIT, StrategyChoice, and Measurements
Junxiao Shie3cf2852016-08-09 03:50:56 +000037 */
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
Davide Pesavento50a6af32019-02-21 00:04:40 -050045 /** \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
Davide Pesavento50a6af32019-02-21 00:04:40 -050085 /** \brief Find or insert an entry by name
Junxiao Shi057d1492018-03-20 17:14:18 +000086 *
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
Davide Pesavento50a6af32019-02-21 00:04:40 -050097 /** \brief Equivalent to `lookup(name, name.size())`
Junxiao Shi057d1492018-03-20 17:14:18 +000098 */
99 Entry&
100 lookup(const Name& name)
101 {
102 return this->lookup(name, name.size());
103 }
104
Davide Pesavento50a6af32019-02-21 00:04:40 -0500105 /** \brief Equivalent to `lookup(fibEntry.getPrefix())`
Junxiao Shi057d1492018-03-20 17:14:18 +0000106 * \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
Davide Pesavento50a6af32019-02-21 00:04:40 -0500112 /** \brief Equivalent to `lookup(pitEntry.getName(), std::min(pitEntry.getName().size(), getMaxDepth()))`
Junxiao Shif2420fc2016-08-11 13:18:21 +0000113 * \param pitEntry a PIT entry attached to this name tree
Junxiao Shi057d1492018-03-20 17:14:18 +0000114 * \note This overload is more efficient than `lookup(const Name&)` in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +0000115 */
Junxiao Shi7f358432016-08-11 17:06:33 +0000116 Entry&
Junxiao Shib184e532016-05-26 18:09:57 +0000117 lookup(const pit::Entry& pitEntry);
118
Davide Pesavento50a6af32019-02-21 00:04:40 -0500119 /** \brief Equivalent to `lookup(measurementsEntry.getName())`
Junxiao Shif2420fc2016-08-11 13:18:21 +0000120 * \param measurementsEntry a Measurements entry attached to this name tree
Junxiao Shi057d1492018-03-20 17:14:18 +0000121 * \note This overload is more efficient than `lookup(const Name&)` in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +0000122 */
Junxiao Shi7f358432016-08-11 17:06:33 +0000123 Entry&
Junxiao Shif2420fc2016-08-11 13:18:21 +0000124 lookup(const measurements::Entry& measurementsEntry);
Junxiao Shib184e532016-05-26 18:09:57 +0000125
Davide Pesavento50a6af32019-02-21 00:04:40 -0500126 /** \brief Equivalent to `lookup(strategyChoiceEntry.getPrefix())`
Junxiao Shif2420fc2016-08-11 13:18:21 +0000127 * \param strategyChoiceEntry a StrategyChoice entry attached to this name tree
Junxiao Shi057d1492018-03-20 17:14:18 +0000128 * \note This overload is more efficient than `lookup(const Name&)` in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +0000129 */
Junxiao Shi7f358432016-08-11 17:06:33 +0000130 Entry&
Junxiao Shif2420fc2016-08-11 13:18:21 +0000131 lookup(const strategy_choice::Entry& strategyChoiceEntry);
Junxiao Shib184e532016-05-26 18:09:57 +0000132
Davide Pesavento50a6af32019-02-21 00:04:40 -0500133 /** \brief Delete the entry if it is empty
Junxiao Shie3cf2852016-08-09 03:50:56 +0000134 * \param entry a valid entry
Junxiao Shie7258ff2016-08-12 23:55:47 +0000135 * \param canEraseAncestors whether ancestors should be deleted if they become empty
Junxiao Shie3cf2852016-08-09 03:50:56 +0000136 * \return number of deleted entries
137 * \sa Entry::isEmpty()
Junxiao Shi057d1492018-03-20 17:14:18 +0000138 * \post If the entry is empty, it's deleted. If \p canEraseAncestors is true,
Junxiao Shie7258ff2016-08-12 23:55:47 +0000139 * ancestors of the entry are also deleted if they become empty.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000140 * \note This function must be called after detaching a table entry from a name tree entry,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000141 * \note Existing iterators, except those pointing to deleted entries, are unaffected.
HYuana9b85752014-02-26 02:32:30 -0600142 */
Junxiao Shib660b4c2016-08-06 20:47:44 +0000143 size_t
Junxiao Shie7258ff2016-08-12 23:55:47 +0000144 eraseIfEmpty(Entry* entry, bool canEraseAncestors = true);
HYuana9b85752014-02-26 02:32:30 -0600145
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700146public: // matching
Davide Pesavento50a6af32019-02-21 00:04:40 -0500147 /** \brief Exact match lookup
Junxiao Shi057d1492018-03-20 17:14:18 +0000148 * \return entry with \c name.getPrefix(prefixLen), or nullptr if it does not exist
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700149 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000150 Entry*
Junxiao Shi042a3312017-09-15 02:51:20 +0000151 findExactMatch(const Name& name, size_t prefixLen = std::numeric_limits<size_t>::max()) const;
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700152
Davide Pesavento50a6af32019-02-21 00:04:40 -0500153 /** \brief Longest prefix matching
Junxiao Shie3cf2852016-08-09 03:50:56 +0000154 * \return entry whose name is a prefix of \p name and passes \p entrySelector,
155 * where no other entry with a longer name satisfies those requirements;
156 * or nullptr if no entry satisfying those requirements exists
HYuana9b85752014-02-26 02:32:30 -0600157 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000158 Entry*
Junxiao Shib660b4c2016-08-06 20:47:44 +0000159 findLongestPrefixMatch(const Name& name,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000160 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600161
Davide Pesavento50a6af32019-02-21 00:04:40 -0500162 /** \brief Equivalent to `findLongestPrefixMatch(entry.getName(), entrySelector)`
Junxiao Shif2420fc2016-08-11 13:18:21 +0000163 * \note This overload is more efficient than
Junxiao Shi057d1492018-03-20 17:14:18 +0000164 * `findLongestPrefixMatch(const Name&, const EntrySelector&)` in common cases.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000165 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000166 Entry*
167 findLongestPrefixMatch(const Entry& entry,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000168 const EntrySelector& entrySelector = AnyEntry()) const;
HangZhangcb4fc832014-03-11 16:57:11 +0800169
Davide Pesavento50a6af32019-02-21 00:04:40 -0500170 /** \brief Equivalent to `findLongestPrefixMatch(getEntry(tableEntry)->getName(), entrySelector)`
Junxiao Shi057d1492018-03-20 17:14:18 +0000171 * \tparam EntryT \c fib::Entry or \c measurements::Entry or \c strategy_choice::Entry
Junxiao Shif2420fc2016-08-11 13:18:21 +0000172 * \note This overload is more efficient than
Junxiao Shi057d1492018-03-20 17:14:18 +0000173 * `findLongestPrefixMatch(const Name&, const EntrySelector&)` in common cases.
174 * \warning Undefined behavior may occur if \p tableEntry is not attached to this name tree.
Junxiao Shidd8f6612016-08-12 15:42:52 +0000175 */
Davide Pesaventoc0a5a392017-08-19 16:49:30 -0400176 template<typename EntryT>
Junxiao Shidd8f6612016-08-12 15:42:52 +0000177 Entry*
Davide Pesaventoc0a5a392017-08-19 16:49:30 -0400178 findLongestPrefixMatch(const EntryT& tableEntry,
179 const EntrySelector& entrySelector = AnyEntry()) const
180 {
181 const Entry* nte = this->getEntry(tableEntry);
182 BOOST_ASSERT(nte != nullptr);
183 return this->findLongestPrefixMatch(*nte, entrySelector);
184 }
Junxiao Shidd8f6612016-08-12 15:42:52 +0000185
Davide Pesavento50a6af32019-02-21 00:04:40 -0500186 /** \brief Equivalent to `findLongestPrefixMatch(pitEntry.getName(), entrySelector)`
Junxiao Shidd8f6612016-08-12 15:42:52 +0000187 * \note This overload is more efficient than
Junxiao Shi057d1492018-03-20 17:14:18 +0000188 * `findLongestPrefixMatch(const Name&, const EntrySelector&)` in common cases.
189 * \warning Undefined behavior may occur if \p pitEntry is not attached to this name tree.
Junxiao Shi4370fde2016-02-24 12:20:46 -0700190 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000191 Entry*
Junxiao Shif2420fc2016-08-11 13:18:21 +0000192 findLongestPrefixMatch(const pit::Entry& pitEntry,
193 const EntrySelector& entrySelector = AnyEntry()) const;
Junxiao Shi4370fde2016-02-24 12:20:46 -0700194
Davide Pesavento50a6af32019-02-21 00:04:40 -0500195 /** \brief All-prefixes match lookup
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000196 * \return a range where every entry has a name that is a prefix of \p name ,
Junxiao Shie3cf2852016-08-09 03:50:56 +0000197 * and matches \p entrySelector.
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700198 *
199 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000200 * \code
201 * Name name("/A/B/C");
202 * auto&& allMatches = nt.findAllMatches(name);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000203 * for (const Entry& nte : allMatches) {
Junxiao Shie3cf2852016-08-09 03:50:56 +0000204 * BOOST_ASSERT(nte.getName().isPrefixOf(name));
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700205 * ...
206 * }
207 * \endcode
Junxiao Shib30863e2016-08-15 21:32:01 +0000208 * \note Iteration order is implementation-defined.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000209 * \warning If a name tree entry whose name is a prefix of \p name is inserted
210 * during the enumeration, it may or may not be visited.
211 * If a name tree entry whose name is a prefix of \p name is deleted
212 * during the enumeration, undefined behavior may occur.
HYuana9b85752014-02-26 02:32:30 -0600213 */
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000214 Range
Junxiao Shie3cf2852016-08-09 03:50:56 +0000215 findAllMatches(const Name& name,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000216 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600217
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700218public: // enumeration
Junxiao Shif54d0302017-09-07 18:16:38 +0000219 using const_iterator = Iterator;
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000220
Davide Pesavento50a6af32019-02-21 00:04:40 -0500221 /** \brief Enumerate all entries
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000222 * \return a range where every entry matches \p entrySelector
Junxiao Shi60607c72014-11-26 22:40:36 -0700223 *
224 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000225 * \code
Junxiao Shi60607c72014-11-26 22:40:36 -0700226 * auto&& enumerable = nt.fullEnumerate();
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000227 * for (const Entry& nte : enumerable) {
Junxiao Shi60607c72014-11-26 22:40:36 -0700228 * ...
229 * }
230 * \endcode
Junxiao Shib30863e2016-08-15 21:32:01 +0000231 * \note Iteration order is implementation-defined.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000232 * \warning If a name tree entry is inserted or deleted during the enumeration,
233 * it may cause the enumeration to skip entries or visit some entries twice.
HYuana9b85752014-02-26 02:32:30 -0600234 */
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000235 Range
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000236 fullEnumerate(const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600237
Davide Pesavento50a6af32019-02-21 00:04:40 -0500238 /** \brief Enumerate all entries under a prefix
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000239 * \return a range where every entry has a name that starts with \p prefix,
Junxiao Shie3cf2852016-08-09 03:50:56 +0000240 * and matches \p entrySubTreeSelector.
Junxiao Shi60607c72014-11-26 22:40:36 -0700241 *
242 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000243 * \code
244 * Name name("/A/B/C");
245 * auto&& enumerable = nt.partialEnumerate(name);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000246 * for (const Entry& nte : enumerable) {
Junxiao Shie3cf2852016-08-09 03:50:56 +0000247 * BOOST_ASSERT(name.isPrefixOf(nte.getName()));
Junxiao Shi60607c72014-11-26 22:40:36 -0700248 * ...
249 * }
250 * \endcode
Junxiao Shib30863e2016-08-15 21:32:01 +0000251 * \note Iteration order is implementation-defined.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000252 * \warning If a name tree entry under \p prefix is inserted or deleted during the enumeration,
253 * it may cause the enumeration to skip entries or visit some entries twice.
Junxiao Shi60607c72014-11-26 22:40:36 -0700254 */
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000255 Range
Junxiao Shi40631842014-03-01 13:52:37 -0700256 partialEnumerate(const Name& prefix,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000257 const EntrySubTreeSelector& entrySubTreeSelector = AnyEntrySubTree()) const;
HYuana9b85752014-02-26 02:32:30 -0600258
Junxiao Shib30863e2016-08-15 21:32:01 +0000259 /** \return an iterator to the beginning
Junxiao Shie3cf2852016-08-09 03:50:56 +0000260 * \sa fullEnumerate
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 begin() const
264 {
265 return fullEnumerate().begin();
266 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600267
Junxiao Shib30863e2016-08-15 21:32:01 +0000268 /** \return an iterator to the end
269 * \sa begin()
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800270 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600271 const_iterator
Junxiao Shib660b4c2016-08-06 20:47:44 +0000272 end() const
273 {
274 return Iterator();
275 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600276
HYuana9b85752014-02-26 02:32:30 -0600277private:
Junxiao Shib660b4c2016-08-06 20:47:44 +0000278 Hashtable m_ht;
Junxiao Shib184e532016-05-26 18:09:57 +0000279
Junxiao Shib660b4c2016-08-06 20:47:44 +0000280 friend class EnumerationImpl;
HYuana9b85752014-02-26 02:32:30 -0600281};
282
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000283} // namespace name_tree
284
285using name_tree::NameTree;
286
HYuana9b85752014-02-26 02:32:30 -0600287} // namespace nfd
288
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700289#endif // NFD_DAEMON_TABLE_NAME_TREE_HPP