blob: 0c24654c7e4ba6275d2593ce1f0e159640c4f2b5 [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 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:
Junxiao Shi029401f2016-08-05 12:55:14 +000039 typedef Iterator const_iterator;
Haowei Yuane1079fc2014-03-08 14:41:25 -060040
HYuana9b85752014-02-26 02:32:30 -060041 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 Shie3cf2852016-08-09 03:50:56 +000045 /** \return number of name tree entries
HYuana9b85752014-02-26 02:32:30 -060046 */
47 size_t
Junxiao Shib660b4c2016-08-06 20:47:44 +000048 size() const
49 {
50 return m_ht.size();
51 }
HYuana9b85752014-02-26 02:32:30 -060052
Junxiao Shie3cf2852016-08-09 03:50:56 +000053 /** \return number of hashtable buckets
HYuana9b85752014-02-26 02:32:30 -060054 */
55 size_t
Junxiao Shib660b4c2016-08-06 20:47:44 +000056 getNBuckets() const
57 {
58 return m_ht.getNBuckets();
59 }
HYuana9b85752014-02-26 02:32:30 -060060
Junxiao Shif2420fc2016-08-11 13:18:21 +000061 /** \return name tree entry on which a table entry is attached,
62 * or nullptr if the table entry is detached
Junxiao Shib184e532016-05-26 18:09:57 +000063 */
64 template<typename ENTRY>
Junxiao Shi7f358432016-08-11 17:06:33 +000065 Entry*
Junxiao Shib660b4c2016-08-06 20:47:44 +000066 getEntry(const ENTRY& tableEntry) const
67 {
Junxiao Shi340d5532016-08-13 04:00:35 +000068 return Entry::get(tableEntry);
Junxiao Shib660b4c2016-08-06 20:47:44 +000069 }
Alexander Afanasyevb3033242014-08-04 11:09:05 -070070
71public: // mutation
Junxiao Shie3cf2852016-08-09 03:50:56 +000072 /** \brief find or insert an entry with specified name
73 * \param name a name prefix
74 * \return an entry with \p name
75 * \post an entry with \p name and all ancestors are created
Junxiao Shi2570f3e2016-07-27 02:48:29 +000076 * \note Existing iterators are unaffected.
HYuana9b85752014-02-26 02:32:30 -060077 */
Junxiao Shi7f358432016-08-11 17:06:33 +000078 Entry&
Junxiao Shib660b4c2016-08-06 20:47:44 +000079 lookup(const Name& name);
HYuana9b85752014-02-26 02:32:30 -060080
Junxiao Shie3cf2852016-08-09 03:50:56 +000081 /** \brief equivalent to .lookup(fibEntry.getPrefix())
Junxiao Shif2420fc2016-08-11 13:18:21 +000082 * \param fibEntry a FIB entry attached to this name tree, or Fib::s_emptyEntry
Junxiao Shie3cf2852016-08-09 03:50:56 +000083 * \note This overload is more efficient than .lookup(const Name&) in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +000084 */
Junxiao Shi7f358432016-08-11 17:06:33 +000085 Entry&
Junxiao Shif2420fc2016-08-11 13:18:21 +000086 lookup(const fib::Entry& fibEntry);
Junxiao Shib184e532016-05-26 18:09:57 +000087
Junxiao Shie3cf2852016-08-09 03:50:56 +000088 /** \brief equivalent to .lookup(pitEntry.getName()).
Junxiao Shif2420fc2016-08-11 13:18:21 +000089 * \param pitEntry a PIT entry attached to this name tree
Junxiao Shie3cf2852016-08-09 03:50:56 +000090 * \note This overload is more efficient than .lookup(const Name&) in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +000091 */
Junxiao Shi7f358432016-08-11 17:06:33 +000092 Entry&
Junxiao Shib184e532016-05-26 18:09:57 +000093 lookup(const pit::Entry& pitEntry);
94
Junxiao Shie3cf2852016-08-09 03:50:56 +000095 /** \brief equivalent to .lookup(measurementsEntry.getName())
Junxiao Shif2420fc2016-08-11 13:18:21 +000096 * \param measurementsEntry a Measurements entry attached to this name tree
Junxiao Shie3cf2852016-08-09 03:50:56 +000097 * \note This overload is more efficient than .lookup(const Name&) in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +000098 */
Junxiao Shi7f358432016-08-11 17:06:33 +000099 Entry&
Junxiao Shif2420fc2016-08-11 13:18:21 +0000100 lookup(const measurements::Entry& measurementsEntry);
Junxiao Shib184e532016-05-26 18:09:57 +0000101
Junxiao Shidd8f6612016-08-12 15:42:52 +0000102 /** \brief equivalent to .lookup(strategyChoiceEntry.getPrefix())
Junxiao Shif2420fc2016-08-11 13:18:21 +0000103 * \param strategyChoiceEntry a StrategyChoice entry attached to this name tree
Junxiao Shie3cf2852016-08-09 03:50:56 +0000104 * \note This overload is more efficient than .lookup(const Name&) in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +0000105 */
Junxiao Shi7f358432016-08-11 17:06:33 +0000106 Entry&
Junxiao Shif2420fc2016-08-11 13:18:21 +0000107 lookup(const strategy_choice::Entry& strategyChoiceEntry);
Junxiao Shib184e532016-05-26 18:09:57 +0000108
Junxiao Shie3cf2852016-08-09 03:50:56 +0000109 /** \brief delete the entry if it is empty
110 * \param entry a valid entry
Junxiao Shie7258ff2016-08-12 23:55:47 +0000111 * \param canEraseAncestors whether ancestors should be deleted if they become empty
Junxiao Shie3cf2852016-08-09 03:50:56 +0000112 * \return number of deleted entries
113 * \sa Entry::isEmpty()
Junxiao Shie7258ff2016-08-12 23:55:47 +0000114 * \post If the entry is empty, it's deleted. If canEraseAncestors is true,
115 * ancestors of the entry are also deleted if they become empty.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000116 * \note This function must be called after detaching a table entry from a name tree entry,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000117 * \note Existing iterators, except those pointing to deleted entries, are unaffected.
HYuana9b85752014-02-26 02:32:30 -0600118 */
Junxiao Shib660b4c2016-08-06 20:47:44 +0000119 size_t
Junxiao Shie7258ff2016-08-12 23:55:47 +0000120 eraseIfEmpty(Entry* entry, bool canEraseAncestors = true);
HYuana9b85752014-02-26 02:32:30 -0600121
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700122public: // matching
Junxiao Shie3cf2852016-08-09 03:50:56 +0000123 /** \brief exact match lookup
124 * \return entry with \p name, or nullptr if it does not exist
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700125 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000126 Entry*
Junxiao Shib660b4c2016-08-06 20:47:44 +0000127 findExactMatch(const Name& name) const;
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700128
Junxiao Shie3cf2852016-08-09 03:50:56 +0000129 /** \brief longest prefix matching
130 * \return entry whose name is a prefix of \p name and passes \p entrySelector,
131 * where no other entry with a longer name satisfies those requirements;
132 * or nullptr if no entry satisfying those requirements exists
HYuana9b85752014-02-26 02:32:30 -0600133 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000134 Entry*
Junxiao Shib660b4c2016-08-06 20:47:44 +0000135 findLongestPrefixMatch(const Name& name,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000136 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600137
Junxiao Shi811c0102016-08-10 04:12:45 +0000138 /** \brief equivalent to .findLongestPrefixMatch(entry.getName(), entrySelector)
Junxiao Shif2420fc2016-08-11 13:18:21 +0000139 * \note This overload is more efficient than
140 * .findLongestPrefixMatch(const Name&, const EntrySelector&) in common cases.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000141 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000142 Entry*
143 findLongestPrefixMatch(const Entry& entry,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000144 const EntrySelector& entrySelector = AnyEntry()) const;
HangZhangcb4fc832014-03-11 16:57:11 +0800145
Junxiao Shidd8f6612016-08-12 15:42:52 +0000146 /** \brief equivalent to .findLongestPrefixMatch(getEntry(tableEntry)->getName(), entrySelector)
147 * \tparam ENTRY fib::Entry or measurements::Entry or strategy_choice::Entry
Junxiao Shif2420fc2016-08-11 13:18:21 +0000148 * \note This overload is more efficient than
149 * .findLongestPrefixMatch(const Name&, const EntrySelector&) in common cases.
Junxiao Shidd8f6612016-08-12 15:42:52 +0000150 * \warning Undefined behavior may occur if tableEntry is not attached to this name tree.
151 */
152 template<typename ENTRY>
153 Entry*
154 findLongestPrefixMatch(const ENTRY& tableEntry,
155 const EntrySelector& entrySelector = AnyEntry()) const;
156
157 /** \brief equivalent to .findLongestPrefixMatch(pitEntry.getName(), entrySelector)
158 * \note This overload is more efficient than
159 * .findLongestPrefixMatch(const Name&, const EntrySelector&) in common cases.
160 * \warning Undefined behavior may occur if pitEntry is not attached to this name tree.
Junxiao Shi4370fde2016-02-24 12:20:46 -0700161 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000162 Entry*
Junxiao Shif2420fc2016-08-11 13:18:21 +0000163 findLongestPrefixMatch(const pit::Entry& pitEntry,
164 const EntrySelector& entrySelector = AnyEntry()) const;
Junxiao Shi4370fde2016-02-24 12:20:46 -0700165
Junxiao Shie3cf2852016-08-09 03:50:56 +0000166 /** \brief all-prefixes match lookup
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700167 * \return an unspecified type that have .begin() and .end() methods
Junxiao Shie3cf2852016-08-09 03:50:56 +0000168 * and is usable with range-based for.
169 * Every entry in the range has a name that is a prefix of \p name ,
170 * and matches \p entrySelector.
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700171 *
172 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000173 * \code
174 * Name name("/A/B/C");
175 * auto&& allMatches = nt.findAllMatches(name);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000176 * for (const Entry& nte : allMatches) {
Junxiao Shie3cf2852016-08-09 03:50:56 +0000177 * BOOST_ASSERT(nte.getName().isPrefixOf(name));
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700178 * ...
179 * }
180 * \endcode
Junxiao Shie3cf2852016-08-09 03:50:56 +0000181 * \note Iteration order is implementation-specific and is undefined.
182 * \warning If a name tree entry whose name is a prefix of \p name is inserted
183 * during the enumeration, it may or may not be visited.
184 * If a name tree entry whose name is a prefix of \p name is deleted
185 * during the enumeration, undefined behavior may occur.
HYuana9b85752014-02-26 02:32:30 -0600186 */
Junxiao Shi5ccd0c22014-12-02 23:54:42 -0700187 boost::iterator_range<const_iterator>
Junxiao Shie3cf2852016-08-09 03:50:56 +0000188 findAllMatches(const Name& name,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000189 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600190
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700191public: // enumeration
Junxiao Shie3cf2852016-08-09 03:50:56 +0000192 /** \brief enumerate all entries
Junxiao Shi60607c72014-11-26 22:40:36 -0700193 * \return an unspecified type that have .begin() and .end() methods
Junxiao Shie3cf2852016-08-09 03:50:56 +0000194 * and is usable with range-based for.
195 * Every entry in the range matches \p entrySelector.
Junxiao Shi60607c72014-11-26 22:40:36 -0700196 *
197 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000198 * \code
Junxiao Shi60607c72014-11-26 22:40:36 -0700199 * auto&& enumerable = nt.fullEnumerate();
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000200 * for (const Entry& nte : enumerable) {
Junxiao Shi60607c72014-11-26 22:40:36 -0700201 * ...
202 * }
203 * \endcode
Junxiao Shie3cf2852016-08-09 03:50:56 +0000204 * \note Iteration order is implementation-specific and is undefined.
205 * \warning If a name tree entry is inserted or deleted during the enumeration,
206 * it may cause the enumeration to skip entries or visit some entries twice.
HYuana9b85752014-02-26 02:32:30 -0600207 */
Junxiao Shi5ccd0c22014-12-02 23:54:42 -0700208 boost::iterator_range<const_iterator>
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000209 fullEnumerate(const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600210
Junxiao Shie3cf2852016-08-09 03:50:56 +0000211 /** \brief enumerate all entries under a prefix
Junxiao Shi60607c72014-11-26 22:40:36 -0700212 * \return an unspecified type that have .begin() and .end() methods
Junxiao Shie3cf2852016-08-09 03:50:56 +0000213 * and is usable with range-based for.
214 * Every entry in the range has a name that starts with \p prefix,
215 * and matches \p entrySubTreeSelector.
Junxiao Shi60607c72014-11-26 22:40:36 -0700216 *
217 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000218 * \code
219 * Name name("/A/B/C");
220 * auto&& enumerable = nt.partialEnumerate(name);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000221 * for (const Entry& nte : enumerable) {
Junxiao Shie3cf2852016-08-09 03:50:56 +0000222 * BOOST_ASSERT(name.isPrefixOf(nte.getName()));
Junxiao Shi60607c72014-11-26 22:40:36 -0700223 * ...
224 * }
225 * \endcode
Junxiao Shie3cf2852016-08-09 03:50:56 +0000226 * \note Iteration order is implementation-specific and is undefined.
227 * \warning If a name tree entry under \p prefix is inserted or deleted during the enumeration,
228 * it may cause the enumeration to skip entries or visit some entries twice.
Junxiao Shi60607c72014-11-26 22:40:36 -0700229 */
Junxiao Shi5ccd0c22014-12-02 23:54:42 -0700230 boost::iterator_range<const_iterator>
Junxiao Shi40631842014-03-01 13:52:37 -0700231 partialEnumerate(const Name& prefix,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000232 const EntrySubTreeSelector& entrySubTreeSelector = AnyEntrySubTree()) const;
HYuana9b85752014-02-26 02:32:30 -0600233
Junxiao Shie3cf2852016-08-09 03:50:56 +0000234 /** \return an iterator to enumerate all entries
235 * \sa fullEnumerate
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800236 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600237 const_iterator
Junxiao Shib660b4c2016-08-06 20:47:44 +0000238 begin() const
239 {
240 return fullEnumerate().begin();
241 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600242
Junxiao Shie3cf2852016-08-09 03:50:56 +0000243 /** \return a past-the-end iterator
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800244 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600245 const_iterator
Junxiao Shib660b4c2016-08-06 20:47:44 +0000246 end() const
247 {
248 return Iterator();
249 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600250
HYuana9b85752014-02-26 02:32:30 -0600251private:
Junxiao Shib660b4c2016-08-06 20:47:44 +0000252 Hashtable m_ht;
Junxiao Shib184e532016-05-26 18:09:57 +0000253
Junxiao Shib660b4c2016-08-06 20:47:44 +0000254 friend class EnumerationImpl;
HYuana9b85752014-02-26 02:32:30 -0600255};
256
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000257} // namespace name_tree
258
259using name_tree::NameTree;
260
HYuana9b85752014-02-26 02:32:30 -0600261} // namespace nfd
262
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700263#endif // NFD_DAEMON_TABLE_NAME_TREE_HPP