table: fix Pit::find leak of NameTreeEntry
refs #3619
Change-Id: If1043a08c9f4f8bb53cad77d2b6f21991553e1cc
diff --git a/daemon/table/pit.cpp b/daemon/table/pit.cpp
index 7286cbe..5db1ce2 100644
--- a/daemon/table/pit.cpp
+++ b/daemon/table/pit.cpp
@@ -60,14 +60,26 @@
std::pair<shared_ptr<pit::Entry>, bool>
Pit::findOrInsert(const Interest& interest, bool allowInsert)
{
- // ensure NameTree entry exists
+ // determine which NameTree entry should the PIT entry be attached onto
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 Name& nteName = isEndWithDigest ? name.getPrefix(-1) : name;
+
+ // ensure NameTree entry exists
+ shared_ptr<name_tree::Entry> nte;
+ if (allowInsert) {
+ nte = m_nameTree.lookup(nteName);
+ BOOST_ASSERT(nte != nullptr);
+ }
+ else {
+ nte = m_nameTree.findExactMatch(nteName);
+ if (nte == nullptr) {
+ return {nullptr, true};
+ }
+ }
// check if PIT entry already exists
+ size_t nteNameLen = nteName.size();
const std::vector<shared_ptr<pit::Entry>>& pitEntries = nte->getPitEntries();
auto it = std::find_if(pitEntries.begin(), pitEntries.end(),
[&interest, nteNameLen] (const shared_ptr<pit::Entry>& entry) -> bool {
@@ -84,12 +96,13 @@
}
if (!allowInsert) {
+ BOOST_ASSERT(!nte->isEmpty()); // nte shouldn't be created in this call
return {nullptr, true};
}
auto entry = make_shared<pit::Entry>(interest);
nte->insertPitEntry(entry);
- m_nItems++;
+ ++m_nItems;
return {entry, true};
}
diff --git a/tests/daemon/table/pit.t.cpp b/tests/daemon/table/pit.t.cpp
index 80e31d3..0418f7e 100644
--- a/tests/daemon/table/pit.t.cpp
+++ b/tests/daemon/table/pit.t.cpp
@@ -197,6 +197,25 @@
BOOST_AUTO_TEST_SUITE_END() // PitEntry
+BOOST_AUTO_TEST_CASE(Find)
+{
+ shared_ptr<Interest> interest1 = makeInterest("/6hNwxJjw");
+ shared_ptr<Interest> interest2 = makeInterest("/v65zqxm4d");
+
+ NameTree nameTree(16);
+ Pit pit(nameTree);
+
+ pit.insert(*interest1);
+ shared_ptr<pit::Entry> found1a = pit.find(*interest1);
+ shared_ptr<pit::Entry> found1b = pit.find(*interest1);
+ BOOST_CHECK(found1a != nullptr);
+ BOOST_CHECK(found1a == found1b);
+
+ shared_ptr<pit::Entry> found2 = pit.find(*interest2);
+ BOOST_CHECK(found2 == nullptr);
+ BOOST_CHECK(nameTree.findExactMatch(interest2->getName()) == nullptr);
+}
+
BOOST_AUTO_TEST_CASE(Insert)
{
Name name1("ndn:/5vzBNnMst");