blob: e4e97eff160d1a96755165d9fcdc298235a823d5 [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 Pesavento2c9d2ca2024-01-27 16:36:51 -05003 * Copyright (c) 2014-2024, 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 Pesavento8f0b8b62023-08-29 21:04:08 -040031#include <boost/operators.hpp>
Davide Pesaventoa9b09b62022-06-04 14:07:25 -040032#include <boost/range/iterator_range_core.hpp>
33
Davide Pesavento2c9d2ca2024-01-27 16:36:51 -050034#include <functional>
35
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040036namespace nfd::name_tree {
Junxiao Shi029401f2016-08-05 12:55:14 +000037
Junxiao Shi340d5532016-08-13 04:00:35 +000038class NameTree;
39
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040040/**
41 * \brief A predicate to accept or reject an Entry in find operations.
Junxiao Shi029401f2016-08-05 12:55:14 +000042 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -040043using EntrySelector = std::function<bool(const Entry&)>;
Junxiao Shi029401f2016-08-05 12:55:14 +000044
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040045/**
46 * \brief An #EntrySelector that accepts every Entry.
Junxiao Shi029401f2016-08-05 12:55:14 +000047 */
48struct AnyEntry
49{
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040050 constexpr bool
51 operator()(const Entry&) const noexcept
Junxiao Shi029401f2016-08-05 12:55:14 +000052 {
53 return true;
54 }
55};
56
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040057/** \brief A predicate to accept or reject an Entry and its children.
Davide Pesavento87fc0f82018-04-11 23:43:51 -040058 * \return `.first` indicates whether entry should be accepted;
59 * `.second` indicates whether entry's children should be visited
Junxiao Shi029401f2016-08-05 12:55:14 +000060 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -040061using EntrySubTreeSelector = std::function<std::pair<bool, bool>(const Entry&)>;
Junxiao Shi029401f2016-08-05 12:55:14 +000062
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040063/**
64 * \brief An #EntrySubTreeSelector that accepts every Entry and its children.
Junxiao Shi029401f2016-08-05 12:55:14 +000065 */
66struct AnyEntrySubTree
67{
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040068 constexpr std::pair<bool, bool>
69 operator()(const Entry&) const noexcept
Junxiao Shi029401f2016-08-05 12:55:14 +000070 {
71 return {true, true};
72 }
73};
74
75class EnumerationImpl;
76
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040077/**
78 * \brief NameTree iterator.
Junxiao Shi029401f2016-08-05 12:55:14 +000079 */
Davide Pesavento8f0b8b62023-08-29 21:04:08 -040080class Iterator : public boost::forward_iterator_helper<Iterator, const Entry>
Junxiao Shi029401f2016-08-05 12:55:14 +000081{
82public:
83 Iterator();
84
Junxiao Shib660b4c2016-08-06 20:47:44 +000085 Iterator(shared_ptr<EnumerationImpl> impl, const Entry* ref);
Junxiao Shi029401f2016-08-05 12:55:14 +000086
Junxiao Shi029401f2016-08-05 12:55:14 +000087 const Entry&
Davide Pesavento191a7a22023-05-17 22:40:43 -040088 operator*() const noexcept
Junxiao Shi029401f2016-08-05 12:55:14 +000089 {
90 BOOST_ASSERT(m_impl != nullptr);
91 return *m_entry;
92 }
93
Junxiao Shi029401f2016-08-05 12:55:14 +000094 Iterator&
95 operator++();
96
Davide Pesavento191a7a22023-05-17 22:40:43 -040097 friend bool
98 operator==(const Iterator& lhs, const Iterator& rhs) noexcept
Junxiao Shi029401f2016-08-05 12:55:14 +000099 {
Davide Pesavento191a7a22023-05-17 22:40:43 -0400100 return lhs.m_entry == rhs.m_entry;
101 }
102
Junxiao Shi029401f2016-08-05 12:55:14 +0000103private:
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400104 /** \brief Enumeration implementation; nullptr for end iterator.
Junxiao Shi029401f2016-08-05 12:55:14 +0000105 */
106 shared_ptr<EnumerationImpl> m_impl;
107
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400108 /** \brief Current entry; nullptr for uninitialized iterator.
Junxiao Shi029401f2016-08-05 12:55:14 +0000109 */
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400110 const Entry* m_entry = nullptr;
Junxiao Shi029401f2016-08-05 12:55:14 +0000111
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400112 /** \brief Reference entry used by enumeration implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000113 */
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400114 const Entry* m_ref = nullptr;
Junxiao Shi029401f2016-08-05 12:55:14 +0000115
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400116 /** \brief State used by enumeration implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000117 */
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400118 int m_state = 0;
Junxiao Shi029401f2016-08-05 12:55:14 +0000119
120 friend std::ostream& operator<<(std::ostream&, const Iterator&);
121 friend class FullEnumerationImpl;
122 friend class PartialEnumerationImpl;
123 friend class PrefixMatchImpl;
124};
125
126std::ostream&
127operator<<(std::ostream& os, const Iterator& i);
128
Davide Pesavento0a05f7a2023-10-16 20:28:06 -0400129/**
130 * \brief Enumeration operation implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000131 */
132class EnumerationImpl
133{
134public:
135 explicit
136 EnumerationImpl(const NameTree& nt);
137
138 virtual void
139 advance(Iterator& i) = 0;
140
141protected:
Davide Pesavento0a05f7a2023-10-16 20:28:06 -0400142 ~EnumerationImpl() = default;
143
144protected:
Junxiao Shi029401f2016-08-05 12:55:14 +0000145 const NameTree& nt;
Junxiao Shib660b4c2016-08-06 20:47:44 +0000146 const Hashtable& ht;
Junxiao Shi029401f2016-08-05 12:55:14 +0000147};
148
Davide Pesavento0a05f7a2023-10-16 20:28:06 -0400149/**
150 * \brief Full enumeration implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000151 */
Davide Pesavento3db98072021-03-09 23:03:27 -0500152class FullEnumerationImpl final : public EnumerationImpl
Junxiao Shi029401f2016-08-05 12:55:14 +0000153{
154public:
155 FullEnumerationImpl(const NameTree& nt, const EntrySelector& pred);
156
Alexander Afanasyev847de402017-09-21 18:57:30 -0400157 void
Davide Pesavento3db98072021-03-09 23:03:27 -0500158 advance(Iterator& i) final;
Junxiao Shi029401f2016-08-05 12:55:14 +0000159
160private:
161 EntrySelector m_pred;
162};
163
Davide Pesavento0a05f7a2023-10-16 20:28:06 -0400164/**
165 * \brief Partial enumeration implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000166 *
Davide Pesavento0a05f7a2023-10-16 20:28:06 -0400167 * Iterator::m_ref should be initialized to subtree root.
168 * Iterator::m_state LSB indicates whether to visit children of m_entry.
Junxiao Shi029401f2016-08-05 12:55:14 +0000169 */
Davide Pesavento3db98072021-03-09 23:03:27 -0500170class PartialEnumerationImpl final : public EnumerationImpl
Junxiao Shi029401f2016-08-05 12:55:14 +0000171{
172public:
173 PartialEnumerationImpl(const NameTree& nt, const EntrySubTreeSelector& pred);
174
Alexander Afanasyev847de402017-09-21 18:57:30 -0400175 void
Davide Pesavento3db98072021-03-09 23:03:27 -0500176 advance(Iterator& i) final;
Junxiao Shi029401f2016-08-05 12:55:14 +0000177
178private:
179 EntrySubTreeSelector m_pred;
180};
181
Davide Pesavento0a05f7a2023-10-16 20:28:06 -0400182/**
183 * \brief Partial enumeration implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000184 *
Davide Pesavento0a05f7a2023-10-16 20:28:06 -0400185 * Iterator::m_ref should be initialized to longest prefix matched entry.
Junxiao Shi029401f2016-08-05 12:55:14 +0000186 */
Davide Pesavento3db98072021-03-09 23:03:27 -0500187class PrefixMatchImpl final : public EnumerationImpl
Junxiao Shi029401f2016-08-05 12:55:14 +0000188{
189public:
190 PrefixMatchImpl(const NameTree& nt, const EntrySelector& pred);
191
192private:
Alexander Afanasyev847de402017-09-21 18:57:30 -0400193 void
Davide Pesavento3db98072021-03-09 23:03:27 -0500194 advance(Iterator& i) final;
Junxiao Shi029401f2016-08-05 12:55:14 +0000195
196private:
197 EntrySelector m_pred;
198};
199
Davide Pesavento0a05f7a2023-10-16 20:28:06 -0400200/**
201 * \brief A forward range of name tree entries.
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000202 *
Davide Pesavento0a05f7a2023-10-16 20:28:06 -0400203 * This type has `.begin()` and `.end()` methods which return Iterator.
204 * This type is usable with range-based for loops.
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000205 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400206using Range = boost::iterator_range<Iterator>;
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000207
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400208} // namespace nfd::name_tree
Junxiao Shi029401f2016-08-05 12:55:14 +0000209
210#endif // NFD_DAEMON_TABLE_NAME_TREE_ITERATOR_HPP