blob: 1b97c92e651bccaae012fad499728ad291048bba [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 Pesavento0a05f7a2023-10-16 20:28:06 -0400127/**
128 * \brief Enumeration operation implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000129 */
130class EnumerationImpl
131{
132public:
133 explicit
134 EnumerationImpl(const NameTree& nt);
135
136 virtual void
137 advance(Iterator& i) = 0;
138
139protected:
Davide Pesavento0a05f7a2023-10-16 20:28:06 -0400140 ~EnumerationImpl() = default;
141
142protected:
Junxiao Shi029401f2016-08-05 12:55:14 +0000143 const NameTree& nt;
Junxiao Shib660b4c2016-08-06 20:47:44 +0000144 const Hashtable& ht;
Junxiao Shi029401f2016-08-05 12:55:14 +0000145};
146
Davide Pesavento0a05f7a2023-10-16 20:28:06 -0400147/**
148 * \brief Full enumeration implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000149 */
Davide Pesavento3db98072021-03-09 23:03:27 -0500150class FullEnumerationImpl final : public EnumerationImpl
Junxiao Shi029401f2016-08-05 12:55:14 +0000151{
152public:
153 FullEnumerationImpl(const NameTree& nt, const EntrySelector& pred);
154
Alexander Afanasyev847de402017-09-21 18:57:30 -0400155 void
Davide Pesavento3db98072021-03-09 23:03:27 -0500156 advance(Iterator& i) final;
Junxiao Shi029401f2016-08-05 12:55:14 +0000157
158private:
159 EntrySelector m_pred;
160};
161
Davide Pesavento0a05f7a2023-10-16 20:28:06 -0400162/**
163 * \brief Partial enumeration implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000164 *
Davide Pesavento0a05f7a2023-10-16 20:28:06 -0400165 * Iterator::m_ref should be initialized to subtree root.
166 * Iterator::m_state LSB indicates whether to visit children of m_entry.
Junxiao Shi029401f2016-08-05 12:55:14 +0000167 */
Davide Pesavento3db98072021-03-09 23:03:27 -0500168class PartialEnumerationImpl final : public EnumerationImpl
Junxiao Shi029401f2016-08-05 12:55:14 +0000169{
170public:
171 PartialEnumerationImpl(const NameTree& nt, const EntrySubTreeSelector& pred);
172
Alexander Afanasyev847de402017-09-21 18:57:30 -0400173 void
Davide Pesavento3db98072021-03-09 23:03:27 -0500174 advance(Iterator& i) final;
Junxiao Shi029401f2016-08-05 12:55:14 +0000175
176private:
177 EntrySubTreeSelector m_pred;
178};
179
Davide Pesavento0a05f7a2023-10-16 20:28:06 -0400180/**
181 * \brief Partial enumeration implementation.
Junxiao Shi029401f2016-08-05 12:55:14 +0000182 *
Davide Pesavento0a05f7a2023-10-16 20:28:06 -0400183 * Iterator::m_ref should be initialized to longest prefix matched entry.
Junxiao Shi029401f2016-08-05 12:55:14 +0000184 */
Davide Pesavento3db98072021-03-09 23:03:27 -0500185class PrefixMatchImpl final : public EnumerationImpl
Junxiao Shi029401f2016-08-05 12:55:14 +0000186{
187public:
188 PrefixMatchImpl(const NameTree& nt, const EntrySelector& pred);
189
190private:
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 EntrySelector m_pred;
196};
197
Davide Pesavento0a05f7a2023-10-16 20:28:06 -0400198/**
199 * \brief A forward range of name tree entries.
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000200 *
Davide Pesavento0a05f7a2023-10-16 20:28:06 -0400201 * This type has `.begin()` and `.end()` methods which return Iterator.
202 * This type is usable with range-based for loops.
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000203 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400204using Range = boost::iterator_range<Iterator>;
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000205
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400206} // namespace nfd::name_tree
Junxiao Shi029401f2016-08-05 12:55:14 +0000207
208#endif // NFD_DAEMON_TABLE_NAME_TREE_ITERATOR_HPP