blob: 4a76a53a68715ee196ce3c011dbf89f8939d8a21 [file] [log] [blame]
Junxiao Shi029401f2016-08-05 12:55:14 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyev847de402017-09-21 18:57:30 -04002/*
Davide Pesaventoe422f9e2022-06-03 01:30:23 -04003 * Copyright (c) 2014-2022, Regents of the University of California,
Junxiao Shi029401f2016-08-05 12:55:14 +00004 * 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.
10 *
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/>.
24 */
25
26#ifndef NFD_DAEMON_TABLE_NAME_TREE_ITERATOR_HPP
27#define NFD_DAEMON_TABLE_NAME_TREE_ITERATOR_HPP
28
Junxiao Shi340d5532016-08-13 04:00:35 +000029#include "name-tree-hashtable.hpp"
Junxiao Shi029401f2016-08-05 12:55:14 +000030
Davide Pesaventoa9b09b62022-06-04 14:07:25 -040031#include <boost/range/iterator_range_core.hpp>
32
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040033namespace nfd::name_tree {
Junxiao Shi029401f2016-08-05 12:55:14 +000034
Junxiao Shi340d5532016-08-13 04:00:35 +000035class NameTree;
36
Junxiao Shi029401f2016-08-05 12:55:14 +000037/** \brief a predicate to accept or reject an Entry in find operations
38 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -040039using EntrySelector = std::function<bool(const Entry&)>;
Junxiao Shi029401f2016-08-05 12:55:14 +000040
41/** \brief an EntrySelector that accepts every Entry
42 */
43struct AnyEntry
44{
45 bool
Davide Pesavento87fc0f82018-04-11 23:43:51 -040046 operator()(const Entry&) const
Junxiao Shi029401f2016-08-05 12:55:14 +000047 {
48 return true;
49 }
50};
51
52/** \brief a predicate to accept or reject an Entry and its children
Davide Pesavento87fc0f82018-04-11 23:43:51 -040053 * \return `.first` indicates whether entry should be accepted;
54 * `.second` indicates whether entry's children should be visited
Junxiao Shi029401f2016-08-05 12:55:14 +000055 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -040056using EntrySubTreeSelector = std::function<std::pair<bool, bool>(const Entry&)>;
Junxiao Shi029401f2016-08-05 12:55:14 +000057
58/** \brief an EntrySubTreeSelector that accepts every Entry and its children
59 */
60struct AnyEntrySubTree
61{
62 std::pair<bool, bool>
Davide Pesavento87fc0f82018-04-11 23:43:51 -040063 operator()(const Entry&) const
Junxiao Shi029401f2016-08-05 12:55:14 +000064 {
65 return {true, true};
66 }
67};
68
69class EnumerationImpl;
70
71/** \brief NameTree iterator
72 */
Davide Pesaventoe4b22382018-06-10 14:37:24 -040073class Iterator
Junxiao Shi029401f2016-08-05 12:55:14 +000074{
75public:
Davide Pesaventoe4b22382018-06-10 14:37:24 -040076 using iterator_category = std::forward_iterator_tag;
77 using value_type = const Entry;
78 using difference_type = std::ptrdiff_t;
79 using pointer = value_type*;
80 using reference = value_type&;
81
Junxiao Shi029401f2016-08-05 12:55:14 +000082 Iterator();
83
Junxiao Shib660b4c2016-08-06 20:47:44 +000084 Iterator(shared_ptr<EnumerationImpl> impl, const Entry* ref);
Junxiao Shi029401f2016-08-05 12:55:14 +000085
Junxiao Shi029401f2016-08-05 12:55:14 +000086 const Entry&
87 operator*() const
88 {
89 BOOST_ASSERT(m_impl != nullptr);
90 return *m_entry;
91 }
92
Junxiao Shib660b4c2016-08-06 20:47:44 +000093 const Entry*
Junxiao Shi029401f2016-08-05 12:55:14 +000094 operator->() const
95 {
96 BOOST_ASSERT(m_impl != nullptr);
97 return m_entry;
98 }
99
100 Iterator&
101 operator++();
102
103 Iterator
104 operator++(int);
105
106 bool
107 operator==(const Iterator& other) const;
108
109 bool
110 operator!=(const Iterator& other) const
111 {
112 return !this->operator==(other);
113 }
114
115private:
116 /** \brief enumeration implementation; nullptr for end iterator
117 */
118 shared_ptr<EnumerationImpl> m_impl;
119
120 /** \brief current entry; nullptr for uninitialized iterator
121 */
Junxiao Shib660b4c2016-08-06 20:47:44 +0000122 const Entry* m_entry;
Junxiao Shi029401f2016-08-05 12:55:14 +0000123
124 /** \brief reference entry used by enumeration implementation
125 */
Junxiao Shib660b4c2016-08-06 20:47:44 +0000126 const Entry* m_ref;
Junxiao Shi029401f2016-08-05 12:55:14 +0000127
128 /** \brief state used by enumeration implementation
129 */
130 int m_state;
131
132 friend std::ostream& operator<<(std::ostream&, const Iterator&);
133 friend class FullEnumerationImpl;
134 friend class PartialEnumerationImpl;
135 friend class PrefixMatchImpl;
136};
137
138std::ostream&
139operator<<(std::ostream& os, const Iterator& i);
140
141/** \brief enumeration operation implementation
142 */
143class EnumerationImpl
144{
145public:
146 explicit
147 EnumerationImpl(const NameTree& nt);
148
Alexander Afanasyev847de402017-09-21 18:57:30 -0400149 virtual
150 ~EnumerationImpl() = default;
151
Junxiao Shi029401f2016-08-05 12:55:14 +0000152 virtual void
153 advance(Iterator& i) = 0;
154
155protected:
156 const NameTree& nt;
Junxiao Shib660b4c2016-08-06 20:47:44 +0000157 const Hashtable& ht;
Junxiao Shi029401f2016-08-05 12:55:14 +0000158};
159
160/** \brief full enumeration implementation
161 */
Davide Pesavento3db98072021-03-09 23:03:27 -0500162class FullEnumerationImpl final : public EnumerationImpl
Junxiao Shi029401f2016-08-05 12:55:14 +0000163{
164public:
165 FullEnumerationImpl(const NameTree& nt, const EntrySelector& pred);
166
Alexander Afanasyev847de402017-09-21 18:57:30 -0400167 void
Davide Pesavento3db98072021-03-09 23:03:27 -0500168 advance(Iterator& i) final;
Junxiao Shi029401f2016-08-05 12:55:14 +0000169
170private:
171 EntrySelector m_pred;
172};
173
174/** \brief partial enumeration implementation
175 *
176 * Iterator::m_ref should be initialized to subtree root.
177 * Iterator::m_state LSB indicates whether to visit children of m_entry.
178 */
Davide Pesavento3db98072021-03-09 23:03:27 -0500179class PartialEnumerationImpl final : public EnumerationImpl
Junxiao Shi029401f2016-08-05 12:55:14 +0000180{
181public:
182 PartialEnumerationImpl(const NameTree& nt, const EntrySubTreeSelector& pred);
183
Alexander Afanasyev847de402017-09-21 18:57:30 -0400184 void
Davide Pesavento3db98072021-03-09 23:03:27 -0500185 advance(Iterator& i) final;
Junxiao Shi029401f2016-08-05 12:55:14 +0000186
187private:
188 EntrySubTreeSelector m_pred;
189};
190
191/** \brief partial enumeration implementation
192 *
193 * Iterator::m_ref should be initialized to longest prefix matched entry.
194 */
Davide Pesavento3db98072021-03-09 23:03:27 -0500195class PrefixMatchImpl final : public EnumerationImpl
Junxiao Shi029401f2016-08-05 12:55:14 +0000196{
197public:
198 PrefixMatchImpl(const NameTree& nt, const EntrySelector& pred);
199
200private:
Alexander Afanasyev847de402017-09-21 18:57:30 -0400201 void
Davide Pesavento3db98072021-03-09 23:03:27 -0500202 advance(Iterator& i) final;
Junxiao Shi029401f2016-08-05 12:55:14 +0000203
204private:
205 EntrySelector m_pred;
206};
207
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000208/** \brief a Forward Range of name tree entries
209 *
210 * This type has .begin() and .end() methods which return Iterator.
211 * This type is usable with range-based for.
212 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400213using Range = boost::iterator_range<Iterator>;
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000214
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400215} // namespace nfd::name_tree
Junxiao Shi029401f2016-08-05 12:55:14 +0000216
217#endif // NFD_DAEMON_TABLE_NAME_TREE_ITERATOR_HPP