table: mock Measurements table
refs #1259, #1197
Change-Id: Ie7cd2ff6fbbb413a77539eb9f1c5354405252cec
diff --git a/daemon/table/measurements-entry.cpp b/daemon/table/measurements-entry.cpp
new file mode 100644
index 0000000..11e4fab
--- /dev/null
+++ b/daemon/table/measurements-entry.cpp
@@ -0,0 +1,19 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "measurements-entry.hpp"
+
+namespace nfd {
+namespace measurements {
+
+Entry::Entry(const Name& name)
+ : m_name(name)
+ , m_expiry(0)
+{
+}
+
+} // namespace measurements
+} // namespace nfd
diff --git a/daemon/table/measurements-entry.hpp b/daemon/table/measurements-entry.hpp
new file mode 100644
index 0000000..c7145d7
--- /dev/null
+++ b/daemon/table/measurements-entry.hpp
@@ -0,0 +1,51 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NFD_TABLE_MEASUREMENTS_ENTRY_HPP
+#define NFD_TABLE_MEASUREMENTS_ENTRY_HPP
+
+#include "common.hpp"
+#include "strategy-info-host.hpp"
+#include "core/scheduler.hpp"
+
+namespace nfd {
+
+class Measurements;
+
+namespace measurements {
+
+/** \class Entry
+ * \brief represents a Measurements entry
+ */
+class Entry : public StrategyInfoHost, noncopyable
+{
+public:
+ explicit
+ Entry(const Name& name);
+
+ const Name&
+ getName() const;
+
+private:
+ Name m_name;
+
+private: // lifetime
+ time::Point m_expiry;
+ EventId m_cleanup;
+
+ friend class ::nfd::Measurements;
+};
+
+inline const Name&
+Entry::getName() const
+{
+ return m_name;
+}
+
+} // namespace measurements
+} // namespace nfd
+
+#endif // NFD_TABLE_MEASUREMENTS_ENTRY_HPP
diff --git a/daemon/table/measurements.cpp b/daemon/table/measurements.cpp
new file mode 100644
index 0000000..bc5a9d2
--- /dev/null
+++ b/daemon/table/measurements.cpp
@@ -0,0 +1,107 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "measurements.hpp"
+#include <algorithm>
+#include "fib-entry.hpp"
+#include "pit-entry.hpp"
+
+namespace nfd {
+
+const time::Duration Measurements::s_defaultLifetime = time::seconds(4);
+
+Measurements::Measurements(boost::asio::io_service& ioService)
+ : m_scheduler(ioService)
+{
+}
+
+Measurements::~Measurements()
+{
+}
+
+shared_ptr<measurements::Entry>
+Measurements::get(const Name& name)
+{
+ std::map<Name, shared_ptr<measurements::Entry> >::iterator it = m_table.find(name);
+ if (it != m_table.end()) {
+ return it->second;
+ }
+
+ shared_ptr<measurements::Entry> entry = make_shared<measurements::Entry>(name);
+ std::pair<std::map<Name, shared_ptr<measurements::Entry> >::iterator, bool> pair =
+ m_table.insert(std::make_pair(name, entry));
+ this->extendLifetimeInternal(pair.first, s_defaultLifetime);
+
+ return entry;
+}
+
+shared_ptr<measurements::Entry>
+Measurements::get(const fib::Entry& fibEntry)
+{
+ return this->get(fibEntry.getPrefix());
+}
+
+shared_ptr<measurements::Entry>
+Measurements::get(const pit::Entry& pitEntry)
+{
+ return this->get(pitEntry.getName());
+}
+
+shared_ptr<measurements::Entry>
+Measurements::getParent(shared_ptr<measurements::Entry> child)
+{
+ if (child->getName().size() == 0) {
+ return shared_ptr<measurements::Entry>();
+ }
+
+ return this->get(child->getName().getPrefix(-1));
+}
+
+//shared_ptr<fib::Entry>
+//Measurements::findLongestPrefixMatch(const Name& name) const
+//{
+//}
+//
+//shared_ptr<fib::Entry>
+//Measurements::findExactMatch(const Name& name) const
+//{
+//}
+
+void
+Measurements::extendLifetime(measurements::Entry& entry, time::Duration lifetime)
+{
+ std::map<Name, shared_ptr<measurements::Entry> >::iterator it =
+ m_table.find(entry.getName());
+ BOOST_ASSERT(it != m_table.end());
+
+ this->extendLifetimeInternal(it, lifetime);
+}
+
+void
+Measurements::extendLifetimeInternal(
+ std::map<Name, shared_ptr<measurements::Entry> >::iterator it,
+ time::Duration lifetime)
+{
+ shared_ptr<measurements::Entry>& entry = it->second;
+
+ time::Point expiry = time::now() + lifetime;
+ if (entry->m_expiry >= expiry) { // has longer lifetime, not extending
+ return;
+ }
+
+ m_scheduler.cancelEvent(entry->m_cleanup);
+ entry->m_expiry = expiry;
+ entry->m_cleanup = m_scheduler.scheduleEvent(lifetime,
+ bind(&Measurements::cleanup, this, it));
+}
+
+void
+Measurements::cleanup(std::map<Name, shared_ptr<measurements::Entry> >::iterator it)
+{
+ m_table.erase(it);
+}
+
+} // namespace nfd
diff --git a/daemon/table/measurements.hpp b/daemon/table/measurements.hpp
new file mode 100644
index 0000000..2e3a88c
--- /dev/null
+++ b/daemon/table/measurements.hpp
@@ -0,0 +1,85 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NFD_TABLE_MEASUREMENTS_HPP
+#define NFD_TABLE_MEASUREMENTS_HPP
+
+#include "measurements-entry.hpp"
+#include "core/time.hpp"
+
+namespace nfd {
+
+namespace fib {
+class Entry;
+}
+namespace pit {
+class Entry;
+}
+
+/** \class Measurement
+ * \brief represents the Measurements table
+ */
+class Measurements : noncopyable
+{
+public:
+ explicit
+ Measurements(boost::asio::io_service& ioService);
+
+ ~Measurements();
+
+ /// find or insert a Measurements entry for name
+ shared_ptr<measurements::Entry>
+ get(const Name& name);
+
+ /// find or insert a Measurements entry for fibEntry->getPrefix()
+ shared_ptr<measurements::Entry>
+ get(const fib::Entry& fibEntry);
+
+ /// find or insert a Measurements entry for pitEntry->getName()
+ shared_ptr<measurements::Entry>
+ get(const pit::Entry& pitEntry);
+
+ /** \brief find or insert a Measurements entry for child's parent
+ *
+ * If child is the root entry, returns null.
+ */
+ shared_ptr<measurements::Entry>
+ getParent(shared_ptr<measurements::Entry> child);
+
+// /// perform a longest prefix match
+// shared_ptr<fib::Entry>
+// findLongestPrefixMatch(const Name& name) const;
+//
+// /// perform an exact match
+// shared_ptr<fib::Entry>
+// findExactMatch(const Name& name) const;
+
+ /** \brief extend lifetime of an entry
+ *
+ * The entry will be kept until at least now()+lifetime.
+ */
+ void
+ extendLifetime(measurements::Entry& entry, time::Duration lifetime);
+
+private:
+ void
+ extendLifetimeInternal(
+ std::map<Name, shared_ptr<measurements::Entry> >::iterator it,
+ time::Duration lifetime);
+
+ void
+ cleanup(std::map<Name, shared_ptr<measurements::Entry> >::iterator it);
+
+private:
+ std::map<Name, shared_ptr<measurements::Entry> > m_table;
+
+ Scheduler m_scheduler;
+ static const time::Duration s_defaultLifetime;
+};
+
+} // namespace nfd
+
+#endif // NFD_TABLE_MEASUREMENTS_HPP
diff --git a/tests/table/measurements.cpp b/tests/table/measurements.cpp
new file mode 100644
index 0000000..09874a0
--- /dev/null
+++ b/tests/table/measurements.cpp
@@ -0,0 +1,41 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "table/measurements.hpp"
+
+#include <boost/test/unit_test.hpp>
+
+namespace nfd {
+
+BOOST_AUTO_TEST_SUITE(TableMeasurements)
+
+BOOST_AUTO_TEST_CASE(Get_Parent)
+{
+ Name name0;
+ Name nameA ("ndn:/A");
+ Name nameAB("ndn:/A/B");
+
+ boost::asio::io_service ioService;
+ Measurements measurements(ioService);
+
+ shared_ptr<measurements::Entry> entryAB = measurements.get(nameAB);
+ BOOST_REQUIRE(static_cast<bool>(entryAB));
+ BOOST_CHECK_EQUAL(entryAB->getName(), nameAB);
+
+ shared_ptr<measurements::Entry> entry0 = measurements.get(name0);
+ BOOST_REQUIRE(static_cast<bool>(entry0));
+
+ shared_ptr<measurements::Entry> entryA = measurements.getParent(entryAB);
+ BOOST_REQUIRE(static_cast<bool>(entryA));
+ BOOST_CHECK_EQUAL(entryA->getName(), nameA);
+
+ shared_ptr<measurements::Entry> entry0c = measurements.getParent(entryA);
+ BOOST_CHECK_EQUAL(entry0, entry0c);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace nfd