blob: f484440180dd60d8a71b1e48fea733a04f84442c [file] [log] [blame]
Junxiao Shi029401f2016-08-05 12:55:14 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2016, Regents of the University of California,
4 * 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
29#include "name-tree-entry.hpp"
30
31namespace nfd {
32namespace name_tree {
33
34/** \brief a predicate to accept or reject an Entry in find operations
35 */
36typedef function<bool(const Entry& entry)> EntrySelector;
37
38/** \brief an EntrySelector that accepts every Entry
39 */
40struct AnyEntry
41{
42 bool
43 operator()(const Entry& entry) const
44 {
45 return true;
46 }
47};
48
49/** \brief a predicate to accept or reject an Entry and its children
50 * \return .first indicates whether entry should be accepted;
51 * .second indicates whether entry's children should be visited
52 */
53typedef function<std::pair<bool,bool>(const Entry& entry)> EntrySubTreeSelector;
54
55/** \brief an EntrySubTreeSelector that accepts every Entry and its children
56 */
57struct AnyEntrySubTree
58{
59 std::pair<bool, bool>
60 operator()(const Entry& entry) const
61 {
62 return {true, true};
63 }
64};
65
66class EnumerationImpl;
67
68/** \brief NameTree iterator
69 */
70class Iterator : public std::iterator<std::forward_iterator_tag, const Entry>
71{
72public:
73 Iterator();
74
Junxiao Shib660b4c2016-08-06 20:47:44 +000075 Iterator(shared_ptr<EnumerationImpl> impl, const Entry* ref);
Junxiao Shi029401f2016-08-05 12:55:14 +000076
Junxiao Shi029401f2016-08-05 12:55:14 +000077 const Entry&
78 operator*() const
79 {
80 BOOST_ASSERT(m_impl != nullptr);
81 return *m_entry;
82 }
83
Junxiao Shib660b4c2016-08-06 20:47:44 +000084 const Entry*
Junxiao Shi029401f2016-08-05 12:55:14 +000085 operator->() const
86 {
87 BOOST_ASSERT(m_impl != nullptr);
88 return m_entry;
89 }
90
91 Iterator&
92 operator++();
93
94 Iterator
95 operator++(int);
96
97 bool
98 operator==(const Iterator& other) const;
99
100 bool
101 operator!=(const Iterator& other) const
102 {
103 return !this->operator==(other);
104 }
105
106private:
107 /** \brief enumeration implementation; nullptr for end iterator
108 */
109 shared_ptr<EnumerationImpl> m_impl;
110
111 /** \brief current entry; nullptr for uninitialized iterator
112 */
Junxiao Shib660b4c2016-08-06 20:47:44 +0000113 const Entry* m_entry;
Junxiao Shi029401f2016-08-05 12:55:14 +0000114
115 /** \brief reference entry used by enumeration implementation
116 */
Junxiao Shib660b4c2016-08-06 20:47:44 +0000117 const Entry* m_ref;
Junxiao Shi029401f2016-08-05 12:55:14 +0000118
119 /** \brief state used by enumeration implementation
120 */
121 int m_state;
122
123 friend std::ostream& operator<<(std::ostream&, const Iterator&);
124 friend class FullEnumerationImpl;
125 friend class PartialEnumerationImpl;
126 friend class PrefixMatchImpl;
127};
128
129std::ostream&
130operator<<(std::ostream& os, const Iterator& i);
131
132/** \brief enumeration operation implementation
133 */
134class EnumerationImpl
135{
136public:
137 explicit
138 EnumerationImpl(const NameTree& nt);
139
140 virtual void
141 advance(Iterator& i) = 0;
142
143protected:
144 const NameTree& nt;
Junxiao Shib660b4c2016-08-06 20:47:44 +0000145 const Hashtable& ht;
Junxiao Shi029401f2016-08-05 12:55:14 +0000146};
147
148/** \brief full enumeration implementation
149 */
150class FullEnumerationImpl : public EnumerationImpl
151{
152public:
153 FullEnumerationImpl(const NameTree& nt, const EntrySelector& pred);
154
155 virtual void
156 advance(Iterator& i) override;
157
158private:
159 EntrySelector m_pred;
160};
161
162/** \brief partial enumeration implementation
163 *
164 * Iterator::m_ref should be initialized to subtree root.
165 * Iterator::m_state LSB indicates whether to visit children of m_entry.
166 */
167class PartialEnumerationImpl : public EnumerationImpl
168{
169public:
170 PartialEnumerationImpl(const NameTree& nt, const EntrySubTreeSelector& pred);
171
172 virtual void
173 advance(Iterator& i) override;
174
175private:
176 EntrySubTreeSelector m_pred;
177};
178
179/** \brief partial enumeration implementation
180 *
181 * Iterator::m_ref should be initialized to longest prefix matched entry.
182 */
183class PrefixMatchImpl : public EnumerationImpl
184{
185public:
186 PrefixMatchImpl(const NameTree& nt, const EntrySelector& pred);
187
188private:
189 virtual void
190 advance(Iterator& i) override;
191
192private:
193 EntrySelector m_pred;
194};
195
196} // namespace name_tree
197} // namespace nfd
198
199#endif // NFD_DAEMON_TABLE_NAME_TREE_ITERATOR_HPP