blob: 9c21f7e760b1b224a1bb8f9169c03c180e5077dd [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 Shie3cf2852016-08-09 03:50:56 +0000102 /** \brief equivalent to .lookup(strategyChoiceEntry.getName())
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 Shie3cf2852016-08-09 03:50:56 +0000145 /** \brief equivalent to .findLongestPrefixMatch(pitEntry.getName(), AnyEntry())
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 Shi4370fde2016-02-24 12:20:46 -0700148 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000149 Entry*
Junxiao Shif2420fc2016-08-11 13:18:21 +0000150 findLongestPrefixMatch(const pit::Entry& pitEntry,
151 const EntrySelector& entrySelector = AnyEntry()) const;
Junxiao Shi4370fde2016-02-24 12:20:46 -0700152
Junxiao Shie3cf2852016-08-09 03:50:56 +0000153 /** \brief all-prefixes match lookup
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700154 * \return an unspecified type that have .begin() and .end() methods
Junxiao Shie3cf2852016-08-09 03:50:56 +0000155 * and is usable with range-based for.
156 * Every entry in the range has a name that is a prefix of \p name ,
157 * and matches \p entrySelector.
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700158 *
159 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000160 * \code
161 * Name name("/A/B/C");
162 * auto&& allMatches = nt.findAllMatches(name);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000163 * for (const Entry& nte : allMatches) {
Junxiao Shie3cf2852016-08-09 03:50:56 +0000164 * BOOST_ASSERT(nte.getName().isPrefixOf(name));
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700165 * ...
166 * }
167 * \endcode
Junxiao Shie3cf2852016-08-09 03:50:56 +0000168 * \note Iteration order is implementation-specific and is undefined.
169 * \warning If a name tree entry whose name is a prefix of \p name is inserted
170 * during the enumeration, it may or may not be visited.
171 * If a name tree entry whose name is a prefix of \p name is deleted
172 * during the enumeration, undefined behavior may occur.
HYuana9b85752014-02-26 02:32:30 -0600173 */
Junxiao Shi5ccd0c22014-12-02 23:54:42 -0700174 boost::iterator_range<const_iterator>
Junxiao Shie3cf2852016-08-09 03:50:56 +0000175 findAllMatches(const Name& name,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000176 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600177
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700178public: // enumeration
Junxiao Shie3cf2852016-08-09 03:50:56 +0000179 /** \brief enumerate all entries
Junxiao Shi60607c72014-11-26 22:40:36 -0700180 * \return an unspecified type that have .begin() and .end() methods
Junxiao Shie3cf2852016-08-09 03:50:56 +0000181 * and is usable with range-based for.
182 * Every entry in the range matches \p entrySelector.
Junxiao Shi60607c72014-11-26 22:40:36 -0700183 *
184 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000185 * \code
Junxiao Shi60607c72014-11-26 22:40:36 -0700186 * 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
Junxiao Shie3cf2852016-08-09 03:50:56 +0000191 * \note Iteration order is implementation-specific and is undefined.
192 * \warning If a name tree entry is inserted or deleted during the enumeration,
193 * it may cause the enumeration to skip entries or visit some entries twice.
HYuana9b85752014-02-26 02:32:30 -0600194 */
Junxiao Shi5ccd0c22014-12-02 23:54:42 -0700195 boost::iterator_range<const_iterator>
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000196 fullEnumerate(const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600197
Junxiao Shie3cf2852016-08-09 03:50:56 +0000198 /** \brief enumerate all entries under a prefix
Junxiao Shi60607c72014-11-26 22:40:36 -0700199 * \return an unspecified type that have .begin() and .end() methods
Junxiao Shie3cf2852016-08-09 03:50:56 +0000200 * and is usable with range-based for.
201 * Every entry in the range has a name that starts with \p prefix,
202 * and matches \p entrySubTreeSelector.
Junxiao Shi60607c72014-11-26 22:40:36 -0700203 *
204 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000205 * \code
206 * Name name("/A/B/C");
207 * auto&& enumerable = nt.partialEnumerate(name);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000208 * for (const Entry& nte : enumerable) {
Junxiao Shie3cf2852016-08-09 03:50:56 +0000209 * BOOST_ASSERT(name.isPrefixOf(nte.getName()));
Junxiao Shi60607c72014-11-26 22:40:36 -0700210 * ...
211 * }
212 * \endcode
Junxiao Shie3cf2852016-08-09 03:50:56 +0000213 * \note Iteration order is implementation-specific and is undefined.
214 * \warning If a name tree entry under \p prefix is inserted or deleted during the enumeration,
215 * it may cause the enumeration to skip entries or visit some entries twice.
Junxiao Shi60607c72014-11-26 22:40:36 -0700216 */
Junxiao Shi5ccd0c22014-12-02 23:54:42 -0700217 boost::iterator_range<const_iterator>
Junxiao Shi40631842014-03-01 13:52:37 -0700218 partialEnumerate(const Name& prefix,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000219 const EntrySubTreeSelector& entrySubTreeSelector = AnyEntrySubTree()) const;
HYuana9b85752014-02-26 02:32:30 -0600220
Junxiao Shie3cf2852016-08-09 03:50:56 +0000221 /** \return an iterator to enumerate all entries
222 * \sa fullEnumerate
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800223 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600224 const_iterator
Junxiao Shib660b4c2016-08-06 20:47:44 +0000225 begin() const
226 {
227 return fullEnumerate().begin();
228 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600229
Junxiao Shie3cf2852016-08-09 03:50:56 +0000230 /** \return a past-the-end iterator
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800231 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600232 const_iterator
Junxiao Shib660b4c2016-08-06 20:47:44 +0000233 end() const
234 {
235 return Iterator();
236 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600237
HYuana9b85752014-02-26 02:32:30 -0600238private:
Junxiao Shib660b4c2016-08-06 20:47:44 +0000239 Hashtable m_ht;
Junxiao Shib184e532016-05-26 18:09:57 +0000240
Junxiao Shib660b4c2016-08-06 20:47:44 +0000241 friend class EnumerationImpl;
HYuana9b85752014-02-26 02:32:30 -0600242};
243
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000244} // namespace name_tree
245
246using name_tree::NameTree;
247
HYuana9b85752014-02-26 02:32:30 -0600248} // namespace nfd
249
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700250#endif // NFD_DAEMON_TABLE_NAME_TREE_HPP