blob: 5c31103eb1f43b2a5c1ef6abdefffacb8d2adfbf [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:
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
Junxiao Shie3cf2852016-08-09 03:50:56 +000043 /** \return number of name tree entries
HYuana9b85752014-02-26 02:32:30 -060044 */
45 size_t
Junxiao Shib660b4c2016-08-06 20:47:44 +000046 size() const
47 {
48 return m_ht.size();
49 }
HYuana9b85752014-02-26 02:32:30 -060050
Junxiao Shie3cf2852016-08-09 03:50:56 +000051 /** \return number of hashtable buckets
HYuana9b85752014-02-26 02:32:30 -060052 */
53 size_t
Junxiao Shib660b4c2016-08-06 20:47:44 +000054 getNBuckets() const
55 {
56 return m_ht.getNBuckets();
57 }
HYuana9b85752014-02-26 02:32:30 -060058
Junxiao Shif2420fc2016-08-11 13:18:21 +000059 /** \return name tree entry on which a table entry is attached,
60 * or nullptr if the table entry is detached
Junxiao Shib184e532016-05-26 18:09:57 +000061 */
62 template<typename ENTRY>
Junxiao Shi7f358432016-08-11 17:06:33 +000063 Entry*
Junxiao Shib660b4c2016-08-06 20:47:44 +000064 getEntry(const ENTRY& tableEntry) const
65 {
Junxiao Shi340d5532016-08-13 04:00:35 +000066 return Entry::get(tableEntry);
Junxiao Shib660b4c2016-08-06 20:47:44 +000067 }
Alexander Afanasyevb3033242014-08-04 11:09:05 -070068
69public: // mutation
Junxiao Shie3cf2852016-08-09 03:50:56 +000070 /** \brief find or insert an entry with specified name
71 * \param name a name prefix
72 * \return an entry with \p name
73 * \post an entry with \p name and all ancestors are created
Junxiao Shi2570f3e2016-07-27 02:48:29 +000074 * \note Existing iterators are unaffected.
HYuana9b85752014-02-26 02:32:30 -060075 */
Junxiao Shi7f358432016-08-11 17:06:33 +000076 Entry&
Junxiao Shib660b4c2016-08-06 20:47:44 +000077 lookup(const Name& name);
HYuana9b85752014-02-26 02:32:30 -060078
Junxiao Shie3cf2852016-08-09 03:50:56 +000079 /** \brief equivalent to .lookup(fibEntry.getPrefix())
Junxiao Shif2420fc2016-08-11 13:18:21 +000080 * \param fibEntry a FIB entry attached to this name tree, or Fib::s_emptyEntry
Junxiao Shie3cf2852016-08-09 03:50:56 +000081 * \note This overload is more efficient than .lookup(const Name&) in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +000082 */
Junxiao Shi7f358432016-08-11 17:06:33 +000083 Entry&
Junxiao Shif2420fc2016-08-11 13:18:21 +000084 lookup(const fib::Entry& fibEntry);
Junxiao Shib184e532016-05-26 18:09:57 +000085
Junxiao Shie3cf2852016-08-09 03:50:56 +000086 /** \brief equivalent to .lookup(pitEntry.getName()).
Junxiao Shif2420fc2016-08-11 13:18:21 +000087 * \param pitEntry a PIT entry attached to this name tree
Junxiao Shie3cf2852016-08-09 03:50:56 +000088 * \note This overload is more efficient than .lookup(const Name&) in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +000089 */
Junxiao Shi7f358432016-08-11 17:06:33 +000090 Entry&
Junxiao Shib184e532016-05-26 18:09:57 +000091 lookup(const pit::Entry& pitEntry);
92
Junxiao Shie3cf2852016-08-09 03:50:56 +000093 /** \brief equivalent to .lookup(measurementsEntry.getName())
Junxiao Shif2420fc2016-08-11 13:18:21 +000094 * \param measurementsEntry a Measurements entry attached to this name tree
Junxiao Shie3cf2852016-08-09 03:50:56 +000095 * \note This overload is more efficient than .lookup(const Name&) in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +000096 */
Junxiao Shi7f358432016-08-11 17:06:33 +000097 Entry&
Junxiao Shif2420fc2016-08-11 13:18:21 +000098 lookup(const measurements::Entry& measurementsEntry);
Junxiao Shib184e532016-05-26 18:09:57 +000099
Junxiao Shidd8f6612016-08-12 15:42:52 +0000100 /** \brief equivalent to .lookup(strategyChoiceEntry.getPrefix())
Junxiao Shif2420fc2016-08-11 13:18:21 +0000101 * \param strategyChoiceEntry a StrategyChoice entry attached to this name tree
Junxiao Shie3cf2852016-08-09 03:50:56 +0000102 * \note This overload is more efficient than .lookup(const Name&) in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +0000103 */
Junxiao Shi7f358432016-08-11 17:06:33 +0000104 Entry&
Junxiao Shif2420fc2016-08-11 13:18:21 +0000105 lookup(const strategy_choice::Entry& strategyChoiceEntry);
Junxiao Shib184e532016-05-26 18:09:57 +0000106
Junxiao Shie3cf2852016-08-09 03:50:56 +0000107 /** \brief delete the entry if it is empty
108 * \param entry a valid entry
Junxiao Shie7258ff2016-08-12 23:55:47 +0000109 * \param canEraseAncestors whether ancestors should be deleted if they become empty
Junxiao Shie3cf2852016-08-09 03:50:56 +0000110 * \return number of deleted entries
111 * \sa Entry::isEmpty()
Junxiao Shie7258ff2016-08-12 23:55:47 +0000112 * \post If the entry is empty, it's deleted. If canEraseAncestors is true,
113 * ancestors of the entry are also deleted if they become empty.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000114 * \note This function must be called after detaching a table entry from a name tree entry,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000115 * \note Existing iterators, except those pointing to deleted entries, are unaffected.
HYuana9b85752014-02-26 02:32:30 -0600116 */
Junxiao Shib660b4c2016-08-06 20:47:44 +0000117 size_t
Junxiao Shie7258ff2016-08-12 23:55:47 +0000118 eraseIfEmpty(Entry* entry, bool canEraseAncestors = true);
HYuana9b85752014-02-26 02:32:30 -0600119
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700120public: // matching
Junxiao Shie3cf2852016-08-09 03:50:56 +0000121 /** \brief exact match lookup
122 * \return entry with \p name, or nullptr if it does not exist
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700123 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000124 Entry*
Junxiao Shib660b4c2016-08-06 20:47:44 +0000125 findExactMatch(const Name& name) const;
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700126
Junxiao Shie3cf2852016-08-09 03:50:56 +0000127 /** \brief longest prefix matching
128 * \return entry whose name is a prefix of \p name and passes \p entrySelector,
129 * where no other entry with a longer name satisfies those requirements;
130 * or nullptr if no entry satisfying those requirements exists
HYuana9b85752014-02-26 02:32:30 -0600131 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000132 Entry*
Junxiao Shib660b4c2016-08-06 20:47:44 +0000133 findLongestPrefixMatch(const Name& name,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000134 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600135
Junxiao Shi811c0102016-08-10 04:12:45 +0000136 /** \brief equivalent to .findLongestPrefixMatch(entry.getName(), entrySelector)
Junxiao Shif2420fc2016-08-11 13:18:21 +0000137 * \note This overload is more efficient than
138 * .findLongestPrefixMatch(const Name&, const EntrySelector&) in common cases.
Junxiao Shie3cf2852016-08-09 03:50:56 +0000139 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000140 Entry*
141 findLongestPrefixMatch(const Entry& entry,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000142 const EntrySelector& entrySelector = AnyEntry()) const;
HangZhangcb4fc832014-03-11 16:57:11 +0800143
Junxiao Shidd8f6612016-08-12 15:42:52 +0000144 /** \brief equivalent to .findLongestPrefixMatch(getEntry(tableEntry)->getName(), entrySelector)
145 * \tparam ENTRY fib::Entry or measurements::Entry or strategy_choice::Entry
Junxiao Shif2420fc2016-08-11 13:18:21 +0000146 * \note This overload is more efficient than
147 * .findLongestPrefixMatch(const Name&, const EntrySelector&) in common cases.
Junxiao Shidd8f6612016-08-12 15:42:52 +0000148 * \warning Undefined behavior may occur if tableEntry is not attached to this name tree.
149 */
150 template<typename ENTRY>
151 Entry*
152 findLongestPrefixMatch(const ENTRY& tableEntry,
153 const EntrySelector& entrySelector = AnyEntry()) const;
154
155 /** \brief equivalent to .findLongestPrefixMatch(pitEntry.getName(), entrySelector)
156 * \note This overload is more efficient than
157 * .findLongestPrefixMatch(const Name&, const EntrySelector&) in common cases.
158 * \warning Undefined behavior may occur if pitEntry is not attached to this name tree.
Junxiao Shi4370fde2016-02-24 12:20:46 -0700159 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000160 Entry*
Junxiao Shif2420fc2016-08-11 13:18:21 +0000161 findLongestPrefixMatch(const pit::Entry& pitEntry,
162 const EntrySelector& entrySelector = AnyEntry()) const;
Junxiao Shi4370fde2016-02-24 12:20:46 -0700163
Junxiao Shie3cf2852016-08-09 03:50:56 +0000164 /** \brief all-prefixes match lookup
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000165 * \return a range where every entry has a name that is a prefix of \p name ,
Junxiao Shie3cf2852016-08-09 03:50:56 +0000166 * and matches \p entrySelector.
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700167 *
168 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000169 * \code
170 * Name name("/A/B/C");
171 * auto&& allMatches = nt.findAllMatches(name);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000172 * for (const Entry& nte : allMatches) {
Junxiao Shie3cf2852016-08-09 03:50:56 +0000173 * BOOST_ASSERT(nte.getName().isPrefixOf(name));
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700174 * ...
175 * }
176 * \endcode
Junxiao Shie3cf2852016-08-09 03:50:56 +0000177 * \note Iteration order is implementation-specific and is undefined.
178 * \warning If a name tree entry whose name is a prefix of \p name is inserted
179 * during the enumeration, it may or may not be visited.
180 * If a name tree entry whose name is a prefix of \p name is deleted
181 * during the enumeration, undefined behavior may occur.
HYuana9b85752014-02-26 02:32:30 -0600182 */
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000183 Range
Junxiao Shie3cf2852016-08-09 03:50:56 +0000184 findAllMatches(const Name& name,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000185 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600186
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700187public: // enumeration
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000188 typedef Iterator const_iterator;
189
Junxiao Shie3cf2852016-08-09 03:50:56 +0000190 /** \brief enumerate all entries
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000191 * \return a range where every entry matches \p entrySelector
Junxiao Shi60607c72014-11-26 22:40:36 -0700192 *
193 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000194 * \code
Junxiao Shi60607c72014-11-26 22:40:36 -0700195 * auto&& enumerable = nt.fullEnumerate();
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000196 * for (const Entry& nte : enumerable) {
Junxiao Shi60607c72014-11-26 22:40:36 -0700197 * ...
198 * }
199 * \endcode
Junxiao Shie3cf2852016-08-09 03:50:56 +0000200 * \note Iteration order is implementation-specific and is undefined.
201 * \warning If a name tree entry is inserted or deleted during the enumeration,
202 * it may cause the enumeration to skip entries or visit some entries twice.
HYuana9b85752014-02-26 02:32:30 -0600203 */
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000204 Range
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000205 fullEnumerate(const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600206
Junxiao Shie3cf2852016-08-09 03:50:56 +0000207 /** \brief enumerate all entries under a prefix
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000208 * \return a range where every entry has a name that starts with \p prefix,
Junxiao Shie3cf2852016-08-09 03:50:56 +0000209 * and matches \p entrySubTreeSelector.
Junxiao Shi60607c72014-11-26 22:40:36 -0700210 *
211 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000212 * \code
213 * Name name("/A/B/C");
214 * auto&& enumerable = nt.partialEnumerate(name);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000215 * for (const Entry& nte : enumerable) {
Junxiao Shie3cf2852016-08-09 03:50:56 +0000216 * BOOST_ASSERT(name.isPrefixOf(nte.getName()));
Junxiao Shi60607c72014-11-26 22:40:36 -0700217 * ...
218 * }
219 * \endcode
Junxiao Shie3cf2852016-08-09 03:50:56 +0000220 * \note Iteration order is implementation-specific and is undefined.
221 * \warning If a name tree entry under \p prefix is inserted or deleted during the enumeration,
222 * it may cause the enumeration to skip entries or visit some entries twice.
Junxiao Shi60607c72014-11-26 22:40:36 -0700223 */
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000224 Range
Junxiao Shi40631842014-03-01 13:52:37 -0700225 partialEnumerate(const Name& prefix,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000226 const EntrySubTreeSelector& entrySubTreeSelector = AnyEntrySubTree()) const;
HYuana9b85752014-02-26 02:32:30 -0600227
Junxiao Shie3cf2852016-08-09 03:50:56 +0000228 /** \return an iterator to enumerate all entries
229 * \sa fullEnumerate
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800230 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600231 const_iterator
Junxiao Shib660b4c2016-08-06 20:47:44 +0000232 begin() const
233 {
234 return fullEnumerate().begin();
235 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600236
Junxiao Shie3cf2852016-08-09 03:50:56 +0000237 /** \return a past-the-end iterator
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800238 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600239 const_iterator
Junxiao Shib660b4c2016-08-06 20:47:44 +0000240 end() const
241 {
242 return Iterator();
243 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600244
HYuana9b85752014-02-26 02:32:30 -0600245private:
Junxiao Shib660b4c2016-08-06 20:47:44 +0000246 Hashtable m_ht;
Junxiao Shib184e532016-05-26 18:09:57 +0000247
Junxiao Shib660b4c2016-08-06 20:47:44 +0000248 friend class EnumerationImpl;
HYuana9b85752014-02-26 02:32:30 -0600249};
250
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000251} // namespace name_tree
252
253using name_tree::NameTree;
254
HYuana9b85752014-02-26 02:32:30 -0600255} // namespace nfd
256
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700257#endif // NFD_DAEMON_TABLE_NAME_TREE_HPP