blob: c27dd2422a7e8963a666e45f02df3ed125f966d3 [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 Shie3cf2852016-08-09 03:50:56 +000061 /** \return entry on which a table entry is attached
Junxiao Shib184e532016-05-26 18:09:57 +000062 */
63 template<typename ENTRY>
Junxiao Shi2570f3e2016-07-27 02:48:29 +000064 shared_ptr<Entry>
Junxiao Shib660b4c2016-08-06 20:47:44 +000065 getEntry(const ENTRY& tableEntry) const
66 {
67 return tableEntry.m_nameTreeEntry.lock();
68 }
Alexander Afanasyevb3033242014-08-04 11:09:05 -070069
70public: // mutation
Junxiao Shie3cf2852016-08-09 03:50:56 +000071 /** \brief find or insert an entry with specified name
72 * \param name a name prefix
73 * \return an entry with \p name
74 * \post an entry with \p name and all ancestors are created
Junxiao Shi2570f3e2016-07-27 02:48:29 +000075 * \note Existing iterators are unaffected.
HYuana9b85752014-02-26 02:32:30 -060076 */
Junxiao Shi2570f3e2016-07-27 02:48:29 +000077 shared_ptr<Entry>
Junxiao Shib660b4c2016-08-06 20:47:44 +000078 lookup(const Name& name);
HYuana9b85752014-02-26 02:32:30 -060079
Junxiao Shie3cf2852016-08-09 03:50:56 +000080 /** \brief equivalent to .lookup(fibEntry.getPrefix())
81 * \note This overload is more efficient than .lookup(const Name&) in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +000082 */
Junxiao Shi2570f3e2016-07-27 02:48:29 +000083 shared_ptr<Entry>
Junxiao Shib184e532016-05-26 18:09:57 +000084 lookup(const fib::Entry& fibEntry) const;
85
Junxiao Shie3cf2852016-08-09 03:50:56 +000086 /** \brief equivalent to .lookup(pitEntry.getName()).
87 * \note This overload is more efficient than .lookup(const Name&) in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +000088 */
Junxiao Shi2570f3e2016-07-27 02:48:29 +000089 shared_ptr<Entry>
Junxiao Shib184e532016-05-26 18:09:57 +000090 lookup(const pit::Entry& pitEntry);
91
Junxiao Shie3cf2852016-08-09 03:50:56 +000092 /** \brief equivalent to .lookup(measurementsEntry.getName())
93 * \note This overload is more efficient than .lookup(const Name&) in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +000094 */
Junxiao Shi2570f3e2016-07-27 02:48:29 +000095 shared_ptr<Entry>
Junxiao Shib184e532016-05-26 18:09:57 +000096 lookup(const measurements::Entry& measurementsEntry) const;
97
Junxiao Shie3cf2852016-08-09 03:50:56 +000098 /** \brief equivalent to .lookup(strategyChoiceEntry.getName())
99 * \note This overload is more efficient than .lookup(const Name&) in common cases.
Junxiao Shib184e532016-05-26 18:09:57 +0000100 */
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000101 shared_ptr<Entry>
Junxiao Shib184e532016-05-26 18:09:57 +0000102 lookup(const strategy_choice::Entry& strategyChoiceEntry) const;
103
Junxiao Shie3cf2852016-08-09 03:50:56 +0000104 /** \brief delete the entry if it is empty
105 * \param entry a valid entry
106 * \return number of deleted entries
107 * \sa Entry::isEmpty()
108 * \post If the entry is empty, it's deleted.
109 * Ancestors of the entry are also deleted if they become empty.
110 * \note This function must be called after detaching a table entry from a name tree entry,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000111 * \note Existing iterators, except those pointing to deleted entries, are unaffected.
HYuana9b85752014-02-26 02:32:30 -0600112 */
Junxiao Shib660b4c2016-08-06 20:47:44 +0000113 size_t
Junxiao Shie3cf2852016-08-09 03:50:56 +0000114 eraseIfEmpty(Entry* entry);
HYuana9b85752014-02-26 02:32:30 -0600115
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700116public: // matching
Junxiao Shie3cf2852016-08-09 03:50:56 +0000117 /** \brief exact match lookup
118 * \return entry with \p name, or nullptr if it does not exist
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700119 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000120 Entry*
Junxiao Shib660b4c2016-08-06 20:47:44 +0000121 findExactMatch(const Name& name) const;
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700122
Junxiao Shie3cf2852016-08-09 03:50:56 +0000123 /** \brief longest prefix matching
124 * \return entry whose name is a prefix of \p name and passes \p entrySelector,
125 * where no other entry with a longer name satisfies those requirements;
126 * or nullptr if no entry satisfying those requirements exists
HYuana9b85752014-02-26 02:32:30 -0600127 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000128 Entry*
Junxiao Shib660b4c2016-08-06 20:47:44 +0000129 findLongestPrefixMatch(const Name& name,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000130 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600131
Junxiao Shi811c0102016-08-10 04:12:45 +0000132 /** \brief equivalent to .findLongestPrefixMatch(entry.getName(), entrySelector)
Junxiao Shie3cf2852016-08-09 03:50:56 +0000133 * \note This overload is more efficient than .findLongestPrefixMatch(const Name&)
134 * in common cases.
135 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000136 Entry*
137 findLongestPrefixMatch(const Entry& entry,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000138 const EntrySelector& entrySelector = AnyEntry()) const;
HangZhangcb4fc832014-03-11 16:57:11 +0800139
Junxiao Shie3cf2852016-08-09 03:50:56 +0000140 /** \brief equivalent to .findLongestPrefixMatch(pitEntry.getName(), AnyEntry())
141 * \note This overload is more efficient than .findLongestPrefixMatch(const Name&)
142 * in common cases.
Junxiao Shi4370fde2016-02-24 12:20:46 -0700143 */
Junxiao Shi811c0102016-08-10 04:12:45 +0000144 Entry*
Junxiao Shi4370fde2016-02-24 12:20:46 -0700145 findLongestPrefixMatch(const pit::Entry& pitEntry) const;
146
Junxiao Shie3cf2852016-08-09 03:50:56 +0000147 /** \brief all-prefixes match lookup
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700148 * \return an unspecified type that have .begin() and .end() methods
Junxiao Shie3cf2852016-08-09 03:50:56 +0000149 * and is usable with range-based for.
150 * Every entry in the range has a name that is a prefix of \p name ,
151 * and matches \p entrySelector.
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700152 *
153 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000154 * \code
155 * Name name("/A/B/C");
156 * auto&& allMatches = nt.findAllMatches(name);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000157 * for (const Entry& nte : allMatches) {
Junxiao Shie3cf2852016-08-09 03:50:56 +0000158 * BOOST_ASSERT(nte.getName().isPrefixOf(name));
Junxiao Shi2b73ca32014-11-17 19:16:08 -0700159 * ...
160 * }
161 * \endcode
Junxiao Shie3cf2852016-08-09 03:50:56 +0000162 * \note Iteration order is implementation-specific and is undefined.
163 * \warning If a name tree entry whose name is a prefix of \p name is inserted
164 * during the enumeration, it may or may not be visited.
165 * If a name tree entry whose name is a prefix of \p name is deleted
166 * during the enumeration, undefined behavior may occur.
HYuana9b85752014-02-26 02:32:30 -0600167 */
Junxiao Shi5ccd0c22014-12-02 23:54:42 -0700168 boost::iterator_range<const_iterator>
Junxiao Shie3cf2852016-08-09 03:50:56 +0000169 findAllMatches(const Name& name,
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000170 const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600171
Alexander Afanasyevb3033242014-08-04 11:09:05 -0700172public: // enumeration
Junxiao Shie3cf2852016-08-09 03:50:56 +0000173 /** \brief enumerate all entries
Junxiao Shi60607c72014-11-26 22:40:36 -0700174 * \return an unspecified type that have .begin() and .end() methods
Junxiao Shie3cf2852016-08-09 03:50:56 +0000175 * and is usable with range-based for.
176 * Every entry in the range matches \p entrySelector.
Junxiao Shi60607c72014-11-26 22:40:36 -0700177 *
178 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000179 * \code
Junxiao Shi60607c72014-11-26 22:40:36 -0700180 * auto&& enumerable = nt.fullEnumerate();
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000181 * for (const Entry& nte : enumerable) {
Junxiao Shi60607c72014-11-26 22:40:36 -0700182 * ...
183 * }
184 * \endcode
Junxiao Shie3cf2852016-08-09 03:50:56 +0000185 * \note Iteration order is implementation-specific and is undefined.
186 * \warning If a name tree entry is inserted or deleted during the enumeration,
187 * it may cause the enumeration to skip entries or visit some entries twice.
HYuana9b85752014-02-26 02:32:30 -0600188 */
Junxiao Shi5ccd0c22014-12-02 23:54:42 -0700189 boost::iterator_range<const_iterator>
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000190 fullEnumerate(const EntrySelector& entrySelector = AnyEntry()) const;
HYuana9b85752014-02-26 02:32:30 -0600191
Junxiao Shie3cf2852016-08-09 03:50:56 +0000192 /** \brief enumerate all entries under a prefix
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 has a name that starts with \p prefix,
196 * and matches \p entrySubTreeSelector.
Junxiao Shi60607c72014-11-26 22:40:36 -0700197 *
198 * Example:
Junxiao Shie3cf2852016-08-09 03:50:56 +0000199 * \code
200 * Name name("/A/B/C");
201 * auto&& enumerable = nt.partialEnumerate(name);
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000202 * for (const Entry& nte : enumerable) {
Junxiao Shie3cf2852016-08-09 03:50:56 +0000203 * BOOST_ASSERT(name.isPrefixOf(nte.getName()));
Junxiao Shi60607c72014-11-26 22:40:36 -0700204 * ...
205 * }
206 * \endcode
Junxiao Shie3cf2852016-08-09 03:50:56 +0000207 * \note Iteration order is implementation-specific and is undefined.
208 * \warning If a name tree entry under \p prefix is inserted or deleted during the enumeration,
209 * it may cause the enumeration to skip entries or visit some entries twice.
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
Junxiao Shie3cf2852016-08-09 03:50:56 +0000215 /** \return an iterator to enumerate all entries
216 * \sa fullEnumerate
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800217 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600218 const_iterator
Junxiao Shib660b4c2016-08-06 20:47:44 +0000219 begin() const
220 {
221 return fullEnumerate().begin();
222 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600223
Junxiao Shie3cf2852016-08-09 03:50:56 +0000224 /** \return a past-the-end iterator
Alexander Afanasyev09fc3d92015-01-03 02:02:37 -0800225 */
Haowei Yuane1079fc2014-03-08 14:41:25 -0600226 const_iterator
Junxiao Shib660b4c2016-08-06 20:47:44 +0000227 end() const
228 {
229 return Iterator();
230 }
Haowei Yuane1079fc2014-03-08 14:41:25 -0600231
HYuana9b85752014-02-26 02:32:30 -0600232private:
Junxiao Shib660b4c2016-08-06 20:47:44 +0000233 Hashtable m_ht;
Junxiao Shib184e532016-05-26 18:09:57 +0000234
Junxiao Shib660b4c2016-08-06 20:47:44 +0000235 friend class EnumerationImpl;
HYuana9b85752014-02-26 02:32:30 -0600236};
237
Junxiao Shi2570f3e2016-07-27 02:48:29 +0000238} // namespace name_tree
239
240using name_tree::NameTree;
241
HYuana9b85752014-02-26 02:32:30 -0600242} // namespace nfd
243
Alexander Afanasyev613e2a92014-04-15 13:36:58 -0700244#endif // NFD_DAEMON_TABLE_NAME_TREE_HPP