table: make NameTree::findAllMatches usable with range-based for
refs #2155
Change-Id: I298825145cf544faaeeb9e558f6deb6703d434c0
diff --git a/daemon/table/name-tree.cpp b/daemon/table/name-tree.cpp
index b42b240..31bde14 100644
--- a/daemon/table/name-tree.cpp
+++ b/daemon/table/name-tree.cpp
@@ -1,11 +1,12 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014 Regents of the University of California,
- * Arizona Board of Regents,
- * Colorado State University,
- * University Pierre & Marie Curie, Sorbonne University,
- * Washington University in St. Louis,
- * Beijing Institute of Technology
+ * Copyright (c) 2014, Regents of the University of California,
+ * Arizona Board of Regents,
+ * Colorado State University,
+ * University Pierre & Marie Curie, Sorbonne University,
+ * Washington University in St. Louis,
+ * Beijing Institute of Technology,
+ * The University of Memphis
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,9 +21,7 @@
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-// Name Tree (Name Prefix Hash Table)
+ */
#include "name-tree.hpp"
#include "core/logger.hpp"
@@ -443,7 +442,7 @@
}
}
-NameTree::const_iterator
+NameTree::Range
NameTree::findAllMatches(const Name& prefix,
const name_tree::EntrySelector& entrySelector) const
{
@@ -457,13 +456,12 @@
shared_ptr<name_tree::Entry> entry = findLongestPrefixMatch(prefix, entrySelector);
- if (static_cast<bool>(entry))
- {
- const_iterator it(FIND_ALL_MATCHES_TYPE, *this, entry, entrySelector);
- return it;
- }
+ if (static_cast<bool>(entry)) {
+ const_iterator begin(FIND_ALL_MATCHES_TYPE, *this, entry, entrySelector);
+ return { begin, end() };
+ }
// If none of the entry satisfies the requirements, then return the end() iterator.
- return end();
+ return { end(), end() };
}
// Hash Table Resize
@@ -762,4 +760,10 @@
return *this;
}
+NameTree::Range::Range(const_iterator begin, const_iterator end)
+ : m_begin(begin)
+ , m_end(end)
+{
+}
+
} // namespace nfd
diff --git a/daemon/table/name-tree.hpp b/daemon/table/name-tree.hpp
index 0832a31..2ef032e 100644
--- a/daemon/table/name-tree.hpp
+++ b/daemon/table/name-tree.hpp
@@ -80,6 +80,7 @@
{
public:
class const_iterator;
+ class Range;
explicit
NameTree(size_t nBuckets = 1024);
@@ -173,10 +174,19 @@
const name_tree::EntrySelector& entrySelector =
name_tree::AnyEntry()) const;
- /**
- * \brief Enumerate all the name prefixes that satisfy the prefix and entrySelector
+ /** \brief Enumerate all the name prefixes that satisfy the prefix and entrySelector
+ * \return an unspecified type that have .begin() and .end() methods
+ * and is usable with range-based for
+ *
+ * Example:
+ * \code{.cpp}
+ * auto&& allMatches = nt.findAllMatches(Name("/A/B/C"));
+ * for (const name_tree::Entry& nte : allMatches) {
+ * ...
+ * }
+ * \endcode
*/
- const_iterator
+ Range
findAllMatches(const Name& prefix,
const name_tree::EntrySelector& entrySelector = name_tree::AnyEntry()) const;
@@ -248,6 +258,32 @@
bool m_shouldVisitChildren;
};
+ /** \brief contains a pair of begin and end iterators
+ *
+ * This is to be used with range-based for.
+ */
+ class Range
+ {
+ public:
+ Range(const_iterator begin, const_iterator end);
+
+ const_iterator
+ begin() const
+ {
+ return m_begin;
+ }
+
+ const_iterator
+ end() const
+ {
+ return m_end;
+ }
+
+ private:
+ const_iterator m_begin;
+ const_iterator m_end;
+ };
+
private:
/**
* \brief Resize the hash table size when its load factor reaches a threshold.
diff --git a/daemon/table/pit.cpp b/daemon/table/pit.cpp
index 13a11d4..e4199e8 100644
--- a/daemon/table/pit.cpp
+++ b/daemon/table/pit.cpp
@@ -75,13 +75,12 @@
pit::DataMatchResult
Pit::findAllDataMatches(const Data& data) const
{
- pit::DataMatchResult matches;
-
- auto allMatchesBegin = m_nameTree.findAllMatches(data.getName(),
+ auto&& ntMatches = m_nameTree.findAllMatches(data.getName(),
[] (const name_tree::Entry& entry) { return entry.hasPitEntries(); });
- // TODO: change to range-based for, after #2155
- for (auto it = allMatchesBegin; it != m_nameTree.end(); ++it) {
- for (const shared_ptr<pit::Entry>& pitEntry : it->getPitEntries()) {
+
+ pit::DataMatchResult matches;
+ for (const name_tree::Entry& nte : ntMatches) {
+ for (const shared_ptr<pit::Entry>& pitEntry : nte.getPitEntries()) {
if (pitEntry->getInterest().matchesData(data))
matches.emplace_back(pitEntry);
}
diff --git a/tests/daemon/table/name-tree.cpp b/tests/daemon/table/name-tree.cpp
index cd1d894..ebb8550 100644
--- a/tests/daemon/table/name-tree.cpp
+++ b/tests/daemon/table/name-tree.cpp
@@ -737,34 +737,33 @@
counter = 0;
- for (NameTree::const_iterator it = nt.findAllMatches(nameABCDEF);
- it != nt.end(); it++)
- {
+ auto&& allMatches = nt.findAllMatches(nameABCDEF);
+ for (const name_tree::Entry& entry : allMatches) {
counter++;
- if (it->getPrefix() == nameRoot)
+ if (entry.getPrefix() == nameRoot)
hasRoot = true;
- if (it->getPrefix() == nameA)
+ if (entry.getPrefix() == nameA)
hasA = true;
- if (it->getPrefix() == nameAB)
+ if (entry.getPrefix() == nameAB)
hasAB = true;
- if (it->getPrefix() == nameABC)
+ if (entry.getPrefix() == nameABC)
hasABC = true;
- if (it->getPrefix() == nameABCD)
+ if (entry.getPrefix() == nameABCD)
hasABCD = true;
- if (it->getPrefix() == nameABCDE)
+ if (entry.getPrefix() == nameABCDE)
hasABCDE = true;
- if (it->getPrefix() == nameABCDEF)
+ if (entry.getPrefix() == nameABCDEF)
hasABCDEF = true;
- if (it->getPrefix() == nameAA)
+ if (entry.getPrefix() == nameAA)
hasAA = true;
- if (it->getPrefix() == nameAAC)
+ if (entry.getPrefix() == nameAAC)
hasAAC = true;
- if (it->getPrefix() == nameAAD)
+ if (entry.getPrefix() == nameAAD)
hasAAD = true;
- if (it->getPrefix() == nameAAD1)
+ if (entry.getPrefix() == nameAAD1)
hasAAD1 = true;
- if (it->getPrefix() == nameAAD2)
+ if (entry.getPrefix() == nameAAD2)
hasAAD2 = true;
}