blob: 973c961988b586e145eabd8fe7a55999ea6f2a35 [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 Pesavento87fc0f82018-04-11 23:43:51 -04003 * Copyright (c) 2014-2018, 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
31namespace nfd {
32namespace name_tree {
33
Junxiao Shi340d5532016-08-13 04:00:35 +000034class NameTree;
35
Junxiao Shi029401f2016-08-05 12:55:14 +000036/** \brief a predicate to accept or reject an Entry in find operations
37 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -040038using EntrySelector = std::function<bool(const Entry&)>;
Junxiao Shi029401f2016-08-05 12:55:14 +000039
40/** \brief an EntrySelector that accepts every Entry
41 */
42struct AnyEntry
43{
44 bool
Davide Pesavento87fc0f82018-04-11 23:43:51 -040045 operator()(const Entry&) const
Junxiao Shi029401f2016-08-05 12:55:14 +000046 {
47 return true;
48 }
49};
50
51/** \brief a predicate to accept or reject an Entry and its children
Davide Pesavento87fc0f82018-04-11 23:43:51 -040052 * \return `.first` indicates whether entry should be accepted;
53 * `.second` indicates whether entry's children should be visited
Junxiao Shi029401f2016-08-05 12:55:14 +000054 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -040055using EntrySubTreeSelector = std::function<std::pair<bool, bool>(const Entry&)>;
Junxiao Shi029401f2016-08-05 12:55:14 +000056
57/** \brief an EntrySubTreeSelector that accepts every Entry and its children
58 */
59struct AnyEntrySubTree
60{
61 std::pair<bool, bool>
Davide Pesavento87fc0f82018-04-11 23:43:51 -040062 operator()(const Entry&) const
Junxiao Shi029401f2016-08-05 12:55:14 +000063 {
64 return {true, true};
65 }
66};
67
68class EnumerationImpl;
69
70/** \brief NameTree iterator
71 */
Davide Pesaventoe4b22382018-06-10 14:37:24 -040072class Iterator
Junxiao Shi029401f2016-08-05 12:55:14 +000073{
74public:
Davide Pesaventoe4b22382018-06-10 14:37:24 -040075 using iterator_category = std::forward_iterator_tag;
76 using value_type = const Entry;
77 using difference_type = std::ptrdiff_t;
78 using pointer = value_type*;
79 using reference = value_type&;
80
Junxiao Shi029401f2016-08-05 12:55:14 +000081 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&
86 operator*() const
87 {
88 BOOST_ASSERT(m_impl != nullptr);
89 return *m_entry;
90 }
91
Junxiao Shib660b4c2016-08-06 20:47:44 +000092 const Entry*
Junxiao Shi029401f2016-08-05 12:55:14 +000093 operator->() const
94 {
95 BOOST_ASSERT(m_impl != nullptr);
96 return m_entry;
97 }
98
99 Iterator&
100 operator++();
101
102 Iterator
103 operator++(int);
104
105 bool
106 operator==(const Iterator& other) const;
107
108 bool
109 operator!=(const Iterator& other) const
110 {
111 return !this->operator==(other);
112 }
113
114private:
115 /** \brief enumeration implementation; nullptr for end iterator
116 */
117 shared_ptr<EnumerationImpl> m_impl;
118
119 /** \brief current entry; nullptr for uninitialized iterator
120 */
Junxiao Shib660b4c2016-08-06 20:47:44 +0000121 const Entry* m_entry;
Junxiao Shi029401f2016-08-05 12:55:14 +0000122
123 /** \brief reference entry used by enumeration implementation
124 */
Junxiao Shib660b4c2016-08-06 20:47:44 +0000125 const Entry* m_ref;
Junxiao Shi029401f2016-08-05 12:55:14 +0000126
127 /** \brief state used by enumeration implementation
128 */
129 int m_state;
130
131 friend std::ostream& operator<<(std::ostream&, const Iterator&);
132 friend class FullEnumerationImpl;
133 friend class PartialEnumerationImpl;
134 friend class PrefixMatchImpl;
135};
136
137std::ostream&
138operator<<(std::ostream& os, const Iterator& i);
139
140/** \brief enumeration operation implementation
141 */
142class EnumerationImpl
143{
144public:
145 explicit
146 EnumerationImpl(const NameTree& nt);
147
Alexander Afanasyev847de402017-09-21 18:57:30 -0400148 virtual
149 ~EnumerationImpl() = default;
150
Junxiao Shi029401f2016-08-05 12:55:14 +0000151 virtual void
152 advance(Iterator& i) = 0;
153
154protected:
155 const NameTree& nt;
Junxiao Shib660b4c2016-08-06 20:47:44 +0000156 const Hashtable& ht;
Junxiao Shi029401f2016-08-05 12:55:14 +0000157};
158
159/** \brief full enumeration implementation
160 */
161class FullEnumerationImpl : public EnumerationImpl
162{
163public:
164 FullEnumerationImpl(const NameTree& nt, const EntrySelector& pred);
165
Alexander Afanasyev847de402017-09-21 18:57:30 -0400166 void
Junxiao Shi029401f2016-08-05 12:55:14 +0000167 advance(Iterator& i) override;
168
169private:
170 EntrySelector m_pred;
171};
172
173/** \brief partial enumeration implementation
174 *
175 * Iterator::m_ref should be initialized to subtree root.
176 * Iterator::m_state LSB indicates whether to visit children of m_entry.
177 */
178class PartialEnumerationImpl : public EnumerationImpl
179{
180public:
181 PartialEnumerationImpl(const NameTree& nt, const EntrySubTreeSelector& pred);
182
Alexander Afanasyev847de402017-09-21 18:57:30 -0400183 void
Junxiao Shi029401f2016-08-05 12:55:14 +0000184 advance(Iterator& i) override;
185
186private:
187 EntrySubTreeSelector m_pred;
188};
189
190/** \brief partial enumeration implementation
191 *
192 * Iterator::m_ref should be initialized to longest prefix matched entry.
193 */
194class PrefixMatchImpl : public EnumerationImpl
195{
196public:
197 PrefixMatchImpl(const NameTree& nt, const EntrySelector& pred);
198
199private:
Alexander Afanasyev847de402017-09-21 18:57:30 -0400200 void
Junxiao Shi029401f2016-08-05 12:55:14 +0000201 advance(Iterator& i) override;
202
203private:
204 EntrySelector m_pred;
205};
206
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000207/** \brief a Forward Range of name tree entries
208 *
209 * This type has .begin() and .end() methods which return Iterator.
210 * This type is usable with range-based for.
211 */
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400212using Range = boost::iterator_range<Iterator>;
Junxiao Shi9f6ca602016-08-15 04:50:29 +0000213
Junxiao Shi029401f2016-08-05 12:55:14 +0000214} // namespace name_tree
215} // namespace nfd
216
217#endif // NFD_DAEMON_TABLE_NAME_TREE_ITERATOR_HPP