table: don't use shared_ptr in Measurements

refs #3164

Change-Id: I7705d00ac155b15b5db69809610b68e96360a0ae
diff --git a/daemon/fw/access-strategy.cpp b/daemon/fw/access-strategy.cpp
index 69c1a39..bb41fba 100644
--- a/daemon/fw/access-strategy.cpp
+++ b/daemon/fw/access-strategy.cpp
@@ -235,7 +235,7 @@
 std::tuple<Name, shared_ptr<AccessStrategy::MtInfo>>
 AccessStrategy::findPrefixMeasurements(const pit::Entry& pitEntry)
 {
-  shared_ptr<measurements::Entry> me = this->getMeasurements().findLongestPrefixMatch(pitEntry);
+  measurements::Entry* me = this->getMeasurements().findLongestPrefixMatch(pitEntry);
   if (me == nullptr) {
     return std::forward_as_tuple(Name(), nullptr);
   }
@@ -250,8 +250,8 @@
 shared_ptr<AccessStrategy::MtInfo>
 AccessStrategy::addPrefixMeasurements(const Data& data)
 {
-  shared_ptr<measurements::Entry> me;
-  if (data.getName().size() >= 1) {
+  measurements::Entry* me = nullptr;
+  if (!data.getName().empty()) {
     me = this->getMeasurements().get(data.getName().getPrefix(-1));
   }
   if (me == nullptr) { // parent of Data Name is not in this strategy, or Data Name is empty
diff --git a/daemon/fw/asf-measurements.cpp b/daemon/fw/asf-measurements.cpp
index 1a2eca2..11249f8 100644
--- a/daemon/fw/asf-measurements.cpp
+++ b/daemon/fw/asf-measurements.cpp
@@ -219,14 +219,14 @@
 shared_ptr<NamespaceInfo>
 AsfMeasurements::getNamespaceInfo(const ndn::Name& prefix)
 {
-  shared_ptr<measurements::Entry> me = m_measurements.findLongestPrefixMatch(prefix);
+  measurements::Entry* me = m_measurements.findLongestPrefixMatch(prefix);
 
   if (me == nullptr) {
     return nullptr;
   }
 
   // Set or update entry lifetime
-  extendLifetime(me);
+  extendLifetime(*me);
 
   shared_ptr<NamespaceInfo> info = me->getOrCreateStrategyInfo<NamespaceInfo>();
   BOOST_ASSERT(info != nullptr);
@@ -237,7 +237,7 @@
 NamespaceInfo&
 AsfMeasurements::getOrCreateNamespaceInfo(const fib::Entry& fibEntry, const ndn::Interest& interest)
 {
-  shared_ptr<measurements::Entry> me = m_measurements.get(fibEntry);
+  measurements::Entry* me = m_measurements.get(fibEntry);
 
   // If the FIB entry is not under the strategy's namespace, find a part of the prefix
   // that falls under the strategy's namespace
@@ -250,7 +250,7 @@
   BOOST_ASSERT(me != nullptr);
 
   // Set or update entry lifetime
-  extendLifetime(me);
+  extendLifetime(*me);
 
   shared_ptr<NamespaceInfo> info = me->getOrCreateStrategyInfo<NamespaceInfo>();
   BOOST_ASSERT(info != nullptr);
@@ -259,11 +259,9 @@
 }
 
 void
-AsfMeasurements::extendLifetime(shared_ptr<measurements::Entry> me)
+AsfMeasurements::extendLifetime(measurements::Entry& me)
 {
-  if (me != nullptr) {
-    m_measurements.extendLifetime(*me, MEASUREMENTS_LIFETIME);
-  }
+  m_measurements.extendLifetime(me, MEASUREMENTS_LIFETIME);
 }
 
 } // namespace asf
diff --git a/daemon/fw/asf-measurements.hpp b/daemon/fw/asf-measurements.hpp
index 8339d97..64f88c2 100644
--- a/daemon/fw/asf-measurements.hpp
+++ b/daemon/fw/asf-measurements.hpp
@@ -294,8 +294,9 @@
   NamespaceInfo&
   getOrCreateNamespaceInfo(const fib::Entry& fibEntry, const ndn::Interest& interest);
 
+private:
   void
-  extendLifetime(shared_ptr<measurements::Entry> me);
+  extendLifetime(measurements::Entry& me);
 
 public:
   static constexpr time::microseconds MEASUREMENTS_LIFETIME = time::seconds(300);
diff --git a/daemon/fw/ncc-strategy.cpp b/daemon/fw/ncc-strategy.cpp
index fc9cd20..213ce59 100644
--- a/daemon/fw/ncc-strategy.cpp
+++ b/daemon/fw/ncc-strategy.cpp
@@ -66,23 +66,22 @@
     return;
   }
 
-  shared_ptr<MeasurementsEntryInfo> measurementsEntryInfo =
-    this->getMeasurementsEntryInfo(pitEntry);
+  MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(pitEntry);
 
   time::microseconds deferFirst = DEFER_FIRST_WITHOUT_BEST_FACE;
   time::microseconds deferRange = DEFER_RANGE_WITHOUT_BEST_FACE;
   size_t nUpstreams = nexthops.size();
 
-  shared_ptr<Face> bestFace = measurementsEntryInfo->getBestFace();
+  shared_ptr<Face> bestFace = meInfo.getBestFace();
   if (bestFace != nullptr && fibEntry.hasNextHop(*bestFace) &&
       canForwardToLegacy(*pitEntry, *bestFace)) {
     // TODO Should we use `randlow = 100 + nrand48(h->seed) % 4096U;` ?
-    deferFirst = measurementsEntryInfo->prediction;
+    deferFirst = meInfo.prediction;
     deferRange = time::microseconds((deferFirst.count() + 1) / 2);
     --nUpstreams;
     this->sendInterest(pitEntry, *bestFace);
     pitEntryInfo->bestFaceTimeout = scheduler::schedule(
-      measurementsEntryInfo->prediction,
+      meInfo.prediction,
       bind(&NccStrategy::timeoutOnBestFace, this, weak_ptr<pit::Entry>(pitEntry)));
   }
   else {
@@ -96,7 +95,7 @@
     }
   }
 
-  shared_ptr<Face> previousFace = measurementsEntryInfo->previousFace.lock();
+  shared_ptr<Face> previousFace = meInfo.previousFace.lock();
   if (previousFace != nullptr && fibEntry.hasNextHop(*previousFace) &&
       canForwardToLegacy(*pitEntry, *previousFace)) {
     --nUpstreams;
@@ -131,10 +130,9 @@
   // from a timer set by NccStrategy.
   BOOST_ASSERT(pitEntryInfo != nullptr);
 
-  shared_ptr<MeasurementsEntryInfo> measurementsEntryInfo =
-    this->getMeasurementsEntryInfo(pitEntry);
+  MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(pitEntry);
 
-  shared_ptr<Face> previousFace = measurementsEntryInfo->previousFace.lock();
+  shared_ptr<Face> previousFace = meInfo.previousFace.lock();
   if (previousFace != nullptr && fibEntry.hasNextHop(*previousFace) &&
       canForwardToLegacy(*pitEntry, *previousFace)) {
     this->sendInterest(pitEntry, *previousFace);
@@ -156,8 +154,7 @@
       pitEntryInfo->maxInterval.count() - 1);
     time::nanoseconds deferNext = time::nanoseconds(dist(getGlobalRng()));
     pitEntryInfo->propagateTimer = scheduler::schedule(deferNext,
-    bind(&NccStrategy::doPropagate, this,
-         weak_ptr<pit::Entry>(pitEntry)));
+      bind(&NccStrategy::doPropagate, this, weak_ptr<pit::Entry>(pitEntry)));
   }
 }
 
@@ -165,21 +162,20 @@
 NccStrategy::timeoutOnBestFace(weak_ptr<pit::Entry> pitEntryWeak)
 {
   shared_ptr<pit::Entry> pitEntry = pitEntryWeak.lock();
-  if (!static_cast<bool>(pitEntry)) {
+  if (pitEntry == nullptr) {
     return;
   }
-  shared_ptr<measurements::Entry> measurementsEntry = this->getMeasurements().get(*pitEntry);
+  measurements::Entry* measurementsEntry = this->getMeasurements().get(*pitEntry);
 
   for (int i = 0; i < UPDATE_MEASUREMENTS_N_LEVELS; ++i) {
-    if (!static_cast<bool>(measurementsEntry)) {
+    if (measurementsEntry == nullptr) {
       // going out of this strategy's namespace
-      return;
+      break;
     }
     this->getMeasurements().extendLifetime(*measurementsEntry, MEASUREMENTS_LIFETIME);
 
-    shared_ptr<MeasurementsEntryInfo> measurementsEntryInfo =
-      this->getMeasurementsEntryInfo(measurementsEntry);
-    measurementsEntryInfo->adjustPredictUp();
+    MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(measurementsEntry);
+    meInfo.adjustPredictUp();
 
     measurementsEntry = this->getMeasurements().getParent(*measurementsEntry);
   }
@@ -195,18 +191,17 @@
     return;
   }
 
-  shared_ptr<measurements::Entry> measurementsEntry = this->getMeasurements().get(*pitEntry);
+  measurements::Entry* measurementsEntry = this->getMeasurements().get(*pitEntry);
 
   for (int i = 0; i < UPDATE_MEASUREMENTS_N_LEVELS; ++i) {
-    if (!static_cast<bool>(measurementsEntry)) {
+    if (measurementsEntry == nullptr) {
       // going out of this strategy's namespace
       return;
     }
     this->getMeasurements().extendLifetime(*measurementsEntry, MEASUREMENTS_LIFETIME);
 
-    shared_ptr<MeasurementsEntryInfo> measurementsEntryInfo =
-      this->getMeasurementsEntryInfo(measurementsEntry);
-    measurementsEntryInfo->updateBestFace(inFace);
+    MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(measurementsEntry);
+    meInfo.updateBestFace(inFace);
 
     measurementsEntry = this->getMeasurements().getParent(*measurementsEntry);
   }
@@ -216,41 +211,40 @@
     scheduler::cancel(pitEntryInfo->propagateTimer);
 
     // Verify that the best face satisfied the interest before canceling the timeout call
-    shared_ptr<MeasurementsEntryInfo> measurementsEntryInfo =
-      this->getMeasurementsEntryInfo(pitEntry);
-    shared_ptr<Face> bestFace = measurementsEntryInfo->getBestFace();
+    MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(pitEntry);
+    shared_ptr<Face> bestFace = meInfo.getBestFace();
 
     if (bestFace.get() == &inFace)
       scheduler::cancel(pitEntryInfo->bestFaceTimeout);
   }
 }
 
-shared_ptr<NccStrategy::MeasurementsEntryInfo>
+NccStrategy::MeasurementsEntryInfo&
 NccStrategy::getMeasurementsEntryInfo(shared_ptr<pit::Entry> entry)
 {
-  shared_ptr<measurements::Entry> measurementsEntry = this->getMeasurements().get(*entry);
+  measurements::Entry* measurementsEntry = this->getMeasurements().get(*entry);
   return this->getMeasurementsEntryInfo(measurementsEntry);
 }
 
-shared_ptr<NccStrategy::MeasurementsEntryInfo>
-NccStrategy::getMeasurementsEntryInfo(shared_ptr<measurements::Entry> entry)
+NccStrategy::MeasurementsEntryInfo&
+NccStrategy::getMeasurementsEntryInfo(measurements::Entry* entry)
 {
+  BOOST_ASSERT(entry != nullptr);
   shared_ptr<MeasurementsEntryInfo> info = entry->getStrategyInfo<MeasurementsEntryInfo>();
-  if (static_cast<bool>(info)) {
-    return info;
+  if (info != nullptr) {
+    return *info;
   }
 
   info = make_shared<MeasurementsEntryInfo>();
   entry->setStrategyInfo(info);
 
-  shared_ptr<measurements::Entry> parentEntry = this->getMeasurements().getParent(*entry);
-  if (static_cast<bool>(parentEntry)) {
-    shared_ptr<MeasurementsEntryInfo> parentInfo = this->getMeasurementsEntryInfo(parentEntry);
-    BOOST_ASSERT(static_cast<bool>(parentInfo));
-    info->inheritFrom(*parentInfo);
+  measurements::Entry* parentEntry = this->getMeasurements().getParent(*entry);
+  if (parentEntry != nullptr) {
+    MeasurementsEntryInfo& parentInfo = this->getMeasurementsEntryInfo(parentEntry);
+    info->inheritFrom(parentInfo);
   }
 
-  return info;
+  return *info;
 }
 
 
@@ -275,7 +269,7 @@
 shared_ptr<Face>
 NccStrategy::MeasurementsEntryInfo::getBestFace(void) {
   shared_ptr<Face> best = this->bestFace.lock();
-  if (static_cast<bool>(best)) {
+  if (best != nullptr) {
     return best;
   }
   this->bestFace = best = this->previousFace.lock();
diff --git a/daemon/fw/ncc-strategy.hpp b/daemon/fw/ncc-strategy.hpp
index bfbb06d..80e2918 100644
--- a/daemon/fw/ncc-strategy.hpp
+++ b/daemon/fw/ncc-strategy.hpp
@@ -117,10 +117,10 @@
   };
 
 protected:
-  shared_ptr<MeasurementsEntryInfo>
-  getMeasurementsEntryInfo(shared_ptr<measurements::Entry> entry);
+  MeasurementsEntryInfo&
+  getMeasurementsEntryInfo(measurements::Entry* entry);
 
-  shared_ptr<MeasurementsEntryInfo>
+  MeasurementsEntryInfo&
   getMeasurementsEntryInfo(shared_ptr<pit::Entry> entry);
 
   /// propagate to another upstream
diff --git a/daemon/table/measurements-accessor.cpp b/daemon/table/measurements-accessor.cpp
index 47b4fe2..68cf784 100644
--- a/daemon/table/measurements-accessor.cpp
+++ b/daemon/table/measurements-accessor.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,
@@ -26,6 +26,7 @@
 #include "measurements-accessor.hpp"
 
 namespace nfd {
+namespace measurements {
 
 using fw::Strategy;
 
@@ -42,8 +43,8 @@
 {
 }
 
-shared_ptr<measurements::Entry>
-MeasurementsAccessor::filter(const shared_ptr<measurements::Entry>& entry) const
+Entry*
+MeasurementsAccessor::filter(Entry* entry) const
 {
   if (entry == nullptr) {
     return entry;
@@ -53,7 +54,8 @@
   if (&effectiveStrategy == m_strategy) {
     return entry;
   }
-  return shared_ptr<measurements::Entry>();
+  return nullptr;
 }
 
+} // namespace measurements
 } // namespace nfd
diff --git a/daemon/table/measurements-accessor.hpp b/daemon/table/measurements-accessor.hpp
index 9a280c2..244897b 100644
--- a/daemon/table/measurements-accessor.hpp
+++ b/daemon/table/measurements-accessor.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,
@@ -33,9 +33,14 @@
 
 namespace fw {
 class Strategy;
-}
+} // namespace fw
+
+namespace measurements {
 
 /** \brief allows Strategy to access portion of Measurements table under its namespace
+ *
+ *  All public methods have the same semantics as the same method on \p Measurements,
+ *  but would return nullptr if the entry falls out of the strategy's authority.
  */
 class MeasurementsAccessor : noncopyable
 {
@@ -47,42 +52,41 @@
 
   /** \brief find or insert a Measurements entry for \p name
    */
-  shared_ptr<measurements::Entry>
+  Entry*
   get(const Name& name);
 
   /** \brief find or insert a Measurements entry for \p fibEntry->getPrefix()
    */
-  shared_ptr<measurements::Entry>
+  Entry*
   get(const fib::Entry& fibEntry);
 
   /** \brief find or insert a Measurements entry for \p pitEntry->getName()
    */
-  shared_ptr<measurements::Entry>
+  Entry*
   get(const pit::Entry& pitEntry);
 
   /** \brief find or insert a Measurements entry for child's parent
-   *  \retval nullptr if child is the root entry
    */
-  shared_ptr<measurements::Entry>
-  getParent(const measurements::Entry& child);
+  Entry*
+  getParent(const Entry& child);
 
   /** \brief perform a longest prefix match for \p name
    */
-  shared_ptr<measurements::Entry>
+  Entry*
   findLongestPrefixMatch(const Name& name,
-                         const measurements::EntryPredicate& pred =
-                             measurements::AnyEntry()) const;
+                         const EntryPredicate& pred =
+                             AnyEntry()) const;
 
   /** \brief perform a longest prefix match for \p pitEntry.getName()
    */
-  shared_ptr<measurements::Entry>
+  Entry*
   findLongestPrefixMatch(const pit::Entry& pitEntry,
-                         const measurements::EntryPredicate& pred =
-                             measurements::AnyEntry()) const;
+                         const EntryPredicate& pred =
+                             AnyEntry()) const;
 
   /** \brief perform an exact match
    */
-  shared_ptr<measurements::Entry>
+  Entry*
   findExactMatch(const Name& name) const;
 
   /** \brief extend lifetime of an entry
@@ -90,14 +94,17 @@
    *  The entry will be kept until at least now()+lifetime.
    */
   void
-  extendLifetime(measurements::Entry& entry, const time::nanoseconds& lifetime);
+  extendLifetime(Entry& entry, const time::nanoseconds& lifetime);
 
 private:
   /** \brief perform access control to Measurements entry
    *  \return entry if strategy has access to namespace, otherwise nullptr
    */
-  shared_ptr<measurements::Entry>
-  filter(const shared_ptr<measurements::Entry>& entry) const;
+  Entry*
+  filter(Entry* entry) const;
+
+  Entry*
+  filter(Entry& entry) const;
 
 private:
   Measurements& m_measurements;
@@ -105,57 +112,66 @@
   const fw::Strategy* m_strategy;
 };
 
-inline shared_ptr<measurements::Entry>
+inline Entry*
+MeasurementsAccessor::filter(Entry& entry) const
+{
+  return this->filter(&entry);
+}
+
+inline Entry*
 MeasurementsAccessor::get(const Name& name)
 {
   return this->filter(m_measurements.get(name));
 }
 
-inline shared_ptr<measurements::Entry>
+inline Entry*
 MeasurementsAccessor::get(const fib::Entry& fibEntry)
 {
   return this->filter(m_measurements.get(fibEntry));
 }
 
-inline shared_ptr<measurements::Entry>
+inline Entry*
 MeasurementsAccessor::get(const pit::Entry& pitEntry)
 {
   return this->filter(m_measurements.get(pitEntry));
 }
 
-inline shared_ptr<measurements::Entry>
-MeasurementsAccessor::getParent(const measurements::Entry& child)
+inline Entry*
+MeasurementsAccessor::getParent(const Entry& child)
 {
   return this->filter(m_measurements.getParent(child));
 }
 
-inline shared_ptr<measurements::Entry>
+inline Entry*
 MeasurementsAccessor::findLongestPrefixMatch(const Name& name,
-                                             const measurements::EntryPredicate& pred) const
+                                             const EntryPredicate& pred) const
 {
   return this->filter(m_measurements.findLongestPrefixMatch(name, pred));
 }
 
-inline shared_ptr<measurements::Entry>
+inline Entry*
 MeasurementsAccessor::findLongestPrefixMatch(const pit::Entry& pitEntry,
-                                             const measurements::EntryPredicate& pred) const
+                                             const EntryPredicate& pred) const
 {
   return this->filter(m_measurements.findLongestPrefixMatch(pitEntry, pred));
 }
 
-inline shared_ptr<measurements::Entry>
+inline Entry*
 MeasurementsAccessor::findExactMatch(const Name& name) const
 {
   return this->filter(m_measurements.findExactMatch(name));
 }
 
 inline void
-MeasurementsAccessor::extendLifetime(measurements::Entry& entry,
-                                     const time::nanoseconds& lifetime)
+MeasurementsAccessor::extendLifetime(Entry& entry, const time::nanoseconds& lifetime)
 {
   m_measurements.extendLifetime(entry, lifetime);
 }
 
+} // namespace measurements
+
+using measurements::MeasurementsAccessor;
+
 } // namespace nfd
 
 #endif // NFD_DAEMON_TABLE_MEASUREMENTS_ACCESSOR_HPP
diff --git a/daemon/table/measurements-entry.hpp b/daemon/table/measurements-entry.hpp
index 0c9bc48..8eb40ff 100644
--- a/daemon/table/measurements-entry.hpp
+++ b/daemon/table/measurements-entry.hpp
@@ -38,12 +38,11 @@
 class Entry;
 } // namespace name_tree
 
-class Measurements;
-
 namespace measurements {
 
-/** \class Entry
- *  \brief represents a Measurements entry
+class Measurements;
+
+/** \brief represents a Measurements entry
  */
 class Entry : public StrategyInfoHost, noncopyable
 {
@@ -64,7 +63,7 @@
 
   friend class nfd::NameTree;
   friend class nfd::name_tree::Entry;
-  friend class nfd::Measurements;
+  friend class Measurements;
 };
 
 inline const Name&
diff --git a/daemon/table/measurements.cpp b/daemon/table/measurements.cpp
index 5981371..60e4f8d 100644
--- a/daemon/table/measurements.cpp
+++ b/daemon/table/measurements.cpp
@@ -29,8 +29,7 @@
 #include "fib-entry.hpp"
 
 namespace nfd {
-
-using measurements::Entry;
+namespace measurements {
 
 Measurements::Measurements(NameTree& nameTree)
   : m_nameTree(nameTree)
@@ -38,37 +37,39 @@
 {
 }
 
-shared_ptr<Entry>
+Entry&
 Measurements::get(name_tree::Entry& nte)
 {
-  shared_ptr<Entry> entry = nte.getMeasurementsEntry();
-  if (entry != nullptr)
-    return entry;
+  Entry* entry = nte.getMeasurementsEntry();
+  if (entry != nullptr) {
+    return *entry;
+  }
 
-  entry = make_shared<Entry>(nte.getPrefix());
-  nte.setMeasurementsEntry(entry);
+  nte.setMeasurementsEntry(make_unique<Entry>(nte.getPrefix()));
   ++m_nItems;
+  entry = nte.getMeasurementsEntry();
 
   entry->m_expiry = time::steady_clock::now() + getInitialLifetime();
   entry->m_cleanup = scheduler::schedule(getInitialLifetime(),
                                          bind(&Measurements::cleanup, this, ref(*entry)));
 
-  return entry;
+  return *entry;
 }
 
-shared_ptr<Entry>
+Entry&
 Measurements::get(const Name& name)
 {
   shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(name);
+  BOOST_ASSERT(nte != nullptr);
   return this->get(*nte);
 }
 
-shared_ptr<Entry>
+Entry&
 Measurements::get(const fib::Entry& fibEntry)
 {
   shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(fibEntry);
   if (nte == nullptr) {
-    // must be Fib::s_emptyEntry that is unattched
+    // must be Fib::s_emptyEntry that is unattached
     BOOST_ASSERT(fibEntry.getPrefix().empty());
     nte = m_nameTree.lookup(fibEntry.getPrefix());
   }
@@ -77,36 +78,35 @@
   return this->get(*nte);
 }
 
-shared_ptr<Entry>
+Entry&
 Measurements::get(const pit::Entry& pitEntry)
 {
   shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(pitEntry);
   BOOST_ASSERT(nte != nullptr);
-
   return this->get(*nte);
 }
 
-shared_ptr<Entry>
+Entry*
 Measurements::getParent(const Entry& child)
 {
-  if (child.getName().size() == 0) { // the root entry
+  if (child.getName().empty()) { // the root entry
     return nullptr;
   }
 
   shared_ptr<name_tree::Entry> nteChild = m_nameTree.lookup(child);
   shared_ptr<name_tree::Entry> nte = nteChild->getParent();
   BOOST_ASSERT(nte != nullptr);
-  return this->get(*nte);
+  return &this->get(*nte);
 }
 
 template<typename K>
-shared_ptr<Entry>
+Entry*
 Measurements::findLongestPrefixMatchImpl(const K& key,
-                                         const measurements::EntryPredicate& pred) const
+                                         const EntryPredicate& pred) const
 {
   shared_ptr<name_tree::Entry> match = m_nameTree.findLongestPrefixMatch(key,
-      [pred] (const name_tree::Entry& nte) -> bool {
-        shared_ptr<Entry> entry = nte.getMeasurementsEntry();
+      [&pred] (const name_tree::Entry& nte) -> bool {
+        Entry* entry = nte.getMeasurementsEntry();
         return entry != nullptr && pred(*entry);
       });
   if (match != nullptr) {
@@ -115,28 +115,29 @@
   return nullptr;
 }
 
-shared_ptr<Entry>
+Entry*
 Measurements::findLongestPrefixMatch(const Name& name,
-                                     const measurements::EntryPredicate& pred) const
+                                     const EntryPredicate& pred) const
 {
   return this->findLongestPrefixMatchImpl(name, pred);
 }
 
-shared_ptr<Entry>
+Entry*
 Measurements::findLongestPrefixMatch(const pit::Entry& pitEntry,
-                                     const measurements::EntryPredicate& pred) const
+                                     const EntryPredicate& pred) const
 {
   shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(pitEntry);
   BOOST_ASSERT(nte != nullptr);
   return this->findLongestPrefixMatchImpl(nte, pred);
 }
 
-shared_ptr<Entry>
+Entry*
 Measurements::findExactMatch(const Name& name) const
 {
   shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(name);
-  if (nte != nullptr)
+  if (nte != nullptr) {
     return nte->getMeasurementsEntry();
+  }
   return nullptr;
 }
 
@@ -144,10 +145,7 @@
 Measurements::extendLifetime(Entry& entry, const time::nanoseconds& lifetime)
 {
   shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(entry);
-  if (nte == nullptr || nte->getMeasurementsEntry().get() != &entry) {
-    // entry is already gone; it is a dangling reference
-    return;
-  }
+  BOOST_ASSERT(nte != nullptr);
 
   time::steady_clock::TimePoint expiry = time::steady_clock::now() + lifetime;
   if (entry.m_expiry >= expiry) {
@@ -164,11 +162,12 @@
 Measurements::cleanup(Entry& entry)
 {
   shared_ptr<name_tree::Entry> nte = m_nameTree.lookup(entry);
-  if (nte != nullptr) {
-    nte->setMeasurementsEntry(nullptr);
-    m_nameTree.eraseEntryIfEmpty(nte);
-    m_nItems--;
-  }
+  BOOST_ASSERT(nte != nullptr);
+
+  nte->setMeasurementsEntry(nullptr);
+  m_nameTree.eraseEntryIfEmpty(nte);
+  --m_nItems;
 }
 
+} // namespace measurements
 } // namespace nfd
diff --git a/daemon/table/measurements.hpp b/daemon/table/measurements.hpp
index 5a61caa..cf9783d 100644
--- a/daemon/table/measurements.hpp
+++ b/daemon/table/measurements.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,
@@ -41,35 +41,35 @@
 
 namespace measurements {
 
-/** \brief a predicate that accepts or rejects a \p Entry
+/** \brief a predicate that accepts or rejects an entry
  */
 typedef std::function<bool(const Entry&)> EntryPredicate;
 
-/** \brief an \p EntryPredicate that accepts any \p Entry
+/** \brief an \p EntryPredicate that accepts any entry
  */
 class AnyEntry
 {
 public:
   bool
-  operator()(const Entry& entry)
+  operator()(const Entry& entry) const
   {
     return true;
   }
 };
 
+/** \brief an \p EntryPredicate that accepts an entry if it has StrategyInfo of type T
+ */
 template<typename T>
 class EntryWithStrategyInfo
 {
 public:
   bool
-  operator()(const Entry& entry)
+  operator()(const Entry& entry) const
   {
     return entry.getStrategyInfo<T>() != nullptr;
   }
 };
 
-} // namespace measurements
-
 /** \brief represents the Measurements table
  */
 class Measurements : noncopyable
@@ -80,42 +80,40 @@
 
   /** \brief find or insert a Measurements entry for \p name
    */
-  shared_ptr<measurements::Entry>
+  Entry&
   get(const Name& name);
 
   /** \brief find or insert a Measurements entry for \p fibEntry.getPrefix()
    */
-  shared_ptr<measurements::Entry>
+  Entry&
   get(const fib::Entry& fibEntry);
 
   /** \brief find or insert a Measurements entry for \p pitEntry.getName()
    */
-  shared_ptr<measurements::Entry>
+  Entry&
   get(const pit::Entry& pitEntry);
 
   /** \brief find or insert a Measurements entry for child's parent
    *  \retval nullptr if child is the root entry
    */
-  shared_ptr<measurements::Entry>
-  getParent(const measurements::Entry& child);
+  Entry*
+  getParent(const Entry& child);
 
   /** \brief perform a longest prefix match for \p name
    */
-  shared_ptr<measurements::Entry>
+  Entry*
   findLongestPrefixMatch(const Name& name,
-                         const measurements::EntryPredicate& pred =
-                             measurements::AnyEntry()) const;
+                         const EntryPredicate& pred = AnyEntry()) const;
 
   /** \brief perform a longest prefix match for \p pitEntry.getName()
    */
-  shared_ptr<measurements::Entry>
+  Entry*
   findLongestPrefixMatch(const pit::Entry& pitEntry,
-                         const measurements::EntryPredicate& pred =
-                             measurements::AnyEntry()) const;
+                         const EntryPredicate& pred = AnyEntry()) const;
 
   /** \brief perform an exact match
    */
-  shared_ptr<measurements::Entry>
+  Entry*
   findExactMatch(const Name& name) const;
 
   static time::nanoseconds
@@ -126,23 +124,23 @@
    *  The entry will be kept until at least now()+lifetime.
    */
   void
-  extendLifetime(measurements::Entry& entry, const time::nanoseconds& lifetime);
+  extendLifetime(Entry& entry, const time::nanoseconds& lifetime);
 
   size_t
   size() const;
 
 private:
   void
-  cleanup(measurements::Entry& entry);
+  cleanup(Entry& entry);
 
-  shared_ptr<measurements::Entry>
+  Entry&
   get(name_tree::Entry& nte);
 
   /** \tparam K Name or shared_ptr<name_tree::Entry>
    */
   template<typename K>
-  shared_ptr<measurements::Entry>
-  findLongestPrefixMatchImpl(const K& key, const measurements::EntryPredicate& pred) const;
+  Entry*
+  findLongestPrefixMatchImpl(const K& key, const EntryPredicate& pred) const;
 
 private:
   NameTree& m_nameTree;
@@ -161,6 +159,10 @@
   return m_nItems;
 }
 
+} // namespace measurements
+
+using measurements::Measurements;
+
 } // namespace nfd
 
 #endif // NFD_DAEMON_TABLE_MEASUREMENTS_HPP
diff --git a/daemon/table/name-tree-entry.cpp b/daemon/table/name-tree-entry.cpp
index 3244059..b094e38 100644
--- a/daemon/table/name-tree-entry.cpp
+++ b/daemon/table/name-tree-entry.cpp
@@ -104,14 +104,14 @@
 }
 
 void
-Entry::setMeasurementsEntry(shared_ptr<measurements::Entry> measurementsEntry)
+Entry::setMeasurementsEntry(unique_ptr<measurements::Entry> measurementsEntry)
 {
   BOOST_ASSERT(measurementsEntry == nullptr || measurementsEntry->m_nameTreeEntry.expired());
 
   if (m_measurementsEntry != nullptr) {
     m_measurementsEntry->m_nameTreeEntry.reset();
   }
-  m_measurementsEntry = measurementsEntry;
+  m_measurementsEntry = std::move(measurementsEntry);
 
   if (m_measurementsEntry != nullptr) {
     m_measurementsEntry->m_nameTreeEntry = this->shared_from_this();
diff --git a/daemon/table/name-tree-entry.hpp b/daemon/table/name-tree-entry.hpp
index 7bade1f..2827926 100644
--- a/daemon/table/name-tree-entry.hpp
+++ b/daemon/table/name-tree-entry.hpp
@@ -114,9 +114,9 @@
   getPitEntries() const;
 
   void
-  setMeasurementsEntry(shared_ptr<measurements::Entry> measurementsEntry);
+  setMeasurementsEntry(unique_ptr<measurements::Entry> measurementsEntry);
 
-  shared_ptr<measurements::Entry>
+  measurements::Entry*
   getMeasurementsEntry() const;
 
   void
@@ -135,7 +135,7 @@
   std::vector<shared_ptr<Entry> > m_children; // Children pointers.
   unique_ptr<fib::Entry> m_fibEntry;
   std::vector<shared_ptr<pit::Entry> > m_pitEntries;
-  shared_ptr<measurements::Entry> m_measurementsEntry;
+  unique_ptr<measurements::Entry> m_measurementsEntry;
   unique_ptr<strategy_choice::Entry> m_strategyChoiceEntry;
 
   // get the Name Tree Node that is associated with this Name Tree Entry
@@ -205,10 +205,10 @@
   return m_pitEntries;
 }
 
-inline shared_ptr<measurements::Entry>
+inline measurements::Entry*
 Entry::getMeasurementsEntry() const
 {
-  return m_measurementsEntry;
+  return m_measurementsEntry.get();
 }
 
 inline strategy_choice::Entry*
diff --git a/daemon/table/name-tree.cpp b/daemon/table/name-tree.cpp
index bc7d7c7..bcf888e 100644
--- a/daemon/table/name-tree.cpp
+++ b/daemon/table/name-tree.cpp
@@ -269,7 +269,7 @@
 NameTree::lookup(const measurements::Entry& measurementsEntry) const
 {
   shared_ptr<name_tree::Entry> nte = this->getEntry(measurementsEntry);
-  BOOST_ASSERT(nte == nullptr || nte->getMeasurementsEntry().get() == &measurementsEntry);
+  BOOST_ASSERT(nte == nullptr || nte->getMeasurementsEntry() == &measurementsEntry);
   return nte;
 }
 
diff --git a/tests/daemon/fw/ncc-strategy.t.cpp b/tests/daemon/fw/ncc-strategy.t.cpp
index 251e3d6..9adc6ab 100644
--- a/tests/daemon/fw/ncc-strategy.t.cpp
+++ b/tests/daemon/fw/ncc-strategy.t.cpp
@@ -343,7 +343,7 @@
 
   auto getMeInfo = [&] () -> shared_ptr<NccStrategy::MeasurementsEntryInfo> {
     Measurements& measurements = topo.getForwarder(nodeA).getMeasurements();
-    shared_ptr<measurements::Entry> me = measurements.findExactMatch("ndn:/P");
+    measurements::Entry* me = measurements.findExactMatch("ndn:/P");
     return me == nullptr ? nullptr : me->getStrategyInfo<NccStrategy::MeasurementsEntryInfo>();
   };
 
diff --git a/tests/daemon/table/fib.t.cpp b/tests/daemon/table/fib.t.cpp
index 7071c19..46a3bca 100644
--- a/tests/daemon/table/fib.t.cpp
+++ b/tests/daemon/table/fib.t.cpp
@@ -207,11 +207,11 @@
   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");
+  measurements::Entry& mAB = measurements.get("/A/B");
+  measurements::Entry& mABCD = measurements.get("/A/B/C/D");
 
-  BOOST_CHECK_EQUAL(fib.findLongestPrefixMatch(*mAB).getPrefix(), "/A");
-  BOOST_CHECK_EQUAL(fib.findLongestPrefixMatch(*mABCD).getPrefix(), "/A/B/C");
+  BOOST_CHECK_EQUAL(fib.findLongestPrefixMatch(mAB).getPrefix(), "/A");
+  BOOST_CHECK_EQUAL(fib.findLongestPrefixMatch(mABCD).getPrefix(), "/A/B/C");
 }
 
 BOOST_AUTO_TEST_CASE(RemoveNextHopFromAllEntries)
diff --git a/tests/daemon/table/measurements-accessor.t.cpp b/tests/daemon/table/measurements-accessor.t.cpp
index cab1dbb..292c5a6 100644
--- a/tests/daemon/table/measurements-accessor.t.cpp
+++ b/tests/daemon/table/measurements-accessor.t.cpp
@@ -31,9 +31,10 @@
 #include "../fw/install-strategy.hpp"
 
 namespace nfd {
+namespace measurements {
 namespace tests {
 
-using measurements::Entry;
+using namespace nfd::tests;
 
 class MeasurementsAccessorTestStrategy : public DummyStrategy
 {
@@ -81,7 +82,8 @@
   MeasurementsAccessor& accessor2;
 };
 
-BOOST_FIXTURE_TEST_SUITE(TableMeasurementsAccessor, MeasurementsAccessorFixture)
+BOOST_AUTO_TEST_SUITE(Table)
+BOOST_FIXTURE_TEST_SUITE(TestMeasurementsAccessor, MeasurementsAccessorFixture)
 
 BOOST_AUTO_TEST_CASE(Get)
 {
@@ -100,17 +102,17 @@
 
 BOOST_AUTO_TEST_CASE(GetParent)
 {
-  shared_ptr<Entry> entryRoot = measurements.get("/");
-  BOOST_CHECK(accessor1.getParent(*entryRoot) == nullptr);
-  BOOST_CHECK(accessor2.getParent(*entryRoot) == nullptr);
+  Entry& entryRoot = measurements.get("/");
+  BOOST_CHECK(accessor1.getParent(entryRoot) == nullptr);
+  BOOST_CHECK(accessor2.getParent(entryRoot) == nullptr);
 
-  shared_ptr<Entry> entryABC = measurements.get("/A/B/C");
-  BOOST_CHECK(accessor1.getParent(*entryABC) != nullptr);
-  BOOST_CHECK(accessor2.getParent(*entryABC) == nullptr);
+  Entry& entryABC = measurements.get("/A/B/C");
+  BOOST_CHECK(accessor1.getParent(entryABC) != nullptr);
+  BOOST_CHECK(accessor2.getParent(entryABC) == nullptr);
 
-  shared_ptr<Entry> entryAB = measurements.get("/A/B");
-  BOOST_CHECK(accessor1.getParent(*entryAB) == nullptr);
-  // whether accessor2.getParent(*entryAB) can return an Entry is undefined,
+  Entry& entryAB = measurements.get("/A/B");
+  BOOST_CHECK(accessor1.getParent(entryAB) == nullptr);
+  // whether accessor2.getParent(entryAB) can return an Entry is undefined,
   // because strategy2 shouldn't obtain entryAB in the first place
 }
 
@@ -153,7 +155,9 @@
   BOOST_CHECK(accessor2.findExactMatch("/F"    ) == nullptr);
 }
 
-BOOST_AUTO_TEST_SUITE_END()
+BOOST_AUTO_TEST_SUITE_END() // TestMeasurementsAccessor
+BOOST_AUTO_TEST_SUITE_END() // Table
 
 } // namespace tests
+} // namespace measurements
 } // namespace nfd
diff --git a/tests/daemon/table/measurements.t.cpp b/tests/daemon/table/measurements.t.cpp
index c8b2e27..79b2b94 100644
--- a/tests/daemon/table/measurements.t.cpp
+++ b/tests/daemon/table/measurements.t.cpp
@@ -30,8 +30,11 @@
 #include "tests/test-common.hpp"
 
 namespace nfd {
+namespace measurements {
 namespace tests {
 
+using namespace nfd::tests;
+
 BOOST_AUTO_TEST_SUITE(Table)
 
 class MeasurementsFixture : public UnitTestTimeFixture
@@ -51,19 +54,19 @@
 
 BOOST_AUTO_TEST_CASE(Get_Parent)
 {
-  shared_ptr<measurements::Entry> entryAB = measurements.get("/A/B");
-  BOOST_REQUIRE(entryAB != nullptr);
-  BOOST_CHECK_EQUAL(entryAB->getName(), "/A/B");
+  Entry& entryAB = measurements.get("/A/B");
+  BOOST_CHECK_EQUAL(entryAB.getName(), "/A/B");
 
-  shared_ptr<measurements::Entry> entry0 = measurements.get("/");
-  BOOST_REQUIRE(entry0 != nullptr);
+  Entry& entry0 = measurements.get("/");
+  BOOST_CHECK_EQUAL(entry0.getName(), "/");
 
-  shared_ptr<measurements::Entry> entryA = measurements.getParent(*entryAB);
+  Entry* entryA = measurements.getParent(entryAB);
   BOOST_REQUIRE(entryA != nullptr);
   BOOST_CHECK_EQUAL(entryA->getName(), "/A");
 
-  shared_ptr<measurements::Entry> entry0c = measurements.getParent(*entryA);
-  BOOST_CHECK_EQUAL(entry0, entry0c);
+  Entry* entry0c = measurements.getParent(*entryA);
+  BOOST_REQUIRE(entry0c != nullptr);
+  BOOST_CHECK_EQUAL(&entry0, entry0c);
 }
 
 BOOST_AUTO_TEST_CASE(GetWithFibEntry)
@@ -73,13 +76,11 @@
   const fib::Entry* fibA = fib.insert("/A").first;
   const fib::Entry* fibAB = fib.insert("/A/B").first;
 
-  shared_ptr<measurements::Entry> entryA = measurements.get(*fibA);
-  BOOST_REQUIRE(entryA != nullptr);
-  BOOST_CHECK_EQUAL(entryA->getName(), "/A");
+  Entry& entryA = measurements.get(*fibA);
+  BOOST_CHECK_EQUAL(entryA.getName(), "/A");
 
-  shared_ptr<measurements::Entry> entryAB = measurements.get(*fibAB);
-  BOOST_REQUIRE(entryAB != nullptr);
-  BOOST_CHECK_EQUAL(entryAB->getName(), "/A/B");
+  Entry& entryAB = measurements.get(*fibAB);
+  BOOST_CHECK_EQUAL(entryAB.getName(), "/A/B");
 }
 
 BOOST_AUTO_TEST_CASE(GetWithEmptyFibEntry) // Bug 3275
@@ -88,9 +89,8 @@
 
   const fib::Entry& fib0 = fib.findLongestPrefixMatch("/");
 
-  shared_ptr<measurements::Entry> entry0 = measurements.get(fib0);
-  BOOST_REQUIRE(entry0 != nullptr);
-  BOOST_CHECK_EQUAL(entry0->getName(), "/");
+  Entry& entry0 = measurements.get(fib0);
+  BOOST_CHECK_EQUAL(entry0.getName(), "/");
 }
 
 BOOST_AUTO_TEST_CASE(GetWithPitEntry)
@@ -104,13 +104,11 @@
   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");
+  Entry& entryA = measurements.get(*pitA);
+  BOOST_CHECK_EQUAL(entryA.getName(), "/A");
 
-  shared_ptr<measurements::Entry> entryFull = measurements.get(*pitFull);
-  BOOST_REQUIRE(entryFull != nullptr);
-  BOOST_CHECK_EQUAL(entryFull->getName(), fullName);
+  Entry& entryFull = measurements.get(*pitFull);
+  BOOST_CHECK_EQUAL(entryFull.getName(), fullName);
 }
 
 class DummyStrategyInfo1 : public fw::StrategyInfo
@@ -136,20 +134,20 @@
 BOOST_AUTO_TEST_CASE(FindLongestPrefixMatch)
 {
   measurements.get("/A");
-  measurements.get("/A/B/C")->getOrCreateStrategyInfo<DummyStrategyInfo1>();
+  measurements.get("/A/B/C").getOrCreateStrategyInfo<DummyStrategyInfo1>();
   measurements.get("/A/B/C/D");
 
-  shared_ptr<measurements::Entry> found1 = measurements.findLongestPrefixMatch("/A/B/C/D/E");
+  Entry* found1 = measurements.findLongestPrefixMatch("/A/B/C/D/E");
   BOOST_REQUIRE(found1 != nullptr);
   BOOST_CHECK_EQUAL(found1->getName(), "/A/B/C/D");
 
-  shared_ptr<measurements::Entry> found2 = measurements.findLongestPrefixMatch("/A/B/C/D/E",
-      measurements::EntryWithStrategyInfo<DummyStrategyInfo1>());
+  Entry* found2 = measurements.findLongestPrefixMatch("/A/B/C/D/E",
+      EntryWithStrategyInfo<DummyStrategyInfo1>());
   BOOST_REQUIRE(found2 != nullptr);
   BOOST_CHECK_EQUAL(found2->getName(), "/A/B/C");
 
-  shared_ptr<measurements::Entry> found3 = measurements.findLongestPrefixMatch("/A/B/C/D/E",
-      measurements::EntryWithStrategyInfo<DummyStrategyInfo2>());
+  Entry* found3 = measurements.findLongestPrefixMatch("/A/B/C/D/E",
+      EntryWithStrategyInfo<DummyStrategyInfo2>());
   BOOST_CHECK(found3 == nullptr);
 }
 
@@ -158,23 +156,23 @@
   Pit pit(nameTree);
 
   measurements.get("/A");
-  measurements.get("/A/B/C")->getOrCreateStrategyInfo<DummyStrategyInfo1>();
+  measurements.get("/A/B/C").getOrCreateStrategyInfo<DummyStrategyInfo1>();
   measurements.get("/A/B/C/D");
 
   shared_ptr<Interest> interest = makeInterest("/A/B/C/D/E");
   shared_ptr<pit::Entry> pitEntry = pit.insert(*interest).first;
 
-  shared_ptr<measurements::Entry> found1 = measurements.findLongestPrefixMatch(*pitEntry);
+  Entry* found1 = measurements.findLongestPrefixMatch(*pitEntry);
   BOOST_REQUIRE(found1 != nullptr);
   BOOST_CHECK_EQUAL(found1->getName(), "/A/B/C/D");
 
-  shared_ptr<measurements::Entry> found2 = measurements.findLongestPrefixMatch(*pitEntry,
-      measurements::EntryWithStrategyInfo<DummyStrategyInfo1>());
+  Entry* found2 = measurements.findLongestPrefixMatch(*pitEntry,
+      EntryWithStrategyInfo<DummyStrategyInfo1>());
   BOOST_REQUIRE(found2 != nullptr);
   BOOST_CHECK_EQUAL(found2->getName(), "/A/B/C");
 
-  shared_ptr<measurements::Entry> found3 = measurements.findLongestPrefixMatch(*pitEntry,
-      measurements::EntryWithStrategyInfo<DummyStrategyInfo2>());
+  Entry* found3 = measurements.findLongestPrefixMatch(*pitEntry,
+      EntryWithStrategyInfo<DummyStrategyInfo2>());
   BOOST_CHECK(found3 == nullptr);
 }
 
@@ -186,9 +184,9 @@
 
   BOOST_CHECK_EQUAL(measurements.size(), 0);
 
-  shared_ptr<measurements::Entry> entryA = measurements.get(nameA);
-  shared_ptr<measurements::Entry> entryB = measurements.get(nameB);
-  shared_ptr<measurements::Entry> entryC = measurements.get(nameC);
+  Entry& entryA = measurements.get(nameA);
+  measurements.get(nameB);
+  Entry& entryC = measurements.get(nameC);
   BOOST_CHECK_EQUAL(measurements.size(), 3);
 
   const time::nanoseconds EXTEND_A = time::seconds(2);
@@ -202,15 +200,12 @@
   BOOST_ASSERT(CHECK2 < EXTEND_C);
   BOOST_ASSERT(EXTEND_C < CHECK3);
 
-  measurements.extendLifetime(*entryA, EXTEND_A);
-  measurements.extendLifetime(*entryC, EXTEND_C);
+  measurements.extendLifetime(entryA, EXTEND_A);
+  measurements.extendLifetime(entryC, EXTEND_C);
   // remaining lifetime:
   //   A = initial lifetime, because it's extended by less duration
   //   B = initial lifetime
   //   C = EXTEND_C
-  entryA.reset();
-  entryB.reset();
-  entryC.reset();
 
   this->advanceClocks(time::milliseconds(100), CHECK1);
   BOOST_CHECK(measurements.findExactMatch(nameA) != nullptr);
@@ -235,7 +230,9 @@
 {
   size_t nNameTreeEntriesBefore = nameTree.size();
 
-  shared_ptr<measurements::Entry> entry = measurements.get("/A");
+  measurements.get("/A");
+  BOOST_CHECK_EQUAL(measurements.size(), 1);
+
   this->advanceClocks(Measurements::getInitialLifetime() + time::milliseconds(10));
   BOOST_CHECK_EQUAL(measurements.size(), 0);
   BOOST_CHECK_EQUAL(nameTree.size(), nNameTreeEntriesBefore);
@@ -245,4 +242,5 @@
 BOOST_AUTO_TEST_SUITE_END() // Table
 
 } // namespace tests
+} // namespace measurements
 } // namespace nfd
diff --git a/tests/daemon/table/strategy-choice.t.cpp b/tests/daemon/table/strategy-choice.t.cpp
index 5897981..42a36b0 100644
--- a/tests/daemon/table/strategy-choice.t.cpp
+++ b/tests/daemon/table/strategy-choice.t.cpp
@@ -157,11 +157,11 @@
   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");
+  measurements::Entry& mAB = measurements.get("/A/B");
+  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);
+  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>))
@@ -222,31 +222,31 @@
 
   BOOST_CHECK(table.insert("ndn:/", nameP));
   // { '/'=>P }
-  measurements.get("ndn:/")     ->getOrCreateStrategyInfo<PStrategyInfo>();
-  measurements.get("ndn:/A")    ->getOrCreateStrategyInfo<PStrategyInfo>();
-  measurements.get("ndn:/A/B")  ->getOrCreateStrategyInfo<PStrategyInfo>();
-  measurements.get("ndn:/A/C")  ->getOrCreateStrategyInfo<PStrategyInfo>();
+  measurements.get("ndn:/").getOrCreateStrategyInfo<PStrategyInfo>();
+  measurements.get("ndn:/A").getOrCreateStrategyInfo<PStrategyInfo>();
+  measurements.get("ndn:/A/B").getOrCreateStrategyInfo<PStrategyInfo>();
+  measurements.get("ndn:/A/C").getOrCreateStrategyInfo<PStrategyInfo>();
 
   BOOST_CHECK(table.insert("ndn:/A/B", nameP));
   // { '/'=>P, '/A/B'=>P }
-  BOOST_CHECK(measurements.get("ndn:/")   ->getStrategyInfo<PStrategyInfo>() != nullptr);
-  BOOST_CHECK(measurements.get("ndn:/A")  ->getStrategyInfo<PStrategyInfo>() != nullptr);
-  BOOST_CHECK(measurements.get("ndn:/A/B")->getStrategyInfo<PStrategyInfo>() != nullptr);
-  BOOST_CHECK(measurements.get("ndn:/A/C")->getStrategyInfo<PStrategyInfo>() != nullptr);
+  BOOST_CHECK(measurements.get("ndn:/").getStrategyInfo<PStrategyInfo>() != nullptr);
+  BOOST_CHECK(measurements.get("ndn:/A").getStrategyInfo<PStrategyInfo>() != nullptr);
+  BOOST_CHECK(measurements.get("ndn:/A/B").getStrategyInfo<PStrategyInfo>() != nullptr);
+  BOOST_CHECK(measurements.get("ndn:/A/C").getStrategyInfo<PStrategyInfo>() != nullptr);
 
   BOOST_CHECK(table.insert("ndn:/A", nameQ));
   // { '/'=>P, '/A/B'=>P, '/A'=>Q }
-  BOOST_CHECK(measurements.get("ndn:/")   ->getStrategyInfo<PStrategyInfo>() != nullptr);
-  BOOST_CHECK(measurements.get("ndn:/A")  ->getStrategyInfo<PStrategyInfo>() == nullptr);
-  BOOST_CHECK(measurements.get("ndn:/A/B")->getStrategyInfo<PStrategyInfo>() != nullptr);
-  BOOST_CHECK(measurements.get("ndn:/A/C")->getStrategyInfo<PStrategyInfo>() == nullptr);
+  BOOST_CHECK(measurements.get("ndn:/").getStrategyInfo<PStrategyInfo>() != nullptr);
+  BOOST_CHECK(measurements.get("ndn:/A").getStrategyInfo<PStrategyInfo>() == nullptr);
+  BOOST_CHECK(measurements.get("ndn:/A/B").getStrategyInfo<PStrategyInfo>() != nullptr);
+  BOOST_CHECK(measurements.get("ndn:/A/C").getStrategyInfo<PStrategyInfo>() == nullptr);
 
   table.erase("ndn:/A/B");
   // { '/'=>P, '/A'=>Q }
-  BOOST_CHECK(measurements.get("ndn:/")   ->getStrategyInfo<PStrategyInfo>() != nullptr);
-  BOOST_CHECK(measurements.get("ndn:/A")  ->getStrategyInfo<PStrategyInfo>() == nullptr);
-  BOOST_CHECK(measurements.get("ndn:/A/B")->getStrategyInfo<PStrategyInfo>() == nullptr);
-  BOOST_CHECK(measurements.get("ndn:/A/C")->getStrategyInfo<PStrategyInfo>() == nullptr);
+  BOOST_CHECK(measurements.get("ndn:/").getStrategyInfo<PStrategyInfo>() != nullptr);
+  BOOST_CHECK(measurements.get("ndn:/A").getStrategyInfo<PStrategyInfo>() == nullptr);
+  BOOST_CHECK(measurements.get("ndn:/A/B").getStrategyInfo<PStrategyInfo>() == nullptr);
+  BOOST_CHECK(measurements.get("ndn:/A/C").getStrategyInfo<PStrategyInfo>() == nullptr);
 }
 
 BOOST_AUTO_TEST_CASE(EraseNameTreeEntry)