blob: fef3e6e08c53738920aa7f1cacc99e86f5f99da3 [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 Pesavento191a7a22023-05-17 22:40:43 -04003 * Copyright (c) 2014-2023, 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
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040037/**
38 * \brief A predicate to accept or reject an Entry in find operations.
Junxiao Shi029401f2016-08-05 12:55:14 +000039 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -040040using EntrySelector = std::function<bool(const Entry&)>;
Junxiao Shi029401f2016-08-05 12:55:14 +000041
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040042/**
43 * \brief An #EntrySelector that accepts every Entry.
Junxiao Shi029401f2016-08-05 12:55:14 +000044 */
45struct AnyEntry
46{
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040047 constexpr bool
48 operator()(const Entry&) const noexcept
Junxiao Shi029401f2016-08-05 12:55:14 +000049 {
50 return true;
51 }
52};
53
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040054/** \brief A predicate to accept or reject an Entry and its children.
Davide Pesavento87fc0f82018-04-11 23:43:51 -040055 * \return `.first` indicates whether entry should be accepted;
56 * `.second` indicates whether entry's children should be visited
Junxiao Shi029401f2016-08-05 12:55:14 +000057 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -040058using EntrySubTreeSelector = std::function<std::pair<bool, bool>(const Entry&)>;
Junxiao Shi029401f2016-08-05 12:55:14 +000059
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040060/**
61 * \brief An #EntrySubTreeSelector that accepts every Entry and its children.
Junxiao Shi029401f2016-08-05 12:55:14 +000062 */
63struct AnyEntrySubTree
64{
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040065 constexpr std::pair<bool, bool>
66 operator()(const Entry&) const noexcept
Junxiao Shi029401f2016-08-05 12:55:14 +000067 {
68 return {true, true};
69 }
70};
71
72class EnumerationImpl;
73
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040074/**
75 * \brief NameTree iterator.
Junxiao Shi029401f2016-08-05 12:55:14 +000076 */
Davide Pesaventoe4b22382018-06-10 14:37:24 -040077class Iterator
Junxiao Shi029401f2016-08-05 12:55:14 +000078{
79public:
Davide Pesaventoe4b22382018-06-10 14:37:24 -040080 using iterator_category = std::forward_iterator_tag;
81 using value_type = const Entry;
82 using difference_type = std::ptrdiff_t;
83 using pointer = value_type*;
84 using reference = value_type&;
85
Junxiao Shi029401f2016-08-05 12:55:14 +000086 Iterator();
87
Junxiao Shib660b4c2016-08-06 20:47:44 +000088 Iterator(shared_ptr<EnumerationImpl> impl, const Entry* ref);
Junxiao Shi029401f2016-08-05 12:55:14 +000089
Junxiao Shi029401f2016-08-05 12:55:14 +000090 const Entry&
Davide Pesavento191a7a22023-05-17 22:40:43 -040091 operator*() const noexcept
Junxiao Shi029401f2016-08-05 12:55:14 +000092 {
93 BOOST_ASSERT(m_impl != nullptr);
94 return *m_entry;
95 }
96
Junxiao Shib660b4c2016-08-06 20:47:44 +000097 const Entry*
Davide Pesavento191a7a22023-05-17 22:40:43 -040098 operator->() const noexcept
Junxiao Shi029401f2016-08-05 12:55:14 +000099 {
100 BOOST_ASSERT(m_impl != nullptr);
101 return m_entry;
102 }
103
104 Iterator&
105 operator++();
106
107 Iterator
108 operator++(int);
109
Davide Pesavento191a7a22023-05-17 22:40:43 -0400110 friend bool
111 operator==(const Iterator& lhs, const Iterator& rhs) noexcept
Junxiao Shi029401f2016-08-05 12:55:14 +0000112 {
Davide Pesavento191a7a22023-05-17 22:40:43 -0400113 return lhs.m_entry == rhs.m_entry;
114 }
115
116 friend bool
117 operator!=(const Iterator& lhs, const Iterator& rhs) noexcept
118 {
119 return !(lhs == rhs);
Junxiao Shi029401f2016-08-05 12:55:14 +0000120 }
121
122private:
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400123 /** \brief Enumeration implementation; nullptr for end iterator.
Junxiao Shi029401f2016-08-05 12:55:14 +0000124 */
125 shared_ptr<EnumerationImpl> m_impl;
126
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400127 /** \brief Current entry; nullptr for uninitialized iterator.
Junxiao Shi029401f2016-08-05 12:55:14 +0000128 */
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400129 const Entry* m_entry = nullptr;
Junxiao Shi029401f2016-08-05 12:55:14 +0000130
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400131 /** \brief Reference entry used by enumeration implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000132 */
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400133 const Entry* m_ref = nullptr;
Junxiao Shi029401f2016-08-05 12:55:14 +0000134
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400135 /** \brief State used by enumeration implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000136 */
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400137 int m_state = 0;
Junxiao Shi029401f2016-08-05 12:55:14 +0000138
139 friend std::ostream& operator<<(std::ostream&, const Iterator&);
140 friend class FullEnumerationImpl;
141 friend class PartialEnumerationImpl;
142 friend class PrefixMatchImpl;
143};
144
145std::ostream&
146operator<<(std::ostream& os, const Iterator& i);
147
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400148/** \brief Enumeration operation implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000149 */
150class EnumerationImpl
151{
152public:
153 explicit
154 EnumerationImpl(const NameTree& nt);
155
Alexander Afanasyev847de402017-09-21 18:57:30 -0400156 virtual
157 ~EnumerationImpl() = default;
158
Junxiao Shi029401f2016-08-05 12:55:14 +0000159 virtual void
160 advance(Iterator& i) = 0;
161
162protected:
163 const NameTree& nt;
Junxiao Shib660b4c2016-08-06 20:47:44 +0000164 const Hashtable& ht;
Junxiao Shi029401f2016-08-05 12:55:14 +0000165};
166
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400167/** \brief Full enumeration implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000168 */
Davide Pesavento3db98072021-03-09 23:03:27 -0500169class FullEnumerationImpl final : public EnumerationImpl
Junxiao Shi029401f2016-08-05 12:55:14 +0000170{
171public:
172 FullEnumerationImpl(const NameTree& nt, const EntrySelector& pred);
173
Alexander Afanasyev847de402017-09-21 18:57:30 -0400174 void
Davide Pesavento3db98072021-03-09 23:03:27 -0500175 advance(Iterator& i) final;
Junxiao Shi029401f2016-08-05 12:55:14 +0000176
177private:
178 EntrySelector m_pred;
179};
180
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400181/** \brief Partial enumeration implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000182 *
183 * Iterator::m_ref should be initialized to subtree root.
184 * Iterator::m_state LSB indicates whether to visit children of m_entry.
185 */
Davide Pesavento3db98072021-03-09 23:03:27 -0500186class PartialEnumerationImpl final : public EnumerationImpl
Junxiao Shi029401f2016-08-05 12:55:14 +0000187{
188public:
189 PartialEnumerationImpl(const NameTree& nt, const EntrySubTreeSelector& pred);
190
Alexander Afanasyev847de402017-09-21 18:57:30 -0400191 void
Davide Pesavento3db98072021-03-09 23:03:27 -0500192 advance(Iterator& i) final;
Junxiao Shi029401f2016-08-05 12:55:14 +0000193
194private:
195 EntrySubTreeSelector m_pred;
196};
197
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400198/** \brief Partial enumeration implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000199 *
200 * Iterator::m_ref should be initialized to longest prefix matched entry.
201 */
Davide Pesavento3db98072021-03-09 23:03:27 -0500202class PrefixMatchImpl final : public EnumerationImpl
Junxiao Shi029401f2016-08-05 12:55:14 +0000203{
204public:
205 PrefixMatchImpl(const NameTree& nt, const EntrySelector& pred);
206
207private:
Alexander Afanasyev847de402017-09-21 18:57:30 -0400208 void
Davide Pesavento3db98072021-03-09 23:03:27 -0500209 advance(Iterator& i) final;
Junxiao Shi029401f2016-08-05 12:55:14 +0000210
211private:
212 EntrySelector m_pred;
213};
214
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400215/** \brief A Forward Range of name tree entries.
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000216 *
217 * This type has .begin() and .end() methods which return Iterator.
218 * This type is usable with range-based for.
219 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400220using Range = boost::iterator_range<Iterator>;
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000221
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400222} // namespace nfd::name_tree
Junxiao Shi029401f2016-08-05 12:55:14 +0000223
224#endif // NFD_DAEMON_TABLE_NAME_TREE_ITERATOR_HPP