blob: 2399826673d968f1e0cee808af53ab30dd77aff1 [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 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 Pesaventoe422f9e2022-06-03 01:30:23 -040034namespace nfd::name_tree {
Junxiao Shi029401f2016-08-05 12:55:14 +000035
Junxiao Shi340d5532016-08-13 04:00:35 +000036class NameTree;
37
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040038/**
39 * \brief A predicate to accept or reject an Entry in find operations.
Junxiao Shi029401f2016-08-05 12:55:14 +000040 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -040041using EntrySelector = std::function<bool(const Entry&)>;
Junxiao Shi029401f2016-08-05 12:55:14 +000042
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040043/**
44 * \brief An #EntrySelector that accepts every Entry.
Junxiao Shi029401f2016-08-05 12:55:14 +000045 */
46struct AnyEntry
47{
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040048 constexpr bool
49 operator()(const Entry&) const noexcept
Junxiao Shi029401f2016-08-05 12:55:14 +000050 {
51 return true;
52 }
53};
54
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040055/** \brief A predicate to accept or reject an Entry and its children.
Davide Pesavento87fc0f82018-04-11 23:43:51 -040056 * \return `.first` indicates whether entry should be accepted;
57 * `.second` indicates whether entry's children should be visited
Junxiao Shi029401f2016-08-05 12:55:14 +000058 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -040059using EntrySubTreeSelector = std::function<std::pair<bool, bool>(const Entry&)>;
Junxiao Shi029401f2016-08-05 12:55:14 +000060
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040061/**
62 * \brief An #EntrySubTreeSelector that accepts every Entry and its children.
Junxiao Shi029401f2016-08-05 12:55:14 +000063 */
64struct AnyEntrySubTree
65{
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040066 constexpr std::pair<bool, bool>
67 operator()(const Entry&) const noexcept
Junxiao Shi029401f2016-08-05 12:55:14 +000068 {
69 return {true, true};
70 }
71};
72
73class EnumerationImpl;
74
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -040075/**
76 * \brief NameTree iterator.
Junxiao Shi029401f2016-08-05 12:55:14 +000077 */
Davide Pesavento8f0b8b62023-08-29 21:04:08 -040078class Iterator : public boost::forward_iterator_helper<Iterator, const Entry>
Junxiao Shi029401f2016-08-05 12:55:14 +000079{
80public:
81 Iterator();
82
Junxiao Shib660b4c2016-08-06 20:47:44 +000083 Iterator(shared_ptr<EnumerationImpl> impl, const Entry* ref);
Junxiao Shi029401f2016-08-05 12:55:14 +000084
Junxiao Shi029401f2016-08-05 12:55:14 +000085 const Entry&
Davide Pesavento191a7a22023-05-17 22:40:43 -040086 operator*() const noexcept
Junxiao Shi029401f2016-08-05 12:55:14 +000087 {
88 BOOST_ASSERT(m_impl != nullptr);
89 return *m_entry;
90 }
91
Junxiao Shi029401f2016-08-05 12:55:14 +000092 Iterator&
93 operator++();
94
Davide Pesavento191a7a22023-05-17 22:40:43 -040095 friend bool
96 operator==(const Iterator& lhs, const Iterator& rhs) noexcept
Junxiao Shi029401f2016-08-05 12:55:14 +000097 {
Davide Pesavento191a7a22023-05-17 22:40:43 -040098 return lhs.m_entry == rhs.m_entry;
99 }
100
Junxiao Shi029401f2016-08-05 12:55:14 +0000101private:
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400102 /** \brief Enumeration implementation; nullptr for end iterator.
Junxiao Shi029401f2016-08-05 12:55:14 +0000103 */
104 shared_ptr<EnumerationImpl> m_impl;
105
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400106 /** \brief Current entry; nullptr for uninitialized iterator.
Junxiao Shi029401f2016-08-05 12:55:14 +0000107 */
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400108 const Entry* m_entry = nullptr;
Junxiao Shi029401f2016-08-05 12:55:14 +0000109
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400110 /** \brief Reference entry used by enumeration implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000111 */
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400112 const Entry* m_ref = nullptr;
Junxiao Shi029401f2016-08-05 12:55:14 +0000113
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400114 /** \brief State used by enumeration implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000115 */
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400116 int m_state = 0;
Junxiao Shi029401f2016-08-05 12:55:14 +0000117
118 friend std::ostream& operator<<(std::ostream&, const Iterator&);
119 friend class FullEnumerationImpl;
120 friend class PartialEnumerationImpl;
121 friend class PrefixMatchImpl;
122};
123
124std::ostream&
125operator<<(std::ostream& os, const Iterator& i);
126
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400127/** \brief Enumeration operation implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000128 */
129class EnumerationImpl
130{
131public:
132 explicit
133 EnumerationImpl(const NameTree& nt);
134
Alexander Afanasyev847de402017-09-21 18:57:30 -0400135 virtual
136 ~EnumerationImpl() = default;
137
Junxiao Shi029401f2016-08-05 12:55:14 +0000138 virtual void
139 advance(Iterator& i) = 0;
140
141protected:
142 const NameTree& nt;
Junxiao Shib660b4c2016-08-06 20:47:44 +0000143 const Hashtable& ht;
Junxiao Shi029401f2016-08-05 12:55:14 +0000144};
145
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400146/** \brief Full enumeration implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000147 */
Davide Pesavento3db98072021-03-09 23:03:27 -0500148class FullEnumerationImpl final : public EnumerationImpl
Junxiao Shi029401f2016-08-05 12:55:14 +0000149{
150public:
151 FullEnumerationImpl(const NameTree& nt, const EntrySelector& pred);
152
Alexander Afanasyev847de402017-09-21 18:57:30 -0400153 void
Davide Pesavento3db98072021-03-09 23:03:27 -0500154 advance(Iterator& i) final;
Junxiao Shi029401f2016-08-05 12:55:14 +0000155
156private:
157 EntrySelector m_pred;
158};
159
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400160/** \brief Partial enumeration implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000161 *
162 * Iterator::m_ref should be initialized to subtree root.
163 * Iterator::m_state LSB indicates whether to visit children of m_entry.
164 */
Davide Pesavento3db98072021-03-09 23:03:27 -0500165class PartialEnumerationImpl final : public EnumerationImpl
Junxiao Shi029401f2016-08-05 12:55:14 +0000166{
167public:
168 PartialEnumerationImpl(const NameTree& nt, const EntrySubTreeSelector& pred);
169
Alexander Afanasyev847de402017-09-21 18:57:30 -0400170 void
Davide Pesavento3db98072021-03-09 23:03:27 -0500171 advance(Iterator& i) final;
Junxiao Shi029401f2016-08-05 12:55:14 +0000172
173private:
174 EntrySubTreeSelector m_pred;
175};
176
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400177/** \brief Partial enumeration implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000178 *
179 * Iterator::m_ref should be initialized to longest prefix matched entry.
180 */
Davide Pesavento3db98072021-03-09 23:03:27 -0500181class PrefixMatchImpl final : public EnumerationImpl
Junxiao Shi029401f2016-08-05 12:55:14 +0000182{
183public:
184 PrefixMatchImpl(const NameTree& nt, const EntrySelector& pred);
185
186private:
Alexander Afanasyev847de402017-09-21 18:57:30 -0400187 void
Davide Pesavento3db98072021-03-09 23:03:27 -0500188 advance(Iterator& i) final;
Junxiao Shi029401f2016-08-05 12:55:14 +0000189
190private:
191 EntrySelector m_pred;
192};
193
Davide Pesaventoaa9e3b22022-10-21 17:00:07 -0400194/** \brief A Forward Range of name tree entries.
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000195 *
196 * This type has .begin() and .end() methods which return Iterator.
197 * This type is usable with range-based for.
198 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400199using Range = boost::iterator_range<Iterator>;
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000200
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400201} // namespace nfd::name_tree
Junxiao Shi029401f2016-08-05 12:55:14 +0000202
203#endif // NFD_DAEMON_TABLE_NAME_TREE_ITERATOR_HPP