table: add Cs::erase method
This commit also corrects CS's description in Doxygen. refs #4318 Change-Id: Ie8854a2e2b59a072b98603c0cc31768bb84ea6d2
This commit is contained in:
1 parent
c14a8acf39
commit
30c37ab9bf
4 files changed
+109
-42
No files matched your search
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/**
|
||||
* Copyright (c) 2014-2016, Regents of the University of California,
|
||||
/*
|
||||
* Copyright (c) 2014-2018, Regents of the University of California,
|
||||
* Arizona Board of Regents,
|
||||
* Colorado State University,
|
||||
* University Pierre & Marie Curie, Sorbonne University,
|
||||
@@ -23,8 +23,8 @@
|
||||
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NFD_DAEMON_TABLE_CS_POLICY_FIFO_HPP
|
||||
#define NFD_DAEMON_TABLE_CS_POLICY_FIFO_HPP
|
||||
#ifndef NFD_DAEMON_TABLE_CS_POLICY_PRIORITY_FIFO_HPP
|
||||
#define NFD_DAEMON_TABLE_CS_POLICY_PRIORITY_FIFO_HPP
|
||||
|
||||
#include "cs-policy.hpp"
|
||||
#include "core/scheduler.hpp"
|
||||
@@ -61,13 +61,17 @@ struct EntryItComparator
|
||||
|
||||
typedef std::map<iterator, EntryInfo*, EntryItComparator> EntryInfoMapFifo;
|
||||
|
||||
/** \brief Priority Fifo cs replacement policy
|
||||
/** \brief Priority FIFO replacement policy
|
||||
*
|
||||
* The entries that get removed first are unsolicited Data packets,
|
||||
* which are the Data packets that got cached opportunistically without preceding
|
||||
* forwarding of the corresponding Interest packet.
|
||||
* Next, the Data packets with expired freshness are removed.
|
||||
* Last, the Data packets are removed from the Content Store on a pure FIFO basis.
|
||||
* This policy maintains a set of cleanup queues to decide the eviction order of CS entries.
|
||||
* The cleanup queues are three doubly linked lists that store Table iterators.
|
||||
* The three queues keep track of unsolicited, stale, and fresh Data packet, respectively.
|
||||
* Table iterator is placed into, removed from, and moved between suitable queues
|
||||
* whenever an Entry is added, removed, or has other attribute changes.
|
||||
* The Table iterator of an Entry should be in exactly one queue at any moment.
|
||||
* Within each queue, the iterators are kept in first-in-first-out order.
|
||||
* Eviction procedure exhausts the first queue before moving onto the next queue,
|
||||
* in the order of unsolicited, stale, and fresh queue.
|
||||
*/
|
||||
class PriorityFifoPolicy : public Policy
|
||||
{
|
||||
@@ -81,19 +85,19 @@ public:
|
||||
static const std::string POLICY_NAME;
|
||||
|
||||
private:
|
||||
virtual void
|
||||
void
|
||||
doAfterInsert(iterator i) override;
|
||||
|
||||
virtual void
|
||||
void
|
||||
doAfterRefresh(iterator i) override;
|
||||
|
||||
virtual void
|
||||
void
|
||||
doBeforeErase(iterator i) override;
|
||||
|
||||
virtual void
|
||||
void
|
||||
doBeforeUse(iterator i) override;
|
||||
|
||||
virtual void
|
||||
void
|
||||
evictEntries() override;
|
||||
|
||||
private:
|
||||
@@ -132,4 +136,4 @@ using priority_fifo::PriorityFifoPolicy;
|
||||
} // namespace cs
|
||||
} // namespace nfd
|
||||
|
||||
#endif // NFD_DAEMON_TABLE_CS_POLICY_FIFO_HPP
|
||||
#endif // NFD_DAEMON_TABLE_CS_POLICY_PRIORITY_FIFO_HPP
|
||||
@@ -88,6 +88,29 @@ Cs::insert(const Data& data, bool isUnsolicited)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Cs::erase(const Name& prefix, size_t limit, const AfterEraseCallback& cb)
|
||||
{
|
||||
BOOST_ASSERT(static_cast<bool>(cb));
|
||||
|
||||
iterator first = m_table.lower_bound(prefix);
|
||||
iterator last = m_table.end();
|
||||
if (prefix.size() > 0) {
|
||||
last = m_table.lower_bound(prefix.getSuccessor());
|
||||
}
|
||||
|
||||
size_t nErased = 0;
|
||||
while (first != last && nErased < limit) {
|
||||
m_policy->beforeErase(first);
|
||||
first = m_table.erase(first);
|
||||
++nErased;
|
||||
}
|
||||
|
||||
if (cb) {
|
||||
cb(nErased);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Cs::find(const Interest& interest,
|
||||
const HitCallback& hitCallback,
|
||||
|
||||
+22
-25
@@ -23,28 +23,6 @@
|
||||
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* \brief implements the ContentStore
|
||||
*
|
||||
* This ContentStore implementation consists of two data structures,
|
||||
* a Table, and a set of cleanup queues.
|
||||
*
|
||||
* The Table is a container (std::set) sorted by full Names of stored Data packets.
|
||||
* Data packets are wrapped in Entry objects.
|
||||
* Each Entry contain the Data packet itself,
|
||||
* and a few addition attributes such as the staleness of the Data packet.
|
||||
*
|
||||
* The cleanup queues are three doubly linked lists which stores Table iterators.
|
||||
* The three queues keep track of unsolicited, stale, and fresh Data packet, respectively.
|
||||
* Table iterator is placed into, removed from, and moved between suitable queues
|
||||
* whenever an Entry is added, removed, or has other attribute changes.
|
||||
* The Table iterator of an Entry should be in exactly one queue at any moment.
|
||||
* Within each queue, the iterators are kept in first-in-first-out order.
|
||||
* Eviction procedure exhausts the first queue before moving onto the next queue,
|
||||
* in the order of unsolicited, stale, and fresh queue.
|
||||
*/
|
||||
|
||||
#ifndef NFD_DAEMON_TABLE_CS_HPP
|
||||
#define NFD_DAEMON_TABLE_CS_HPP
|
||||
|
||||
@@ -57,7 +35,15 @@
|
||||
namespace nfd {
|
||||
namespace cs {
|
||||
|
||||
/** \brief represents the ContentStore
|
||||
/** \brief implements the Content Store
|
||||
*
|
||||
* This Content Store implementation consists of a Table and a replacement policy.
|
||||
*
|
||||
* The Table is a container ( \c std::set ) sorted by full Names of stored Data packets.
|
||||
* Data packets are wrapped in Entry objects. Each Entry contains the Data packet itself,
|
||||
* and a few additional attributes such as when the Data becomes non-fresh.
|
||||
*
|
||||
* The replacement policy is implemented in a subclass of \c Policy.
|
||||
*/
|
||||
class Cs : noncopyable
|
||||
{
|
||||
@@ -70,8 +56,19 @@ public:
|
||||
void
|
||||
insert(const Data& data, bool isUnsolicited = false);
|
||||
|
||||
typedef std::function<void(const Interest&, const Data& data)> HitCallback;
|
||||
typedef std::function<void(const Interest&)> MissCallback;
|
||||
using AfterEraseCallback = std::function<void(size_t nErased)>;
|
||||
|
||||
/** \brief asynchronously erases entries under \p prefix
|
||||
* \param prefix name prefix of entries
|
||||
* \param limit max number of entries to erase
|
||||
* \param cb callback to receive the actual number of erased entries; it may be empty;
|
||||
* it may be invoked either before or after erase() returns
|
||||
*/
|
||||
void
|
||||
erase(const Name& prefix, size_t limit, const AfterEraseCallback& cb);
|
||||
|
||||
using HitCallback = std::function<void(const Interest&, const Data&)>;
|
||||
using MissCallback = std::function<void(const Interest&)>;
|
||||
|
||||
/** \brief finds the best matching Data packet
|
||||
* \param interest the Interest for lookup
|
||||
|
||||
@@ -85,10 +85,21 @@ protected:
|
||||
check(0);
|
||||
}));
|
||||
|
||||
// current Cs::find implementation performs lookup synchronously
|
||||
// current Cs::find implementation is synchronous
|
||||
BOOST_CHECK(hasResult);
|
||||
}
|
||||
|
||||
size_t
|
||||
erase(const Name& prefix, size_t limit)
|
||||
{
|
||||
ndn::optional<size_t> nErased;
|
||||
m_cs.erase(prefix, limit, [&] (size_t nErased1) { nErased = nErased1; });
|
||||
|
||||
// current Cs::erase implementation is synchronous
|
||||
// if callback was not invoked, bad_optional_access would occur
|
||||
return *nErased;
|
||||
}
|
||||
|
||||
protected:
|
||||
Cs m_cs;
|
||||
shared_ptr<Interest> m_interest;
|
||||
@@ -364,6 +375,38 @@ BOOST_AUTO_TEST_CASE(DigestExclude)
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END() // Find
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(Erase, FindFixture)
|
||||
{
|
||||
insert(1, "/A/B/1");
|
||||
insert(2, "/A/B/2");
|
||||
insert(3, "/A/C/3");
|
||||
insert(4, "/A/C/4");
|
||||
insert(5, "/D/5");
|
||||
insert(6, "/E/6");
|
||||
BOOST_CHECK_EQUAL(m_cs.size(), 6);
|
||||
|
||||
BOOST_CHECK_EQUAL(erase("/A", 3), 3);
|
||||
BOOST_CHECK_EQUAL(m_cs.size(), 3);
|
||||
int nDataUnderA = 0;
|
||||
startInterest("/A/B/1");
|
||||
find([&] (uint32_t found) { nDataUnderA += static_cast<int>(found > 0); });
|
||||
startInterest("/A/B/2");
|
||||
find([&] (uint32_t found) { nDataUnderA += static_cast<int>(found > 0); });
|
||||
startInterest("/A/C/3");
|
||||
find([&] (uint32_t found) { nDataUnderA += static_cast<int>(found > 0); });
|
||||
startInterest("/A/C/4");
|
||||
find([&] (uint32_t found) { nDataUnderA += static_cast<int>(found > 0); });
|
||||
BOOST_CHECK_EQUAL(nDataUnderA, 1);
|
||||
|
||||
BOOST_CHECK_EQUAL(erase("/D", 2), 1);
|
||||
BOOST_CHECK_EQUAL(m_cs.size(), 2);
|
||||
startInterest("/D/5");
|
||||
CHECK_CS_FIND(0);
|
||||
|
||||
BOOST_CHECK_EQUAL(erase("/F", 2), 0);
|
||||
BOOST_CHECK_EQUAL(m_cs.size(), 2);
|
||||
}
|
||||
|
||||
// When the capacity limit is set to zero, Data cannot be inserted;
|
||||
// this test case covers this situation.
|
||||
// The behavior of non-zero capacity limit depends on the eviction policy,
|
||||
|
||||
Reference in new issue
Block a user