table: fix PIT not matching full name
refs #3363
Change-Id: I4ff3d02aaf43c3aaba843cfcf6221c218c1cea99
diff --git a/daemon/table/fib.cpp b/daemon/table/fib.cpp
index aaa89c6..7d60dfa 100644
--- a/daemon/table/fib.cpp
+++ b/daemon/table/fib.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -90,11 +90,9 @@
shared_ptr<fib::Entry>
Fib::findLongestPrefixMatch(const pit::Entry& pitEntry) const
{
- shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.get(pitEntry);
-
- BOOST_ASSERT(static_cast<bool>(nameTreeEntry));
-
- return findLongestPrefixMatch(nameTreeEntry);
+ shared_ptr<name_tree::Entry> nte = m_nameTree.findLongestPrefixMatch(pitEntry);
+ BOOST_ASSERT(nte != nullptr);
+ return findLongestPrefixMatch(nte);
}
shared_ptr<fib::Entry>
diff --git a/daemon/table/name-tree.cpp b/daemon/table/name-tree.cpp
index 0f730d1..8e699c5 100644
--- a/daemon/table/name-tree.cpp
+++ b/daemon/table/name-tree.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -240,6 +240,99 @@
return entry;
}
+// return {false: this entry is not empty, true: this entry is empty and erased}
+bool
+NameTree::eraseEntryIfEmpty(shared_ptr<name_tree::Entry> entry)
+{
+ BOOST_ASSERT(static_cast<bool>(entry));
+
+ NFD_LOG_TRACE("eraseEntryIfEmpty " << entry->getPrefix());
+
+ // first check if this Entry can be erased
+ if (entry->isEmpty())
+ {
+ // update child-related info in the parent
+ shared_ptr<name_tree::Entry> parent = entry->getParent();
+
+ if (static_cast<bool>(parent))
+ {
+ std::vector<shared_ptr<name_tree::Entry> >& parentChildrenList =
+ parent->getChildren();
+
+ bool isFound = false;
+ size_t size = parentChildrenList.size();
+ for (size_t i = 0; i < size; i++)
+ {
+ if (parentChildrenList[i] == entry)
+ {
+ parentChildrenList[i] = parentChildrenList[size - 1];
+ parentChildrenList.pop_back();
+ isFound = true;
+ break;
+ }
+ }
+
+ BOOST_VERIFY(isFound == true);
+ }
+
+ // remove this Entry and its Name Tree Node
+ name_tree::Node* node = entry->m_node;
+ name_tree::Node* nodePrev = node->m_prev;
+
+ // configure the previous node
+ if (nodePrev != 0)
+ {
+ // link the previous node to the next node
+ nodePrev->m_next = node->m_next;
+ }
+ else
+ {
+ m_buckets[entry->getHash() % m_nBuckets] = node->m_next;
+ }
+
+ // link the previous node with the next node (skip the erased one)
+ if (node->m_next != 0)
+ {
+ node->m_next->m_prev = nodePrev;
+ node->m_next = 0;
+ }
+
+ BOOST_ASSERT(node->m_next == 0);
+
+ m_nItems--;
+ delete node;
+
+ if (static_cast<bool>(parent))
+ eraseEntryIfEmpty(parent);
+
+ size_t newNBuckets = static_cast<size_t>(m_shrinkFactor *
+ static_cast<double>(m_nBuckets));
+
+ if (newNBuckets >= m_minNBuckets && m_nItems < m_shrinkThreshold)
+ {
+ resize(newNBuckets);
+ }
+
+ return true;
+
+ } // if this entry is empty
+
+ return false; // if this entry is not empty
+}
+
+shared_ptr<name_tree::Entry>
+NameTree::get(const pit::Entry& pitEntry)
+{
+ shared_ptr<name_tree::Entry> nte = pitEntry.m_nameTreeEntry;
+ if (nte->getPrefix().size() == pitEntry.getName().size()) {
+ return nte;
+ }
+
+ BOOST_ASSERT(pitEntry.getName().at(-1).isImplicitSha256Digest());
+ BOOST_ASSERT(nte->getPrefix() == pitEntry.getName().getPrefix(-1));
+ return this->lookup(pitEntry.getName());
+}
+
// Exact Match
shared_ptr<name_tree::Entry>
NameTree::findExactMatch(const Name& prefix) const
@@ -324,84 +417,40 @@
return shared_ptr<name_tree::Entry>();
}
-// return {false: this entry is not empty, true: this entry is empty and erased}
-bool
-NameTree::eraseEntryIfEmpty(shared_ptr<name_tree::Entry> entry)
+shared_ptr<name_tree::Entry>
+NameTree::findLongestPrefixMatch(const pit::Entry& pitEntry) const
{
- BOOST_ASSERT(static_cast<bool>(entry));
+ shared_ptr<name_tree::Entry> nte = pitEntry.m_nameTreeEntry;
+ if (nte->getPrefix().size() == pitEntry.getName().size()) {
+ return nte;
+ }
- NFD_LOG_TRACE("eraseEntryIfEmpty " << entry->getPrefix());
+ BOOST_ASSERT(pitEntry.getName().at(-1).isImplicitSha256Digest());
+ BOOST_ASSERT(nte->getPrefix() == pitEntry.getName().getPrefix(-1));
+ shared_ptr<name_tree::Entry> exact = this->findExactMatch(pitEntry.getName());
+ return exact == nullptr ? nte : exact;
+}
- // first check if this Entry can be erased
- if (entry->isEmpty())
- {
- // update child-related info in the parent
- shared_ptr<name_tree::Entry> parent = entry->getParent();
+boost::iterator_range<NameTree::const_iterator>
+NameTree::findAllMatches(const Name& prefix,
+ const name_tree::EntrySelector& entrySelector) const
+{
+ NFD_LOG_TRACE("NameTree::findAllMatches" << prefix);
- if (static_cast<bool>(parent))
- {
- std::vector<shared_ptr<name_tree::Entry> >& parentChildrenList =
- parent->getChildren();
+ // As we are using Name Prefix Hash Table, and the current LPM() is
+ // implemented as starting from full name, and reduce the number of
+ // components by 1 each time, we could use it here.
+ // For trie-like design, it could be more efficient by walking down the
+ // trie from the root node.
- bool isFound = false;
- size_t size = parentChildrenList.size();
- for (size_t i = 0; i < size; i++)
- {
- if (parentChildrenList[i] == entry)
- {
- parentChildrenList[i] = parentChildrenList[size - 1];
- parentChildrenList.pop_back();
- isFound = true;
- break;
- }
- }
+ shared_ptr<name_tree::Entry> entry = findLongestPrefixMatch(prefix, entrySelector);
- BOOST_VERIFY(isFound == true);
- }
-
- // remove this Entry and its Name Tree Node
- name_tree::Node* node = entry->m_node;
- name_tree::Node* nodePrev = node->m_prev;
-
- // configure the previous node
- if (nodePrev != 0)
- {
- // link the previous node to the next node
- nodePrev->m_next = node->m_next;
- }
- else
- {
- m_buckets[entry->getHash() % m_nBuckets] = node->m_next;
- }
-
- // link the previous node with the next node (skip the erased one)
- if (node->m_next != 0)
- {
- node->m_next->m_prev = nodePrev;
- node->m_next = 0;
- }
-
- BOOST_ASSERT(node->m_next == 0);
-
- m_nItems--;
- delete node;
-
- if (static_cast<bool>(parent))
- eraseEntryIfEmpty(parent);
-
- size_t newNBuckets = static_cast<size_t>(m_shrinkFactor *
- static_cast<double>(m_nBuckets));
-
- if (newNBuckets >= m_minNBuckets && m_nItems < m_shrinkThreshold)
- {
- resize(newNBuckets);
- }
-
- return true;
-
- } // if this entry is empty
-
- return false; // if this entry is not empty
+ 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(), end()};
}
boost::iterator_range<NameTree::const_iterator>
@@ -452,28 +501,6 @@
return {it, end()};
}
-boost::iterator_range<NameTree::const_iterator>
-NameTree::findAllMatches(const Name& prefix,
- const name_tree::EntrySelector& entrySelector) const
-{
- NFD_LOG_TRACE("NameTree::findAllMatches" << prefix);
-
- // As we are using Name Prefix Hash Table, and the current LPM() is
- // implemented as starting from full name, and reduce the number of
- // components by 1 each time, we could use it here.
- // For trie-like design, it could be more efficient by walking down the
- // trie from the root node.
-
- shared_ptr<name_tree::Entry> entry = findLongestPrefixMatch(prefix, entrySelector);
-
- 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(), end()};
-}
-
// Hash Table Resize
void
NameTree::resize(size_t newNBuckets)
diff --git a/daemon/table/name-tree.hpp b/daemon/table/name-tree.hpp
index 465299a..15a717b 100644
--- a/daemon/table/name-tree.hpp
+++ b/daemon/table/name-tree.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -133,19 +133,31 @@
eraseEntryIfEmpty(shared_ptr<name_tree::Entry> entry);
public: // shortcut access
- /// get NameTree entry from attached FIB entry
+ /** \brief get NameTree entry from FIB entry
+ *
+ * This is equivalent to .lookup(fibEntry.getPrefix())
+ */
shared_ptr<name_tree::Entry>
get(const fib::Entry& fibEntry) const;
- /// get NameTree entry from attached PIT entry
+ /** \brief get NameTree entry from PIT entry
+ *
+ * This is equivalent to .lookup(pitEntry.getName()).
+ */
shared_ptr<name_tree::Entry>
- get(const pit::Entry& pitEntry) const;
+ get(const pit::Entry& pitEntry);
- /// get NameTree entry from attached Measurements entry
+ /** \brief get NameTree entry from Measurements entry
+ *
+ * This is equivalent to .lookup(measurementsEntry.getName())
+ */
shared_ptr<name_tree::Entry>
get(const measurements::Entry& measurementsEntry) const;
- /// get NameTree entry from attached StrategyChoice entry
+ /** \brief get NameTree entry from StrategyChoice entry
+ *
+ * This is equivalent to .lookup(strategyChoiceEntry.getName())
+ */
shared_ptr<name_tree::Entry>
get(const strategy_choice::Entry& strategyChoiceEntry) const;
@@ -173,6 +185,13 @@
const name_tree::EntrySelector& entrySelector =
name_tree::AnyEntry()) const;
+ /** \brief longest prefix matching for Interest name of the PIT entry
+ *
+ * This is equivalent to .findLongestPrefixMatch(pitEntry.getName(), AnyEntry()).
+ */
+ shared_ptr<name_tree::Entry>
+ findLongestPrefixMatch(const pit::Entry& pitEntry) const;
+
/** \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
@@ -351,12 +370,6 @@
}
inline shared_ptr<name_tree::Entry>
-NameTree::get(const pit::Entry& pitEntry) const
-{
- return pitEntry.m_nameTreeEntry;
-}
-
-inline shared_ptr<name_tree::Entry>
NameTree::get(const measurements::Entry& measurementsEntry) const
{
return measurementsEntry.m_nameTreeEntry;
diff --git a/daemon/table/pit.cpp b/daemon/table/pit.cpp
index 959593f..12a21bd 100644
--- a/daemon/table/pit.cpp
+++ b/daemon/table/pit.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -57,26 +57,28 @@
{
}
-Pit::~Pit()
-{
-}
-
std::pair<shared_ptr<pit::Entry>, bool>
Pit::findOrInsert(const Interest& interest, bool allowInsert)
{
- // first lookup() the Interest Name in the NameTree, which will creates all
- // the intermedia nodes, starting from the shortest prefix.
- shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.lookup(interest.getName());
- BOOST_ASSERT(static_cast<bool>(nameTreeEntry));
+ // ensure NameTree entry exists
+ const Name& name = interest.getName();
+ bool isEndWithDigest = name.size() > 0 && name[-1].isImplicitSha256Digest();
+ shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(isEndWithDigest ? name.getPrefix(-1) : name);
+ BOOST_ASSERT(nte != nullptr);
+ size_t nteNameLen = nte->getPrefix().size();
- const std::vector<shared_ptr<pit::Entry>>& pitEntries = nameTreeEntry->getPitEntries();
-
- // then check if this Interest is already in the PIT entries
+ // check if PIT entry already exists
+ const std::vector<shared_ptr<pit::Entry>>& pitEntries = nte->getPitEntries();
auto it = std::find_if(pitEntries.begin(), pitEntries.end(),
- [&interest] (const shared_ptr<pit::Entry>& entry) {
- return entry->getInterest().getName() == interest.getName() &&
- entry->getInterest().getSelectors() == interest.getSelectors();
- });
+ [&interest, nteNameLen] (const shared_ptr<pit::Entry>& entry) -> bool {
+ // initial part of the name is guaranteed to be the same
+ BOOST_ASSERT(entry->getInterest().getName().compare(0, nteNameLen,
+ interest.getName(), 0, nteNameLen) == 0);
+ // compare implicit digest (or its absence) only
+ return entry->getInterest().getName().compare(nteNameLen, Name::npos,
+ interest.getName(), nteNameLen) == 0 &&
+ entry->getInterest().getSelectors() == interest.getSelectors();
+ });
if (it != pitEntries.end()) {
return {*it, false};
}
@@ -85,8 +87,8 @@
return {nullptr, true};
}
- shared_ptr<pit::Entry> entry = make_shared<pit::Entry>(interest);
- nameTreeEntry->insertPitEntry(entry);
+ auto entry = make_shared<pit::Entry>(interest);
+ nte->insertPitEntry(entry);
m_nItems++;
return {entry, true};
}
diff --git a/daemon/table/pit.hpp b/daemon/table/pit.hpp
index adab085..cea528f 100644
--- a/daemon/table/pit.hpp
+++ b/daemon/table/pit.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -51,8 +51,6 @@
explicit
Pit(NameTree& nameTree);
- ~Pit();
-
/** \return number of entries
*/
size_t
diff --git a/tests/daemon/table/fib.t.cpp b/tests/daemon/table/fib.t.cpp
index 59a88e9..30846f4 100644
--- a/tests/daemon/table/fib.t.cpp
+++ b/tests/daemon/table/fib.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -24,6 +24,8 @@
*/
#include "table/fib.hpp"
+#include "table/pit.hpp"
+#include "table/measurements.hpp"
#include "tests/daemon/face/dummy-face.hpp"
#include "tests/test-common.hpp"
@@ -31,7 +33,8 @@
namespace nfd {
namespace tests {
-BOOST_FIXTURE_TEST_SUITE(TableFib, BaseFixture)
+BOOST_AUTO_TEST_SUITE(Table)
+BOOST_FIXTURE_TEST_SUITE(TestFib, BaseFixture)
BOOST_AUTO_TEST_CASE(Entry)
{
@@ -66,14 +69,14 @@
BOOST_CHECK_EQUAL(nexthops4.size(), 2);
int i = -1;
for (fib::NextHopList::const_iterator it = nexthops4.begin();
- it != nexthops4.end(); ++it) {
+ it != nexthops4.end(); ++it) {
++i;
switch (i) {
- case 0 :
+ case 0:
BOOST_CHECK_EQUAL(it->getFace(), face1);
BOOST_CHECK_EQUAL(it->getCost(), 30);
break;
- case 1 :
+ case 1:
BOOST_CHECK_EQUAL(it->getFace(), face2);
BOOST_CHECK_EQUAL(it->getCost(), 40);
break;
@@ -86,14 +89,14 @@
BOOST_CHECK_EQUAL(nexthops5.size(), 2);
i = -1;
for (fib::NextHopList::const_iterator it = nexthops5.begin();
- it != nexthops5.end(); ++it) {
+ it != nexthops5.end(); ++it) {
++i;
switch (i) {
- case 0 :
+ case 0:
BOOST_CHECK_EQUAL(it->getFace(), face2);
BOOST_CHECK_EQUAL(it->getCost(), 10);
break;
- case 1 :
+ case 1:
BOOST_CHECK_EQUAL(it->getFace(), face1);
BOOST_CHECK_EQUAL(it->getCost(), 30);
break;
@@ -198,6 +201,64 @@
BOOST_CHECK_EQUAL(entry->getPrefix(), nameEmpty);
}
+BOOST_AUTO_TEST_CASE(LongestPrefixMatchWithPitEntry)
+{
+ NameTree nameTree;
+ Fib fib(nameTree);
+
+ shared_ptr<Data> dataABC = makeData("/A/B/C");
+ Name fullNameABC = dataABC->getFullName();
+ shared_ptr<Data> dataADE = makeData("/A/D/E");
+ Name fullNameADE = dataADE->getFullName();
+ fib.insert("/A");
+ fib.insert(fullNameABC);
+
+ Pit pit(nameTree);
+ shared_ptr<Interest> interestAB = makeInterest("/A/B");
+ shared_ptr<pit::Entry> pitAB = pit.insert(*interestAB).first;
+ shared_ptr<Interest> interestABC = makeInterest(fullNameABC);
+ shared_ptr<pit::Entry> pitABC = pit.insert(*interestABC).first;
+ shared_ptr<Interest> interestADE = makeInterest(fullNameADE);
+ shared_ptr<pit::Entry> pitADE = pit.insert(*interestADE).first;
+
+ size_t nNameTreeEntries = nameTree.size();
+
+ shared_ptr<fib::Entry> entry = fib.findLongestPrefixMatch(*pitAB);
+ BOOST_REQUIRE(entry != nullptr);
+ BOOST_CHECK_EQUAL(entry->getPrefix(), "/A");
+
+ entry = fib.findLongestPrefixMatch(*pitABC);
+ BOOST_REQUIRE(entry != nullptr);
+ BOOST_CHECK_EQUAL(entry->getPrefix(), fullNameABC);
+
+ entry = fib.findLongestPrefixMatch(*pitADE);
+ BOOST_REQUIRE(entry != nullptr);
+ BOOST_CHECK_EQUAL(entry->getPrefix(), "/A");
+
+ BOOST_CHECK_EQUAL(nameTree.size(), nNameTreeEntries);
+}
+
+BOOST_AUTO_TEST_CASE(LongestPrefixMatchWithMeasurementsEntry)
+{
+ NameTree nameTree;
+ Fib fib(nameTree);
+
+ fib.insert("/A");
+ fib.insert("/A/B/C");
+
+ Measurements measurements(nameTree);
+ shared_ptr<measurements::Entry> mAB = measurements.get("/A/B");
+ shared_ptr<measurements::Entry> mABCD = measurements.get("/A/B/C/D");
+
+ shared_ptr<fib::Entry> entry = fib.findLongestPrefixMatch(*mAB);
+ BOOST_REQUIRE(entry != nullptr);
+ BOOST_CHECK_EQUAL(entry->getPrefix(), "/A");
+
+ entry = fib.findLongestPrefixMatch(*mABCD);
+ BOOST_REQUIRE(entry != nullptr);
+ BOOST_CHECK_EQUAL(entry->getPrefix(), "/A/B/C");
+}
+
BOOST_AUTO_TEST_CASE(RemoveNextHopFromAllEntries)
{
shared_ptr<Face> face1 = make_shared<DummyFace>();
@@ -420,8 +481,7 @@
expected.insert(nameABC);
expected.insert(nameRoot);
- for (Fib::const_iterator it = fib.begin(); it != fib.end(); it++)
- {
+ 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());
@@ -430,7 +490,8 @@
BOOST_CHECK_EQUAL(expected.size(), 0);
}
-BOOST_AUTO_TEST_SUITE_END()
+BOOST_AUTO_TEST_SUITE_END() // TestFib
+BOOST_AUTO_TEST_SUITE_END() // Table
} // namespace tests
} // namespace nfd
diff --git a/tests/daemon/table/measurements.t.cpp b/tests/daemon/table/measurements.t.cpp
index 0f788bb..bbf1903 100644
--- a/tests/daemon/table/measurements.t.cpp
+++ b/tests/daemon/table/measurements.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -99,10 +99,18 @@
shared_ptr<Interest> interestA = makeInterest("/A");
shared_ptr<pit::Entry> pitA = pit.insert(*interestA).first;
+ shared_ptr<Data> dataABC = makeData("/A/B/C");
+ Name fullName = dataABC->getFullName();
+ shared_ptr<Interest> interestFull = makeInterest(fullName);
+ shared_ptr<pit::Entry> pitFull = pit.insert(*interestFull).first;
shared_ptr<measurements::Entry> entryA = measurements.get(*pitA);
BOOST_REQUIRE(entryA != nullptr);
BOOST_CHECK_EQUAL(entryA->getName(), "/A");
+
+ shared_ptr<measurements::Entry> entryFull = measurements.get(*pitFull);
+ BOOST_REQUIRE(entryFull != nullptr);
+ BOOST_CHECK_EQUAL(entryFull->getName(), fullName);
}
class DummyStrategyInfo1 : public fw::StrategyInfo
diff --git a/tests/daemon/table/pit.t.cpp b/tests/daemon/table/pit.t.cpp
index dd02bec..546c0a5 100644
--- a/tests/daemon/table/pit.t.cpp
+++ b/tests/daemon/table/pit.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -487,7 +487,23 @@
BOOST_CHECK_EQUAL(hasD , false);
BOOST_CHECK_EQUAL(count, 2);
+}
+BOOST_AUTO_TEST_CASE(MatchFullName) // Bug 3363
+{
+ NameTree nameTree(16);
+ Pit pit(nameTree);
+
+ shared_ptr<Data> data = makeData("/A");
+ Name fullName = data->getFullName();
+ shared_ptr<Interest> interest = makeInterest(fullName);
+
+ pit.insert(*interest);
+ pit::DataMatchResult matches = pit.findAllDataMatches(*data);
+
+ BOOST_REQUIRE_EQUAL(std::distance(matches.begin(), matches.end()), 1);
+ shared_ptr<pit::Entry> found = *matches.begin();
+ BOOST_CHECK_EQUAL(found->getName(), fullName);
}
BOOST_AUTO_TEST_CASE(Iterator)
diff --git a/tests/daemon/table/strategy-choice.t.cpp b/tests/daemon/table/strategy-choice.t.cpp
index ec450f5..469cb1a 100644
--- a/tests/daemon/table/strategy-choice.t.cpp
+++ b/tests/daemon/table/strategy-choice.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2014-2015, Regents of the University of California,
+ * Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -31,7 +31,8 @@
namespace nfd {
namespace tests {
-BOOST_FIXTURE_TEST_SUITE(TableStrategyChoice, BaseFixture)
+BOOST_AUTO_TEST_SUITE(Table)
+BOOST_FIXTURE_TEST_SUITE(TestStrategyChoice, BaseFixture)
using fw::Strategy;
@@ -57,7 +58,7 @@
BOOST_CHECK_EQUAL(getA.first, false);
}
-BOOST_AUTO_TEST_CASE(Effective)
+BOOST_AUTO_TEST_CASE(FindEffectiveStrategy)
{
Forwarder forwarder;
Name nameP("ndn:/strategy/P");
@@ -124,13 +125,61 @@
BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/D") .getName(), nameQ);
}
+BOOST_AUTO_TEST_CASE(FindEffectiveStrategyWithPitEntry)
+{
+ Forwarder forwarder;
+ Name nameP("ndn:/strategy/P");
+ Name nameQ("ndn:/strategy/Q");
+ shared_ptr<Strategy> strategyP = make_shared<DummyStrategy>(ref(forwarder), nameP);
+ shared_ptr<Strategy> strategyQ = make_shared<DummyStrategy>(ref(forwarder), nameQ);
+ StrategyChoice& table = forwarder.getStrategyChoice();
+ table.install(strategyP);
+ table.install(strategyQ);
+
+ shared_ptr<Data> dataABC = makeData("/A/B/C");
+ Name fullName = dataABC->getFullName();
+
+ BOOST_CHECK(table.insert("/A", nameP));
+ BOOST_CHECK(table.insert(fullName, nameQ));
+
+ Pit& pit = forwarder.getPit();
+ shared_ptr<Interest> interestAB = makeInterest("/A/B");
+ shared_ptr<pit::Entry> pitAB = pit.insert(*interestAB).first;
+ shared_ptr<Interest> interestFull = makeInterest(fullName);
+ shared_ptr<pit::Entry> pitFull = pit.insert(*interestFull).first;
+
+ BOOST_CHECK_EQUAL(table.findEffectiveStrategy(*pitAB).getName(), nameP);
+ BOOST_CHECK_EQUAL(table.findEffectiveStrategy(*pitFull).getName(), nameQ);
+}
+
+BOOST_AUTO_TEST_CASE(FindEffectiveStrategyWithMeasurementsEntry)
+{
+ Forwarder forwarder;
+ Name nameP("ndn:/strategy/P");
+ Name nameQ("ndn:/strategy/Q");
+ shared_ptr<Strategy> strategyP = make_shared<DummyStrategy>(ref(forwarder), nameP);
+ shared_ptr<Strategy> strategyQ = make_shared<DummyStrategy>(ref(forwarder), nameQ);
+ StrategyChoice& table = forwarder.getStrategyChoice();
+ table.install(strategyP);
+ table.install(strategyQ);
+
+ BOOST_CHECK(table.insert("/A", nameP));
+ BOOST_CHECK(table.insert("/A/B/C", nameQ));
+
+ Measurements& measurements = forwarder.getMeasurements();
+ shared_ptr<measurements::Entry> mAB = measurements.get("/A/B");
+ shared_ptr<measurements::Entry> mABCD = measurements.get("/A/B/C/D");
+
+ BOOST_CHECK_EQUAL(table.findEffectiveStrategy(*mAB).getName(), nameP);
+ BOOST_CHECK_EQUAL(table.findEffectiveStrategy(*mABCD).getName(), nameQ);
+}
+
//XXX BOOST_CONCEPT_ASSERT((ForwardIterator<std::vector<int>::iterator>))
// is also failing. There might be a problem with ForwardIterator concept checking.
//BOOST_CONCEPT_ASSERT((ForwardIterator<StrategyChoice::const_iterator>));
BOOST_AUTO_TEST_CASE(Enumerate)
{
-
Forwarder forwarder;
Name nameP("ndn:/strategy/P");
Name nameQ("ndn:/strategy/Q");
@@ -305,7 +354,8 @@
BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/").getName(), name4);
}
-BOOST_AUTO_TEST_SUITE_END()
+BOOST_AUTO_TEST_SUITE_END() // TestStrategyChoice
+BOOST_AUTO_TEST_SUITE_END() // Table
} // namespace tests
} // namespace nfd