blob: f350c723b30d2d5053c03cd04bbb99672c37250b [file] [log] [blame]
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesaventoe4b22382018-06-10 14:37:24 -04002/*
Davide Pesavento3dade002019-03-19 11:29:56 -06003 * Copyright (c) 2014-2019, Regents of the University of California,
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -05004 * 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
26#include "cs-policy-priority-fifo.hpp"
27#include "cs.hpp"
Davide Pesavento3dade002019-03-19 11:29:56 -060028#include "daemon/global.hpp"
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050029
30namespace nfd {
31namespace cs {
32namespace priority_fifo {
33
Junxiao Shi52555b02016-11-25 21:39:06 +000034const std::string PriorityFifoPolicy::POLICY_NAME = "priority_fifo";
35NFD_REGISTER_CS_POLICY(PriorityFifoPolicy);
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050036
37PriorityFifoPolicy::PriorityFifoPolicy()
38 : Policy(POLICY_NAME)
39{
40}
41
Minsheng Zhang9c903e02015-10-03 18:16:05 -050042PriorityFifoPolicy::~PriorityFifoPolicy()
43{
44 for (auto entryInfoMapPair : m_entryInfoMap) {
45 delete entryInfoMapPair.second;
46 }
47}
48
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050049void
50PriorityFifoPolicy::doAfterInsert(iterator i)
51{
52 this->attachQueue(i);
53 this->evictEntries();
54}
55
56void
57PriorityFifoPolicy::doAfterRefresh(iterator i)
58{
59 this->detachQueue(i);
60 this->attachQueue(i);
61}
62
63void
64PriorityFifoPolicy::doBeforeErase(iterator i)
65{
66 this->detachQueue(i);
67}
68
69void
70PriorityFifoPolicy::doBeforeUse(iterator i)
71{
72 BOOST_ASSERT(m_entryInfoMap.find(i) != m_entryInfoMap.end());
73}
74
75void
76PriorityFifoPolicy::evictEntries()
77{
78 BOOST_ASSERT(this->getCs() != nullptr);
79
80 while (this->getCs()->size() > this->getLimit()) {
81 this->evictOne();
82 }
83}
84
85void
86PriorityFifoPolicy::evictOne()
87{
88 BOOST_ASSERT(!m_queues[QUEUE_UNSOLICITED].empty() ||
89 !m_queues[QUEUE_STALE].empty() ||
90 !m_queues[QUEUE_FIFO].empty());
91
92 iterator i;
93 if (!m_queues[QUEUE_UNSOLICITED].empty()) {
94 i = m_queues[QUEUE_UNSOLICITED].front();
95 }
96 else if (!m_queues[QUEUE_STALE].empty()) {
97 i = m_queues[QUEUE_STALE].front();
98 }
99 else if (!m_queues[QUEUE_FIFO].empty()) {
100 i = m_queues[QUEUE_FIFO].front();
101 }
102
103 this->detachQueue(i);
104 this->emitSignal(beforeEvict, i);
105}
106
107void
108PriorityFifoPolicy::attachQueue(iterator i)
109{
110 BOOST_ASSERT(m_entryInfoMap.find(i) == m_entryInfoMap.end());
111
112 EntryInfo* entryInfo = new EntryInfo();
113 if (i->isUnsolicited()) {
114 entryInfo->queueType = QUEUE_UNSOLICITED;
115 }
116 else if (i->isStale()) {
117 entryInfo->queueType = QUEUE_STALE;
118 }
119 else {
120 entryInfo->queueType = QUEUE_FIFO;
Davide Pesavento3dade002019-03-19 11:29:56 -0600121 entryInfo->moveStaleEventId = getScheduler().schedule(i->getData().getFreshnessPeriod(),
122 [=] { moveToStaleQueue(i); });
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500123 }
124
125 Queue& queue = m_queues[entryInfo->queueType];
126 entryInfo->queueIt = queue.insert(queue.end(), i);
127 m_entryInfoMap[i] = entryInfo;
128}
129
130void
131PriorityFifoPolicy::detachQueue(iterator i)
132{
133 BOOST_ASSERT(m_entryInfoMap.find(i) != m_entryInfoMap.end());
134
135 EntryInfo* entryInfo = m_entryInfoMap[i];
136 if (entryInfo->queueType == QUEUE_FIFO) {
Davide Pesavento3dade002019-03-19 11:29:56 -0600137 entryInfo->moveStaleEventId.cancel();
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500138 }
139
140 m_queues[entryInfo->queueType].erase(entryInfo->queueIt);
141 m_entryInfoMap.erase(i);
Minsheng Zhang9c903e02015-10-03 18:16:05 -0500142 delete entryInfo;
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500143}
144
145void
146PriorityFifoPolicy::moveToStaleQueue(iterator i)
147{
148 BOOST_ASSERT(m_entryInfoMap.find(i) != m_entryInfoMap.end());
149
150 EntryInfo* entryInfo = m_entryInfoMap[i];
151 BOOST_ASSERT(entryInfo->queueType == QUEUE_FIFO);
152
153 m_queues[QUEUE_FIFO].erase(entryInfo->queueIt);
154
155 entryInfo->queueType = QUEUE_STALE;
156 Queue& queue = m_queues[QUEUE_STALE];
157 entryInfo->queueIt = queue.insert(queue.end(), i);
158 m_entryInfoMap[i] = entryInfo;
159}
160
Junxiao Shi52555b02016-11-25 21:39:06 +0000161} // namespace priority_fifo
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500162} // namespace cs
163} // namespace nfd