blob: fc04fb6d1198f4c73ec684af48e4a09ffedd9a49 [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 Pesaventoe422f9e2022-06-03 01:30:23 -040031namespace nfd::name_tree {
Junxiao Shi029401f2016-08-05 12:55:14 +000032
Junxiao Shi340d5532016-08-13 04:00:35 +000033class NameTree;
34
Junxiao Shi029401f2016-08-05 12:55:14 +000035/** \brief a predicate to accept or reject an Entry in find operations
36 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -040037using EntrySelector = std::function<bool(const Entry&)>;
Junxiao Shi029401f2016-08-05 12:55:14 +000038
39/** \brief an EntrySelector that accepts every Entry
40 */
41struct AnyEntry
42{
43 bool
Davide Pesavento87fc0f82018-04-11 23:43:51 -040044 operator()(const Entry&) const
Junxiao Shi029401f2016-08-05 12:55:14 +000045 {
46 return true;
47 }
48};
49
50/** \brief a predicate to accept or reject an Entry and its children
Davide Pesavento87fc0f82018-04-11 23:43:51 -040051 * \return `.first` indicates whether entry should be accepted;
52 * `.second` indicates whether entry's children should be visited
Junxiao Shi029401f2016-08-05 12:55:14 +000053 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -040054using EntrySubTreeSelector = std::function<std::pair<bool, bool>(const Entry&)>;
Junxiao Shi029401f2016-08-05 12:55:14 +000055
56/** \brief an EntrySubTreeSelector that accepts every Entry and its children
57 */
58struct AnyEntrySubTree
59{
60 std::pair<bool, bool>
Davide Pesavento87fc0f82018-04-11 23:43:51 -040061 operator()(const Entry&) const
Junxiao Shi029401f2016-08-05 12:55:14 +000062 {
63 return {true, true};
64 }
65};
66
67class EnumerationImpl;
68
69/** \brief NameTree iterator
70 */
Davide Pesaventoe4b22382018-06-10 14:37:24 -040071class Iterator
Junxiao Shi029401f2016-08-05 12:55:14 +000072{
73public:
Davide Pesaventoe4b22382018-06-10 14:37:24 -040074 using iterator_category = std::forward_iterator_tag;
75 using value_type = const Entry;
76 using difference_type = std::ptrdiff_t;
77 using pointer = value_type*;
78 using reference = value_type&;
79
Junxiao Shi029401f2016-08-05 12:55:14 +000080 Iterator();
81
Junxiao Shib660b4c2016-08-06 20:47:44 +000082 Iterator(shared_ptr<EnumerationImpl> impl, const Entry* ref);
Junxiao Shi029401f2016-08-05 12:55:14 +000083
Junxiao Shi029401f2016-08-05 12:55:14 +000084 const Entry&
85 operator*() const
86 {
87 BOOST_ASSERT(m_impl != nullptr);
88 return *m_entry;
89 }
90
Junxiao Shib660b4c2016-08-06 20:47:44 +000091 const Entry*
Junxiao Shi029401f2016-08-05 12:55:14 +000092 operator->() const
93 {
94 BOOST_ASSERT(m_impl != nullptr);
95 return m_entry;
96 }
97
98 Iterator&
99 operator++();
100
101 Iterator
102 operator++(int);
103
104 bool
105 operator==(const Iterator& other) const;
106
107 bool
108 operator!=(const Iterator& other) const
109 {
110 return !this->operator==(other);
111 }
112
113private:
114 /** \brief enumeration implementation; nullptr for end iterator
115 */
116 shared_ptr<EnumerationImpl> m_impl;
117
118 /** \brief current entry; nullptr for uninitialized iterator
119 */
Junxiao Shib660b4c2016-08-06 20:47:44 +0000120 const Entry* m_entry;
Junxiao Shi029401f2016-08-05 12:55:14 +0000121
122 /** \brief reference entry used by enumeration implementation
123 */
Junxiao Shib660b4c2016-08-06 20:47:44 +0000124 const Entry* m_ref;
Junxiao Shi029401f2016-08-05 12:55:14 +0000125
126 /** \brief state used by enumeration implementation
127 */
128 int m_state;
129
130 friend std::ostream& operator<<(std::ostream&, const Iterator&);
131 friend class FullEnumerationImpl;
132 friend class PartialEnumerationImpl;
133 friend class PrefixMatchImpl;
134};
135
136std::ostream&
137operator<<(std::ostream& os, const Iterator& i);
138
139/** \brief enumeration operation implementation
140 */
141class EnumerationImpl
142{
143public:
144 explicit
145 EnumerationImpl(const NameTree& nt);
146
Alexander Afanasyev847de402017-09-21 18:57:30 -0400147 virtual
148 ~EnumerationImpl() = default;
149
Junxiao Shi029401f2016-08-05 12:55:14 +0000150 virtual void
151 advance(Iterator& i) = 0;
152
153protected:
154 const NameTree& nt;
Junxiao Shib660b4c2016-08-06 20:47:44 +0000155 const Hashtable& ht;
Junxiao Shi029401f2016-08-05 12:55:14 +0000156};
157
158/** \brief full enumeration implementation
159 */
Davide Pesavento3db98072021-03-09 23:03:27 -0500160class FullEnumerationImpl final : public EnumerationImpl
Junxiao Shi029401f2016-08-05 12:55:14 +0000161{
162public:
163 FullEnumerationImpl(const NameTree& nt, const EntrySelector& pred);
164
Alexander Afanasyev847de402017-09-21 18:57:30 -0400165 void
Davide Pesavento3db98072021-03-09 23:03:27 -0500166 advance(Iterator& i) final;
Junxiao Shi029401f2016-08-05 12:55:14 +0000167
168private:
169 EntrySelector m_pred;
170};
171
172/** \brief partial enumeration implementation
173 *
174 * Iterator::m_ref should be initialized to subtree root.
175 * Iterator::m_state LSB indicates whether to visit children of m_entry.
176 */
Davide Pesavento3db98072021-03-09 23:03:27 -0500177class PartialEnumerationImpl final : public EnumerationImpl
Junxiao Shi029401f2016-08-05 12:55:14 +0000178{
179public:
180 PartialEnumerationImpl(const NameTree& nt, const EntrySubTreeSelector& pred);
181
Alexander Afanasyev847de402017-09-21 18:57:30 -0400182 void
Davide Pesavento3db98072021-03-09 23:03:27 -0500183 advance(Iterator& i) final;
Junxiao Shi029401f2016-08-05 12:55:14 +0000184
185private:
186 EntrySubTreeSelector m_pred;
187};
188
189/** \brief partial enumeration implementation
190 *
191 * Iterator::m_ref should be initialized to longest prefix matched entry.
192 */
Davide Pesavento3db98072021-03-09 23:03:27 -0500193class PrefixMatchImpl final : public EnumerationImpl
Junxiao Shi029401f2016-08-05 12:55:14 +0000194{
195public:
196 PrefixMatchImpl(const NameTree& nt, const EntrySelector& pred);
197
198private:
Alexander Afanasyev847de402017-09-21 18:57:30 -0400199 void
Davide Pesavento3db98072021-03-09 23:03:27 -0500200 advance(Iterator& i) final;
Junxiao Shi029401f2016-08-05 12:55:14 +0000201
202private:
203 EntrySelector m_pred;
204};
205
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000206/** \brief a Forward Range of name tree entries
207 *
208 * This type has .begin() and .end() methods which return Iterator.
209 * This type is usable with range-based for.
210 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400211using Range = boost::iterator_range<Iterator>;
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000212
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400213} // namespace nfd::name_tree
Junxiao Shi029401f2016-08-05 12:55:14 +0000214
215#endif // NFD_DAEMON_TABLE_NAME_TREE_ITERATOR_HPP