cs-policy-priority-fifo.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2014-2022, Regents of the University of California,
4  * Arizona Board of Regents,
5  * Colorado State University,
6  * University Pierre & Marie Curie, Sorbonne University,
7  * Washington University in St. Louis,
8  * Beijing Institute of Technology,
9  * The University of Memphis.
10  *
11  * This file is part of NFD (Named Data Networking Forwarding Daemon).
12  * See AUTHORS.md for complete list of NFD authors and contributors.
13  *
14  * NFD is free software: you can redistribute it and/or modify it under the terms
15  * of the GNU General Public License as published by the Free Software Foundation,
16  * either version 3 of the License, or (at your option) any later version.
17  *
18  * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20  * PURPOSE. See the GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License along with
23  * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24  */
25 
27 #include "cs.hpp"
28 #include "common/global.hpp"
29 
31 
32 const std::string PriorityFifoPolicy::POLICY_NAME = "priority_fifo";
34 
36  : Policy(POLICY_NAME)
37 {
38 }
39 
41 {
42  for (auto entryInfoMapPair : m_entryInfoMap) {
43  delete entryInfoMapPair.second;
44  }
45 }
46 
47 void
48 PriorityFifoPolicy::doAfterInsert(EntryRef i)
49 {
50  this->attachQueue(i);
51  this->evictEntries();
52 }
53 
54 void
55 PriorityFifoPolicy::doAfterRefresh(EntryRef i)
56 {
57  this->detachQueue(i);
58  this->attachQueue(i);
59 }
60 
61 void
62 PriorityFifoPolicy::doBeforeErase(EntryRef i)
63 {
64  this->detachQueue(i);
65 }
66 
67 void
68 PriorityFifoPolicy::doBeforeUse(EntryRef i)
69 {
70  BOOST_ASSERT(m_entryInfoMap.find(i) != m_entryInfoMap.end());
71 }
72 
73 void
74 PriorityFifoPolicy::evictEntries()
75 {
76  BOOST_ASSERT(this->getCs() != nullptr);
77 
78  while (this->getCs()->size() > this->getLimit()) {
79  this->evictOne();
80  }
81 }
82 
83 void
84 PriorityFifoPolicy::evictOne()
85 {
86  BOOST_ASSERT(!m_queues[QUEUE_UNSOLICITED].empty() ||
87  !m_queues[QUEUE_STALE].empty() ||
88  !m_queues[QUEUE_FIFO].empty());
89 
90  EntryRef i;
91  if (!m_queues[QUEUE_UNSOLICITED].empty()) {
92  i = m_queues[QUEUE_UNSOLICITED].front();
93  }
94  else if (!m_queues[QUEUE_STALE].empty()) {
95  i = m_queues[QUEUE_STALE].front();
96  }
97  else if (!m_queues[QUEUE_FIFO].empty()) {
98  i = m_queues[QUEUE_FIFO].front();
99  }
100 
101  this->detachQueue(i);
102  this->emitSignal(beforeEvict, i);
103 }
104 
105 void
106 PriorityFifoPolicy::attachQueue(EntryRef i)
107 {
108  BOOST_ASSERT(m_entryInfoMap.find(i) == m_entryInfoMap.end());
109 
110  EntryInfo* entryInfo = new EntryInfo();
111  if (i->isUnsolicited()) {
112  entryInfo->queueType = QUEUE_UNSOLICITED;
113  }
114  else if (!i->isFresh()) {
115  entryInfo->queueType = QUEUE_STALE;
116  }
117  else {
118  entryInfo->queueType = QUEUE_FIFO;
119  entryInfo->moveStaleEventId = getScheduler().schedule(i->getData().getFreshnessPeriod(),
120  [=] { moveToStaleQueue(i); });
121  }
122 
123  Queue& queue = m_queues[entryInfo->queueType];
124  entryInfo->queueIt = queue.insert(queue.end(), i);
125  m_entryInfoMap[i] = entryInfo;
126 }
127 
128 void
129 PriorityFifoPolicy::detachQueue(EntryRef i)
130 {
131  BOOST_ASSERT(m_entryInfoMap.find(i) != m_entryInfoMap.end());
132 
133  EntryInfo* entryInfo = m_entryInfoMap[i];
134  if (entryInfo->queueType == QUEUE_FIFO) {
135  entryInfo->moveStaleEventId.cancel();
136  }
137 
138  m_queues[entryInfo->queueType].erase(entryInfo->queueIt);
139  m_entryInfoMap.erase(i);
140  delete entryInfo;
141 }
142 
143 void
144 PriorityFifoPolicy::moveToStaleQueue(EntryRef i)
145 {
146  BOOST_ASSERT(m_entryInfoMap.find(i) != m_entryInfoMap.end());
147 
148  EntryInfo* entryInfo = m_entryInfoMap[i];
149  BOOST_ASSERT(entryInfo->queueType == QUEUE_FIFO);
150 
151  m_queues[QUEUE_FIFO].erase(entryInfo->queueIt);
152 
153  entryInfo->queueType = QUEUE_STALE;
154  Queue& queue = m_queues[QUEUE_STALE];
155  entryInfo->queueIt = queue.insert(queue.end(), i);
156  m_entryInfoMap[i] = entryInfo;
157 }
158 
159 } // namespace nfd::cs::priority_fifo
Represents a CS replacement policy.
Definition: cs-policy.hpp:39
Cs * getCs() const noexcept
Returns a pointer to the associated CS instance.
Definition: cs-policy.hpp:77
Table::const_iterator EntryRef
A reference to a CS entry.
Definition: cs-policy.hpp:113
size_t getLimit() const noexcept
Gets hard limit (in number of entries).
Definition: cs-policy.hpp:95
signal::Signal< Policy, EntryRef > beforeEvict
Signal emitted when an entry is being evicted.
Definition: cs-policy.hpp:120
Priority First-In-First-Out (FIFO) replacement policy.
#define NFD_REGISTER_CS_POLICY(P)
Registers a CS policy.
Definition: cs-policy.hpp:218
std::list< Policy::EntryRef > Queue
Scheduler & getScheduler()
Returns the global Scheduler instance for the calling thread.
Definition: global.cpp:45