blob: 9ddf0ffcdbb2bad96279da1759b27e15aea9ff31 [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 Shi7f358432016-08-11 17:06:33 +000068 return tableEntry.m_nameTreeEntry.lock().get();
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
111 * \return number of deleted entries
112 * \sa Entry::isEmpty()
113 * \post If the entry is empty, it's deleted.
114 * Ancestors of the entry are also deleted if they become empty.
115 * \note This function must be called after detaching a table entry from a name tree entry,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000116 * \note Existing iterators, except those pointing to deleted entries, are unaffected.
HYuana9b85752014-02-26 02:32:30 -0600117 */
Junxiao Shib660b4c2016-08-06 20:47:44 +0000118 size_t
Junxiao Shie3cf2852016-08-09 03:50:56 +0000119 eraseIfEmpty(Entry* entry);
HYuana9b85752014-02-26 02:32:30 -0600120
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700121public: // matching
Junxiao Shie3cf2852016-08-09 03:50:56 +0000122 /** \brief exact match lookup
123 * \return entry with \p name, or nullptr if it does not exist
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700124 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000125 Entry*
Junxiao Shib660b4c2016-08-06 20:47:44 +0000126 findExactMatch(const Name& name) const;
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700127
Junxiao Shie3cf2852016-08-09 03:50:56 +0000128 /** \brief longest prefix matching
129 * \return entry whose name is a prefix of \p name and passes \p entrySelector,
130 * where no other entry with a longer name satisfies those requirements;
131 * or nullptr if no entry satisfying those requirements exists
HYuana9b85752014-02-26 02:32:30 -0600132 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000133 Entry*
Junxiao Shib660b4c2016-08-06 20:47:44 +0000134 findLongestPrefixMatch(const Name& name,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000135 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600136
Junxiao Shi811c0102016-08-10 04:12:45 +0000137 /** \brief equivalent to .findLongestPrefixMatch(entry.getName(), entrySelector)
Junxiao Shif2420fc2016-08-11 13:18:21 +0000138 * \note This overload is more efficient than
139 * .findLongestPrefixMatch(const Name&, const EntrySelector&) in common cases.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000140 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000141 Entry*
142 findLongestPrefixMatch(const Entry& entry,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000143 const EntrySelector& entrySelector = AnyEntry()) const;
HangZhangcb4fc832014-03-11 16:57:11 +0800144
Junxiao Shidd8f6612016-08-12 15:42:52 +0000145 /** \brief equivalent to .findLongestPrefixMatch(getEntry(tableEntry)->getName(), entrySelector)
146 * \tparam ENTRY fib::Entry or measurements::Entry or strategy_choice::Entry
Junxiao Shif2420fc2016-08-11 13:18:21 +0000147 * \note This overload is more efficient than
148 * .findLongestPrefixMatch(const Name&, const EntrySelector&) in common cases.
Junxiao Shidd8f6612016-08-12 15:42:52 +0000149 * \warning Undefined behavior may occur if tableEntry is not attached to this name tree.
150 */
151 template<typename ENTRY>
152 Entry*
153 findLongestPrefixMatch(const ENTRY& tableEntry,
154 const EntrySelector& entrySelector = AnyEntry()) const;
155
156 /** \brief equivalent to .findLongestPrefixMatch(pitEntry.getName(), entrySelector)
157 * \note This overload is more efficient than
158 * .findLongestPrefixMatch(const Name&, const EntrySelector&) in common cases.
159 * \warning Undefined behavior may occur if pitEntry is not attached to this name tree.
Junxiao Shi4370fde2016-02-24 12:20:46 -0700160 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000161 Entry*
Junxiao Shif2420fc2016-08-11 13:18:21 +0000162 findLongestPrefixMatch(const pit::Entry& pitEntry,
163 const EntrySelector& entrySelector = AnyEntry()) const;
Junxiao Shi4370fde2016-02-24 12:20:46 -0700164
Junxiao Shie3cf2852016-08-09 03:50:56 +0000165 /** \brief all-prefixes match lookup
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700166 * \return an unspecified type that have .begin() and .end() methods
Junxiao Shie3cf2852016-08-09 03:50:56 +0000167 * and is usable with range-based for.
168 * Every entry in the range has a name that is a prefix of \p name ,
169 * and matches \p entrySelector.
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700170 *
171 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000172 * \code
173 * Name name("/A/B/C");
174 * auto&& allMatches = nt.findAllMatches(name);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000175 * for (const Entry& nte : allMatches) {
Junxiao Shie3cf2852016-08-09 03:50:56 +0000176 * BOOST_ASSERT(nte.getName().isPrefixOf(name));
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700177 * ...
178 * }
179 * \endcode
Junxiao Shie3cf2852016-08-09 03:50:56 +0000180 * \note Iteration order is implementation-specific and is undefined.
181 * \warning If a name tree entry whose name is a prefix of \p name is inserted
182 * during the enumeration, it may or may not be visited.
183 * If a name tree entry whose name is a prefix of \p name is deleted
184 * during the enumeration, undefined behavior may occur.
HYuana9b85752014-02-26 02:32:30 -0600185 */
Junxiao Shi5ccd0c22014-12-02 23:54:42 -0700186 boost::iterator_range<const_iterator>
Junxiao Shie3cf2852016-08-09 03:50:56 +0000187 findAllMatches(const Name& name,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000188 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600189
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700190public: // enumeration
Junxiao Shie3cf2852016-08-09 03:50:56 +0000191 /** \brief enumerate all entries
Junxiao Shi60607c72014-11-26 22:40:36 -0700192 * \return an unspecified type that have .begin() and .end() methods
Junxiao Shie3cf2852016-08-09 03:50:56 +0000193 * and is usable with range-based for.
194 * Every entry in the range matches \p entrySelector.
Junxiao Shi60607c72014-11-26 22:40:36 -0700195 *
196 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000197 * \code
Junxiao Shi60607c72014-11-26 22:40:36 -0700198 * auto&& enumerable = nt.fullEnumerate();
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000199 * for (const Entry& nte : enumerable) {
Junxiao Shi60607c72014-11-26 22:40:36 -0700200 * ...
201 * }
202 * \endcode
Junxiao Shie3cf2852016-08-09 03:50:56 +0000203 * \note Iteration order is implementation-specific and is undefined.
204 * \warning If a name tree entry is inserted or deleted during the enumeration,
205 * it may cause the enumeration to skip entries or visit some entries twice.
HYuana9b85752014-02-26 02:32:30 -0600206 */
Junxiao Shi5ccd0c22014-12-02 23:54:42 -0700207 boost::iterator_range<const_iterator>
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000208 fullEnumerate(const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600209
Junxiao Shie3cf2852016-08-09 03:50:56 +0000210 /** \brief enumerate all entries under a prefix
Junxiao Shi60607c72014-11-26 22:40:36 -0700211 * \return an unspecified type that have .begin() and .end() methods
Junxiao Shie3cf2852016-08-09 03:50:56 +0000212 * and is usable with range-based for.
213 * Every entry in the range has a name that starts with \p prefix,
214 * and matches \p entrySubTreeSelector.
Junxiao Shi60607c72014-11-26 22:40:36 -0700215 *
216 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000217 * \code
218 * Name name("/A/B/C");
219 * auto&& enumerable = nt.partialEnumerate(name);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000220 * for (const Entry& nte : enumerable) {
Junxiao Shie3cf2852016-08-09 03:50:56 +0000221 * BOOST_ASSERT(name.isPrefixOf(nte.getName()));
Junxiao Shi60607c72014-11-26 22:40:36 -0700222 * ...
223 * }
224 * \endcode
Junxiao Shie3cf2852016-08-09 03:50:56 +0000225 * \note Iteration order is implementation-specific and is undefined.
226 * \warning If a name tree entry under \p prefix is inserted or deleted during the enumeration,
227 * it may cause the enumeration to skip entries or visit some entries twice.
Junxiao Shi60607c72014-11-26 22:40:36 -0700228 */
Junxiao Shi5ccd0c22014-12-02 23:54:42 -0700229 boost::iterator_range<const_iterator>
Junxiao Shi40631842014-03-01 13:52:37 -0700230 partialEnumerate(const Name& prefix,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000231 const EntrySubTreeSelector& entrySubTreeSelector = AnyEntrySubTree()) const;
HYuana9b85752014-02-26 02:32:30 -0600232
Junxiao Shie3cf2852016-08-09 03:50:56 +0000233 /** \return an iterator to enumerate all entries
234 * \sa fullEnumerate
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800235 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600236 const_iterator
Junxiao Shib660b4c2016-08-06 20:47:44 +0000237 begin() const
238 {
239 return fullEnumerate().begin();
240 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600241
Junxiao Shie3cf2852016-08-09 03:50:56 +0000242 /** \return a past-the-end iterator
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800243 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600244 const_iterator
Junxiao Shib660b4c2016-08-06 20:47:44 +0000245 end() const
246 {
247 return Iterator();
248 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600249
HYuana9b85752014-02-26 02:32:30 -0600250private:
Junxiao Shib660b4c2016-08-06 20:47:44 +0000251 Hashtable m_ht;
Junxiao Shib184e532016-05-26 18:09:57 +0000252
Junxiao Shib660b4c2016-08-06 20:47:44 +0000253 friend class EnumerationImpl;
HYuana9b85752014-02-26 02:32:30 -0600254};
255
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000256} // namespace name_tree
257
258using name_tree::NameTree;
259
HYuana9b85752014-02-26 02:32:30 -0600260} // namespace nfd
261
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700262#endif // NFD_DAEMON_TABLE_NAME_TREE_HPP