diff --git a/daemon/table/name-tree.cpp b/daemon/table/name-tree.cpp index b42b2402..31bde140 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 . - **/ - -// Name Tree (Name Prefix Hash Table) + */ #include "name-tree.hpp" #include "core/logger.hpp" @@ -443,7 +442,7 @@ NameTree::partialEnumerate(const Name& prefix, } } -NameTree::const_iterator +NameTree::Range NameTree::findAllMatches(const Name& prefix, const name_tree::EntrySelector& entrySelector) const { @@ -457,13 +456,12 @@ NameTree::findAllMatches(const Name& prefix, shared_ptr entry = findLongestPrefixMatch(prefix, entrySelector); - if (static_cast(entry)) - { - const_iterator it(FIND_ALL_MATCHES_TYPE, *this, entry, entrySelector); - return it; - } + if (static_cast(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 @@ NameTree::const_iterator::operator++() 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 0832a317..2ef032ee 100644 --- a/daemon/table/name-tree.hpp +++ b/daemon/table/name-tree.hpp @@ -80,6 +80,7 @@ class NameTree : noncopyable { public: class const_iterator; + class Range; explicit NameTree(size_t nBuckets = 1024); @@ -173,10 +174,19 @@ public: // matching 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 @@ public: // enumeration 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 13a11d48..e4199e89 100644 --- a/daemon/table/pit.cpp +++ b/daemon/table/pit.cpp @@ -75,13 +75,12 @@ Pit::insert(const Interest& interest) 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& pitEntry : it->getPitEntries()) { + + pit::DataMatchResult matches; + for (const name_tree::Entry& nte : ntMatches) { + for (const shared_ptr& 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 cd1d8947..ebb85506 100644 --- a/tests/daemon/table/name-tree.cpp +++ b/tests/daemon/table/name-tree.cpp @@ -737,34 +737,33 @@ BOOST_AUTO_TEST_CASE(IteratorFindAllMatches) 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; }