blob: 91ec3fa1dae84b4a577acbcaf9c33c238b682b84 [file] [log] [blame]
HYuana9b85752014-02-26 02:32:30 -06001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi4370fde2016-02-24 12:20:46 -07003 * Copyright (c) 2014-2016, 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 Shi2570f3e2016-07-27 02:48:29 +000034/** \brief Compute the hash value of the given name prefix's WIRE FORMAT
HYuana9b85752014-02-26 02:32:30 -060035 */
Haowei Yuanf52dac72014-03-24 23:35:03 -050036size_t
37computeHash(const Name& prefix);
38
Junxiao Shi2570f3e2016-07-27 02:48:29 +000039/** \brief Incrementally compute hash values
40 * \return Return a vector of hash values, starting from the root prefix
Haowei Yuanf52dac72014-03-24 23:35:03 -050041 */
42std::vector<size_t>
43computeHashSet(const Name& prefix);
HYuana9b85752014-02-26 02:32:30 -060044
Junxiao Shi2570f3e2016-07-27 02:48:29 +000045/** \brief shared name-based index for FIB, PIT, Measurements, and StrategyChoice
HYuana9b85752014-02-26 02:32:30 -060046 */
47class NameTree : noncopyable
48{
49public:
Junxiao Shi029401f2016-08-05 12:55:14 +000050 typedef Iterator const_iterator;
Haowei Yuane1079fc2014-03-08 14:41:25 -060051
HYuana9b85752014-02-26 02:32:30 -060052 explicit
Haowei Yuanf52dac72014-03-24 23:35:03 -050053 NameTree(size_t nBuckets = 1024);
HYuana9b85752014-02-26 02:32:30 -060054
55 ~NameTree();
56
Alexander Afanasyevb3033242014-08-04 11:09:05 -070057public: // information
Junxiao Shi2570f3e2016-07-27 02:48:29 +000058 /** \brief Get the number of occupied entries in the Name Tree
HYuana9b85752014-02-26 02:32:30 -060059 */
60 size_t
61 size() const;
62
Junxiao Shi2570f3e2016-07-27 02:48:29 +000063 /** \brief Get the number of buckets in the Name Tree (NPHT)
64 *
65 * The number of buckets is the one that used to create the hash
66 * table, i.e., m_nBuckets.
HYuana9b85752014-02-26 02:32:30 -060067 */
68 size_t
69 getNBuckets() const;
70
Junxiao Shib184e532016-05-26 18:09:57 +000071 /** \return Name Tree Entry on which a table entry is attached
72 */
73 template<typename ENTRY>
Junxiao Shi2570f3e2016-07-27 02:48:29 +000074 shared_ptr<Entry>
Junxiao Shib184e532016-05-26 18:09:57 +000075 getEntry(const ENTRY& tableEntry) const;
76
Junxiao Shi2570f3e2016-07-27 02:48:29 +000077 /** \brief Dump all the information stored in the Name Tree for debugging.
Alexander Afanasyevb3033242014-08-04 11:09:05 -070078 */
79 void
80 dump(std::ostream& output) const;
81
82public: // mutation
Junxiao Shi2570f3e2016-07-27 02:48:29 +000083 /** \brief Look for the Name Tree Entry that contains this name prefix.
84 *
85 * Starts from the shortest name prefix, and then increase the
86 * number of name components by one each time. All non-existing Name Tree
87 * Entries will be created.
88 *
89 * \param prefix The querying name prefix.
90 * \return The pointer to the Name Tree Entry that contains this full name prefix.
91 * \note Existing iterators are unaffected.
HYuana9b85752014-02-26 02:32:30 -060092 */
Junxiao Shi2570f3e2016-07-27 02:48:29 +000093 shared_ptr<Entry>
HYuana9b85752014-02-26 02:32:30 -060094 lookup(const Name& prefix);
95
Junxiao Shib184e532016-05-26 18:09:57 +000096 /** \brief get NameTree entry from FIB entry
97 *
98 * This is equivalent to .lookup(fibEntry.getPrefix())
99 */
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000100 shared_ptr<Entry>
Junxiao Shib184e532016-05-26 18:09:57 +0000101 lookup(const fib::Entry& fibEntry) const;
102
103 /** \brief get NameTree entry from PIT entry
104 *
105 * This is equivalent to .lookup(pitEntry.getName()).
106 */
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000107 shared_ptr<Entry>
Junxiao Shib184e532016-05-26 18:09:57 +0000108 lookup(const pit::Entry& pitEntry);
109
110 /** \brief get NameTree entry from Measurements entry
111 *
112 * This is equivalent to .lookup(measurementsEntry.getName())
113 */
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000114 shared_ptr<Entry>
Junxiao Shib184e532016-05-26 18:09:57 +0000115 lookup(const measurements::Entry& measurementsEntry) const;
116
117 /** \brief get NameTree entry from StrategyChoice entry
118 *
119 * This is equivalent to .lookup(strategyChoiceEntry.getName())
120 */
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000121 shared_ptr<Entry>
Junxiao Shib184e532016-05-26 18:09:57 +0000122 lookup(const strategy_choice::Entry& strategyChoiceEntry) const;
123
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000124 /** \brief Delete a Name Tree Entry if this entry is empty.
125 * \param entry The entry to be deleted if empty.
126 * \note This function must be called after a table entry is detached from Name Tree
127 * entry. The function deletes a Name Tree entry if nothing is attached to it and
128 * it has no children, then repeats the same process on its ancestors.
129 * \note Existing iterators, except those pointing to deleted entries, are unaffected.
HYuana9b85752014-02-26 02:32:30 -0600130 */
131 bool
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000132 eraseEntryIfEmpty(shared_ptr<Entry> entry);
HYuana9b85752014-02-26 02:32:30 -0600133
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700134public: // matching
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000135 /** \brief Exact match lookup for the given name prefix.
136 * \return nullptr if this prefix is not found; otherwise return the Name Tree Entry address
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700137 */
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000138 shared_ptr<Entry>
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700139 findExactMatch(const Name& prefix) const;
140
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000141 /** \brief Longest prefix matching for the given name
142 *
143 * Starts from the full name string, reduce the number of name component
144 * by one each time, until an Entry is found.
HYuana9b85752014-02-26 02:32:30 -0600145 */
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000146 shared_ptr<Entry>
Junxiao Shi40631842014-03-01 13:52:37 -0700147 findLongestPrefixMatch(const Name& prefix,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000148 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600149
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000150 shared_ptr<Entry>
151 findLongestPrefixMatch(shared_ptr<Entry> entry,
152 const EntrySelector& entrySelector = AnyEntry()) const;
HangZhangcb4fc832014-03-11 16:57:11 +0800153
Junxiao Shi4370fde2016-02-24 12:20:46 -0700154 /** \brief longest prefix matching for Interest name of the PIT entry
155 *
156 * This is equivalent to .findLongestPrefixMatch(pitEntry.getName(), AnyEntry()).
157 */
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000158 shared_ptr<Entry>
Junxiao Shi4370fde2016-02-24 12:20:46 -0700159 findLongestPrefixMatch(const pit::Entry& pitEntry) const;
160
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700161 /** \brief Enumerate all the name prefixes that satisfy the prefix and entrySelector
162 * \return an unspecified type that have .begin() and .end() methods
163 * and is usable with range-based for
164 *
165 * Example:
166 * \code{.cpp}
167 * auto&& allMatches = nt.findAllMatches(Name("/A/B/C"));
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000168 * for (const Entry& nte : allMatches) {
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700169 * ...
170 * }
171 * \endcode
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800172 * \note Iteration order is implementation-specific and is undefined
173 * \note The returned iterator may get invalidated when NameTree is modified
HYuana9b85752014-02-26 02:32:30 -0600174 */
Junxiao Shi5ccd0c22014-12-02 23:54:42 -0700175 boost::iterator_range<const_iterator>
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700176 findAllMatches(const Name& prefix,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000177 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600178
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700179public: // enumeration
Junxiao Shi60607c72014-11-26 22:40:36 -0700180 /** \brief Enumerate all entries, optionally filtered by an EntrySelector.
181 * \return an unspecified type that have .begin() and .end() methods
182 * and is usable with range-based for
183 *
184 * Example:
185 * \code{.cpp}
186 * auto&& enumerable = nt.fullEnumerate();
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000187 * for (const Entry& nte : enumerable) {
Junxiao Shi60607c72014-11-26 22:40:36 -0700188 * ...
189 * }
190 * \endcode
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800191 * \note Iteration order is implementation-specific and is undefined
192 * \note The returned iterator may get invalidated when NameTree is modified
HYuana9b85752014-02-26 02:32:30 -0600193 */
Junxiao Shi5ccd0c22014-12-02 23:54:42 -0700194 boost::iterator_range<const_iterator>
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000195 fullEnumerate(const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600196
Junxiao Shi60607c72014-11-26 22:40:36 -0700197 /** \brief Enumerate all entries under a prefix, optionally filtered by an EntrySubTreeSelector.
198 * \return an unspecified type that have .begin() and .end() methods
199 * and is usable with range-based for
200 *
201 * Example:
202 * \code{.cpp}
203 * auto&& enumerable = nt.partialEnumerate(Name("/A/B/C"));
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000204 * for (const Entry& nte : enumerable) {
Junxiao Shi60607c72014-11-26 22:40:36 -0700205 * ...
206 * }
207 * \endcode
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800208 * \note Iteration order is implementation-specific and is undefined
209 * \note The returned iterator may get invalidated when NameTree is modified
Junxiao Shi60607c72014-11-26 22:40:36 -0700210 */
Junxiao Shi5ccd0c22014-12-02 23:54:42 -0700211 boost::iterator_range<const_iterator>
Junxiao Shi40631842014-03-01 13:52:37 -0700212 partialEnumerate(const Name& prefix,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000213 const EntrySubTreeSelector& entrySubTreeSelector = AnyEntrySubTree()) const;
HYuana9b85752014-02-26 02:32:30 -0600214
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800215 /** \brief Get an iterator pointing to the first NameTree entry
216 * \note Iteration order is implementation-specific and is undefined
217 * \note The returned iterator may get invalidated when NameTree is modified
218 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600219 const_iterator
220 begin() const;
221
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800222 /** \brief Get an iterator referring to the past-the-end FIB entry
223 * \note Iteration order is implementation-specific and is undefined
224 * \note The returned iterator may get invalidated when NameTree is modified
225 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600226 const_iterator
227 end() const;
228
HYuana9b85752014-02-26 02:32:30 -0600229private:
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000230 /** \brief Create a Name Tree Entry if it does not exist, or return the existing
231 * Name Tree Entry address.
232 *
233 * Called by lookup() only.
234 *
235 * \return The first item is the Name Tree Entry address, the second item is
236 * a bool value indicates whether this is an old entry (false) or a new
237 * entry (true).
Junxiao Shib184e532016-05-26 18:09:57 +0000238 */
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000239 std::pair<shared_ptr<Entry>, bool>
Junxiao Shib184e532016-05-26 18:09:57 +0000240 insert(const Name& prefix);
241
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000242 /** \brief Resize the hash table size when its load factor reaches a threshold.
243 *
244 * As we are currently using a hand-written hash table implementation
245 * for the Name Tree, the hash table resize() function should be kept in the
246 * name-tree.hpp file.
247 * \param newNBuckets The number of buckets for the new hash table.
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700248 */
249 void
250 resize(size_t newNBuckets);
251
252private:
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000253 size_t m_nItems; ///< Number of items being stored
254 size_t m_nBuckets; ///< Number of hash buckets
255 size_t m_minNBuckets; ///< Minimum number of hash buckets
256 double m_enlargeLoadFactor;
257 size_t m_enlargeThreshold;
258 int m_enlargeFactor;
259 double m_shrinkLoadFactor;
260 size_t m_shrinkThreshold;
261 double m_shrinkFactor;
262 Node** m_buckets; ///< Name Tree Buckets in the NPHT
Junxiao Shi029401f2016-08-05 12:55:14 +0000263
264 friend class FullEnumerationImpl;
265 friend class PartialEnumerationImpl;
266 friend class PrefixMatchImpl;
HYuana9b85752014-02-26 02:32:30 -0600267};
268
269inline size_t
270NameTree::size() const
271{
272 return m_nItems;
273}
274
275inline size_t
276NameTree::getNBuckets() const
277{
278 return m_nBuckets;
279}
280
Junxiao Shib184e532016-05-26 18:09:57 +0000281template<typename ENTRY>
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000282inline shared_ptr<Entry>
Junxiao Shib184e532016-05-26 18:09:57 +0000283NameTree::getEntry(const ENTRY& tableEntry) const
HangZhangcb4fc832014-03-11 16:57:11 +0800284{
Junxiao Shib184e532016-05-26 18:09:57 +0000285 return tableEntry.m_nameTreeEntry.lock();
HangZhangcb4fc832014-03-11 16:57:11 +0800286}
287
Haowei Yuane1079fc2014-03-08 14:41:25 -0600288inline NameTree::const_iterator
289NameTree::begin() const
290{
Junxiao Shi60607c72014-11-26 22:40:36 -0700291 return fullEnumerate().begin();
Haowei Yuane1079fc2014-03-08 14:41:25 -0600292}
293
294inline NameTree::const_iterator
295NameTree::end() const
296{
Junxiao Shi029401f2016-08-05 12:55:14 +0000297 return Iterator();
Haowei Yuane1079fc2014-03-08 14:41:25 -0600298}
299
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000300} // namespace name_tree
301
302using name_tree::NameTree;
303
HYuana9b85752014-02-26 02:32:30 -0600304} // namespace nfd
305
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700306#endif // NFD_DAEMON_TABLE_NAME_TREE_HPP