table: FIB enumeration
refs #1315
Change-Id: I535d519836720c40f72904e5520d11026ea30a33
diff --git a/daemon/table/fib.cpp b/daemon/table/fib.cpp
index 940f604..30d20e6 100644
--- a/daemon/table/fib.cpp
+++ b/daemon/table/fib.cpp
@@ -130,4 +130,10 @@
}
}
+Fib::const_iterator
+Fib::begin() const
+{
+ return const_iterator(m_nameTree.fullEnumerate(&predicate_NameTreeEntry_hasFibEntry));
+}
+
} // namespace nfd
diff --git a/daemon/table/fib.hpp b/daemon/table/fib.hpp
index e1e5c5a..93741d8 100644
--- a/daemon/table/fib.hpp
+++ b/daemon/table/fib.hpp
@@ -25,6 +25,8 @@
class Fib : noncopyable
{
public:
+ class const_iterator;
+
explicit
Fib(NameTree& nameTree);
@@ -68,6 +70,42 @@
size_t
size() const;
+ const_iterator
+ begin() const;
+
+ const_iterator
+ end() const;
+
+ class const_iterator : public std::iterator<std::forward_iterator_tag, fib::Entry>
+ {
+ public:
+ explicit
+ const_iterator(const NameTree::const_iterator& it);
+
+ ~const_iterator();
+
+ const fib::Entry&
+ operator*() const;
+
+ shared_ptr<fib::Entry>
+ operator->() const;
+
+ const_iterator&
+ operator++();
+
+ const_iterator
+ operator++(int);
+
+ bool
+ operator==(const const_iterator& other) const;
+
+ bool
+ operator!=(const const_iterator& other) const;
+
+ private:
+ NameTree::const_iterator m_nameTreeIterator;
+ };
+
private:
shared_ptr<fib::Entry>
findLongestPrefixMatch(shared_ptr<name_tree::Entry> nameTreeEntry) const;
@@ -91,6 +129,63 @@
return m_nItems;
}
+inline Fib::const_iterator
+Fib::end() const
+{
+ return const_iterator(m_nameTree.end());
+}
+
+inline
+Fib::const_iterator::const_iterator(const NameTree::const_iterator& it)
+ : m_nameTreeIterator(it)
+{
+}
+
+inline
+Fib::const_iterator::~const_iterator()
+{
+}
+
+inline
+Fib::const_iterator
+Fib::const_iterator::operator++(int)
+{
+ Fib::const_iterator temp(*this);
+ ++(*this);
+ return temp;
+}
+
+inline Fib::const_iterator&
+Fib::const_iterator::operator++()
+{
+ ++m_nameTreeIterator;
+ return *this;
+}
+
+inline const fib::Entry&
+Fib::const_iterator::operator*() const
+{
+ return *(m_nameTreeIterator->getFibEntry());
+}
+
+inline shared_ptr<fib::Entry>
+Fib::const_iterator::operator->() const
+{
+ return m_nameTreeIterator->getFibEntry();
+}
+
+inline bool
+Fib::const_iterator::operator==(const Fib::const_iterator& other) const
+{
+ return m_nameTreeIterator == other.m_nameTreeIterator;
+}
+
+inline bool
+Fib::const_iterator::operator!=(const Fib::const_iterator& other) const
+{
+ return m_nameTreeIterator != other.m_nameTreeIterator;
+}
+
} // namespace nfd
#endif // NFD_TABLE_FIB_HPP
diff --git a/tests/table/fib.cpp b/tests/table/fib.cpp
index cc80bba..a86d5ad 100644
--- a/tests/table/fib.cpp
+++ b/tests/table/fib.cpp
@@ -327,6 +327,36 @@
validateFindExactMatch(gapFib, "/X/Y/Z");
}
+BOOST_AUTO_TEST_CASE(Iterator)
+{
+ NameTree nameTree(1024);
+ Fib fib(nameTree);
+ Name nameA("/A");
+ Name nameAB("/A/B");
+ Name nameABC("/A/B/C");
+ Name nameRoot("/");
+
+ fib.insert(nameA);
+ fib.insert(nameAB);
+ fib.insert(nameABC);
+ fib.insert(nameRoot);
+
+ std::set<Name> expected;
+ expected.insert(nameA);
+ expected.insert(nameAB);
+ expected.insert(nameABC);
+ expected.insert(nameRoot);
+
+ for (Fib::const_iterator it = fib.begin(); it != fib.end(); it++)
+ {
+ bool isInSet = expected.find(it->getPrefix()) != expected.end();
+ BOOST_CHECK(isInSet);
+ expected.erase(it->getPrefix());
+ }
+
+ BOOST_CHECK_EQUAL(expected.size(), 0);
+}
+
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests