fw: FaceTable::get returns Face* instead of shared_ptr

refs #3205

Change-Id: I1c61493382fe065389266ff3519ab2b265fe4f79
diff --git a/daemon/fw/access-strategy.cpp b/daemon/fw/access-strategy.cpp
index 204aaaa..90feaff 100644
--- a/daemon/fw/access-strategy.cpp
+++ b/daemon/fw/access-strategy.cpp
@@ -125,7 +125,7 @@
     return false;
   }
 
-  shared_ptr<Face> face = this->getFace(mi.lastNexthop);
+  Face* face = this->getFace(mi.lastNexthop);
   if (face == nullptr || !fibEntry.hasNextHop(*face)) {
     NFD_LOG_DEBUG(pitEntry->getInterest() << " last-nexthop-gone");
     return false;
diff --git a/daemon/fw/client-control-strategy.cpp b/daemon/fw/client-control-strategy.cpp
index a73291b..0779cc1 100644
--- a/daemon/fw/client-control-strategy.cpp
+++ b/daemon/fw/client-control-strategy.cpp
@@ -56,7 +56,7 @@
   }
 
   FaceId outFaceId = static_cast<FaceId>(*tag);
-  shared_ptr<Face> outFace = this->getFace(outFaceId);
+  Face* outFace = this->getFace(outFaceId);
   if (outFace == nullptr) {
     // If outFace doesn't exist, it's better to reject the Interest
     // than to use BestRouteStrategy.
diff --git a/daemon/fw/face-table.cpp b/daemon/fw/face-table.cpp
index 4cda948..b2f1332 100644
--- a/daemon/fw/face-table.cpp
+++ b/daemon/fw/face-table.cpp
@@ -44,11 +44,14 @@
 
 }
 
-shared_ptr<Face>
+Face*
 FaceTable::get(FaceId id) const
 {
-  std::map<FaceId, shared_ptr<Face> >::const_iterator i = m_faces.find(id);
-  return (i == m_faces.end()) ? (shared_ptr<Face>()) : (i->second);
+  auto i = m_faces.find(id);
+  if (i == m_faces.end()) {
+    return nullptr;
+  }
+  return i->second.get();
 }
 
 size_t
diff --git a/daemon/fw/face-table.hpp b/daemon/fw/face-table.hpp
index a9186f6..19517b7 100644
--- a/daemon/fw/face-table.hpp
+++ b/daemon/fw/face-table.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,7 +33,7 @@
 
 class Forwarder;
 
-/** \brief container of all Faces
+/** \brief container of all faces
  */
 class FaceTable : noncopyable
 {
@@ -44,16 +44,28 @@
   VIRTUAL_WITH_TESTS
   ~FaceTable();
 
+  /** \brief add a face
+   *
+   *  FaceTable obtains shared ownership of the face.
+   *  The channel or protocol factory that creates the face may retain ownership.
+   */
   VIRTUAL_WITH_TESTS void
   add(shared_ptr<Face> face);
 
-  /// add a special Face with a reserved FaceId
+  /** \brief add a special Face with a reserved FaceId
+   */
   VIRTUAL_WITH_TESTS void
   addReserved(shared_ptr<Face> face, FaceId faceId);
 
-  VIRTUAL_WITH_TESTS shared_ptr<Face>
+  /** \brief get face by FaceId
+   *  \return a face if found, nullptr if not found;
+   *          face->shared_from_this() can be used if shared_ptr<Face> is desired
+   */
+  VIRTUAL_WITH_TESTS Face*
   get(FaceId id) const;
 
+  /** \return count of faces
+   */
   size_t
   size() const;
 
diff --git a/daemon/fw/forwarder.hpp b/daemon/fw/forwarder.hpp
index bf95d98..3c80419 100644
--- a/daemon/fw/forwarder.hpp
+++ b/daemon/fw/forwarder.hpp
@@ -67,7 +67,7 @@
    *
    *  shortcut to .getFaceTable().get(face)
    */
-  shared_ptr<Face>
+  Face*
   getFace(FaceId id) const;
 
   /** \brief add new Face
@@ -260,7 +260,7 @@
   return m_faceTable;
 }
 
-inline shared_ptr<Face>
+inline Face*
 Forwarder::getFace(FaceId id) const
 {
   return m_faceTable.get(id);
diff --git a/daemon/fw/strategy.hpp b/daemon/fw/strategy.hpp
index 386dd7f..bc8c348 100644
--- a/daemon/fw/strategy.hpp
+++ b/daemon/fw/strategy.hpp
@@ -171,11 +171,11 @@
   MeasurementsAccessor&
   getMeasurements();
 
-  shared_ptr<Face>
-  getFace(FaceId id);
+  Face*
+  getFace(FaceId id) const;
 
   const FaceTable&
-  getFaceTable();
+  getFaceTable() const;
 
 protected: // accessors
   signal::Signal<FaceTable, shared_ptr<Face>>& afterAddFace;
@@ -230,14 +230,14 @@
   return m_measurements;
 }
 
-inline shared_ptr<Face>
-Strategy::getFace(FaceId id)
+inline Face*
+Strategy::getFace(FaceId id) const
 {
   return m_forwarder.getFace(id);
 }
 
 inline const FaceTable&
-Strategy::getFaceTable()
+Strategy::getFaceTable() const
 {
   return m_forwarder.getFaceTable();
 }
diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp
index b8506ac..ac9085c 100644
--- a/daemon/mgmt/face-manager.cpp
+++ b/daemon/mgmt/face-manager.cpp
@@ -150,9 +150,9 @@
                          const ControlParameters& parameters,
                          const ndn::mgmt::CommandContinuation& done)
 {
-  shared_ptr<Face> target = m_faceTable.get(parameters.getFaceId());
-  if (target) {
-    target->close();
+  Face* face = m_faceTable.get(parameters.getFaceId());
+  if (face != nullptr) {
+    face->close();
   }
 
   done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
@@ -228,7 +228,7 @@
   // and is initialized synchronously with IncomingFaceId field enabled.
   BOOST_ASSERT(incomingFaceIdTag != nullptr);
 
-  auto face = m_faceTable.get(*incomingFaceIdTag);
+  Face* face = m_faceTable.get(*incomingFaceIdTag);
   if (face == nullptr) {
     NFD_LOG_DEBUG("FaceId " << *incomingFaceIdTag << " not found");
     done(ControlResponse(410, "Face not found"));
@@ -241,7 +241,7 @@
     return nullptr;
   }
 
-  return face.get();
+  return face;
 }
 
 void
diff --git a/daemon/mgmt/fib-manager.cpp b/daemon/mgmt/fib-manager.cpp
index b7ac209..1c15ebf 100644
--- a/daemon/mgmt/fib-manager.cpp
+++ b/daemon/mgmt/fib-manager.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "fib-manager.hpp"
+#include "fw/face-table.hpp"
 #include <ndn-cxx/management/nfd-fib-entry.hpp>
 
 namespace nfd {
@@ -31,12 +32,12 @@
 NFD_LOG_INIT("FibManager");
 
 FibManager::FibManager(Fib& fib,
-                       function<shared_ptr<Face>(FaceId)> getFace,
+                       const FaceTable& faceTable,
                        Dispatcher& dispatcher,
                        CommandValidator& validator)
   : NfdManagerBase(dispatcher, validator, "fib")
   , m_fib(fib)
-  , m_getFace(getFace)
+  , m_faceTable(faceTable)
 {
   registerCommandHandler<ndn::nfd::FibAddNextHopCommand>("add-nexthop",
     bind(&FibManager::addNextHop, this, _2, _3, _4, _5));
@@ -61,7 +62,7 @@
                 << " faceid: " << faceId
                 << " cost: " << cost);
 
-  shared_ptr<Face> face = m_getFace(faceId);
+  Face* face = m_faceTable.get(faceId);
   if (face != nullptr) {
     fib::Entry* entry = m_fib.insert(prefix).first;
     entry->addNextHop(*face, cost);
@@ -89,7 +90,7 @@
   NFD_LOG_TRACE("remove-nexthop prefix: " << parameters.getName()
                 << " faceid: " << parameters.getFaceId());
 
-  shared_ptr<Face> face = m_getFace(parameters.getFaceId());
+  Face* face = m_faceTable.get(parameters.getFaceId());
   if (face != nullptr) {
     fib::Entry* entry = m_fib.findExactMatch(parameters.getName());
     if (entry != nullptr) {
diff --git a/daemon/mgmt/fib-manager.hpp b/daemon/mgmt/fib-manager.hpp
index 94300cb..9599a01 100644
--- a/daemon/mgmt/fib-manager.hpp
+++ b/daemon/mgmt/fib-manager.hpp
@@ -33,6 +33,8 @@
 
 namespace nfd {
 
+class FaceTable;
+
 /**
  * @brief implement the FIB Management of NFD Management Protocol.
  * @sa http://redmine.named-data.net/projects/nfd/wiki/FibMgmt
@@ -44,12 +46,12 @@
    * @brief construct a FibManger
    *
    * @param fib the managed FIB
-   * @param getFace a function used to retrive a face by FaceId from the face table
+   * @param faceTable FaceTable for querying available faces
    * @param dispatcher the management dispatcher
    * @param validator the command validator
    */
   FibManager(Fib& fib,
-             function<shared_ptr<Face>(FaceId)> getFace,
+             const FaceTable& faceTable,
              Dispatcher& dispatcher,
              CommandValidator& validator);
 
@@ -74,7 +76,7 @@
 
 private:
   Fib& m_fib;
-  function<shared_ptr<Face>(FaceId)> m_getFace;
+  const FaceTable& m_faceTable;
 };
 
 } // namespace nfd
diff --git a/daemon/nfd.cpp b/daemon/nfd.cpp
index 65fa80a..35fc941 100644
--- a/daemon/nfd.cpp
+++ b/daemon/nfd.cpp
@@ -151,7 +151,7 @@
   m_validator.reset(new CommandValidator());
 
   m_fibManager.reset(new FibManager(m_forwarder->getFib(),
-                                    bind(&Forwarder::getFace, m_forwarder.get(), _1),
+                                    m_forwarder->getFaceTable(),
                                     *m_dispatcher,
                                     *m_validator));
 
diff --git a/tests/daemon/fw/face-table.t.cpp b/tests/daemon/fw/face-table.t.cpp
index 59bb7c8..4616efb 100644
--- a/tests/daemon/fw/face-table.t.cpp
+++ b/tests/daemon/fw/face-table.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,
@@ -38,8 +38,8 @@
 BOOST_AUTO_TEST_CASE(AddRemove)
 {
   Forwarder forwarder;
-
   FaceTable& faceTable = forwarder.getFaceTable();
+
   std::vector<FaceId> addHistory;
   std::vector<FaceId> removeHistory;
   faceTable.afterAdd.connect([&] (shared_ptr<Face> face) { addHistory.push_back(face->getId()); });
@@ -50,15 +50,20 @@
 
   BOOST_CHECK_EQUAL(face1->getId(), face::INVALID_FACEID);
   BOOST_CHECK_EQUAL(face2->getId(), face::INVALID_FACEID);
+  BOOST_CHECK(faceTable.get(face::INVALID_FACEID) == nullptr);
+  BOOST_CHECK_EQUAL(faceTable.size(), 0);
 
-  forwarder.addFace(face1);
-  forwarder.addFace(face2);
+  faceTable.add(face1);
+  faceTable.add(face2);
+  BOOST_CHECK_EQUAL(faceTable.size(), 2);
 
   BOOST_CHECK_NE(face1->getId(), face::INVALID_FACEID);
   BOOST_CHECK_NE(face2->getId(), face::INVALID_FACEID);
   BOOST_CHECK_NE(face1->getId(), face2->getId());
   BOOST_CHECK_GT(face1->getId(), face::FACEID_RESERVED_MAX);
   BOOST_CHECK_GT(face2->getId(), face::FACEID_RESERVED_MAX);
+  BOOST_CHECK(faceTable.get(face1->getId()) == face1.get());
+  BOOST_CHECK(faceTable.get(face2->getId()) == face2.get());
 
   FaceId oldId1 = face1->getId();
   faceTable.add(face1);
@@ -72,6 +77,8 @@
   face1->close();
 
   BOOST_CHECK_EQUAL(face1->getId(), face::INVALID_FACEID);
+  BOOST_CHECK_EQUAL(faceTable.size(), 1);
+  BOOST_CHECK(faceTable.get(oldId1) == nullptr);
 
   BOOST_REQUIRE_EQUAL(removeHistory.size(), 1);
   BOOST_CHECK_EQUAL(removeHistory[0], addHistory[0]);
diff --git a/tests/daemon/mgmt/fib-manager.t.cpp b/tests/daemon/mgmt/fib-manager.t.cpp
index 9e5f285..3e5ee0e 100644
--- a/tests/daemon/mgmt/fib-manager.t.cpp
+++ b/tests/daemon/mgmt/fib-manager.t.cpp
@@ -38,7 +38,7 @@
   FibManagerFixture()
     : m_fib(m_forwarder.getFib())
     , m_faceTable(m_forwarder.getFaceTable())
-    , m_manager(m_fib, bind(&Forwarder::getFace, &m_forwarder, _1), m_dispatcher, m_validator)
+    , m_manager(m_fib, m_faceTable, m_dispatcher, m_validator)
   {
     setPrivilege("fib");
   }