blob: a61f33403389176166e5fe27a64fa6e736f0bd15 [file] [log] [blame]
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi52555b02016-11-25 21:39:06 +00003 * Copyright (c) 2014-2016, 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"
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050028
29namespace nfd {
30namespace cs {
31namespace priority_fifo {
32
Junxiao Shi52555b02016-11-25 21:39:06 +000033const std::string PriorityFifoPolicy::POLICY_NAME = "priority_fifo";
34NFD_REGISTER_CS_POLICY(PriorityFifoPolicy);
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050035
36PriorityFifoPolicy::PriorityFifoPolicy()
37 : Policy(POLICY_NAME)
38{
39}
40
Minsheng Zhang9c903e02015-10-03 18:16:05 -050041PriorityFifoPolicy::~PriorityFifoPolicy()
42{
43 for (auto entryInfoMapPair : m_entryInfoMap) {
44 delete entryInfoMapPair.second;
45 }
46}
47
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -050048void
49PriorityFifoPolicy::doAfterInsert(iterator i)
50{
51 this->attachQueue(i);
52 this->evictEntries();
53}
54
55void
56PriorityFifoPolicy::doAfterRefresh(iterator i)
57{
58 this->detachQueue(i);
59 this->attachQueue(i);
60}
61
62void
63PriorityFifoPolicy::doBeforeErase(iterator i)
64{
65 this->detachQueue(i);
66}
67
68void
69PriorityFifoPolicy::doBeforeUse(iterator i)
70{
71 BOOST_ASSERT(m_entryInfoMap.find(i) != m_entryInfoMap.end());
72}
73
74void
75PriorityFifoPolicy::evictEntries()
76{
77 BOOST_ASSERT(this->getCs() != nullptr);
78
79 while (this->getCs()->size() > this->getLimit()) {
80 this->evictOne();
81 }
82}
83
84void
85PriorityFifoPolicy::evictOne()
86{
87 BOOST_ASSERT(!m_queues[QUEUE_UNSOLICITED].empty() ||
88 !m_queues[QUEUE_STALE].empty() ||
89 !m_queues[QUEUE_FIFO].empty());
90
91 iterator i;
92 if (!m_queues[QUEUE_UNSOLICITED].empty()) {
93 i = m_queues[QUEUE_UNSOLICITED].front();
94 }
95 else if (!m_queues[QUEUE_STALE].empty()) {
96 i = m_queues[QUEUE_STALE].front();
97 }
98 else if (!m_queues[QUEUE_FIFO].empty()) {
99 i = m_queues[QUEUE_FIFO].front();
100 }
101
102 this->detachQueue(i);
103 this->emitSignal(beforeEvict, i);
104}
105
106void
107PriorityFifoPolicy::attachQueue(iterator i)
108{
109 BOOST_ASSERT(m_entryInfoMap.find(i) == m_entryInfoMap.end());
110
111 EntryInfo* entryInfo = new EntryInfo();
112 if (i->isUnsolicited()) {
113 entryInfo->queueType = QUEUE_UNSOLICITED;
114 }
115 else if (i->isStale()) {
116 entryInfo->queueType = QUEUE_STALE;
117 }
118 else {
119 entryInfo->queueType = QUEUE_FIFO;
120
121 if (i->canStale()) {
122 entryInfo->moveStaleEventId = scheduler::schedule(i->getData().getFreshnessPeriod(),
123 bind(&PriorityFifoPolicy::moveToStaleQueue, this, i));
124 }
125 }
126
127 Queue& queue = m_queues[entryInfo->queueType];
128 entryInfo->queueIt = queue.insert(queue.end(), i);
129 m_entryInfoMap[i] = entryInfo;
130}
131
132void
133PriorityFifoPolicy::detachQueue(iterator i)
134{
135 BOOST_ASSERT(m_entryInfoMap.find(i) != m_entryInfoMap.end());
136
137 EntryInfo* entryInfo = m_entryInfoMap[i];
138 if (entryInfo->queueType == QUEUE_FIFO) {
139 scheduler::cancel(entryInfo->moveStaleEventId);
140 }
141
142 m_queues[entryInfo->queueType].erase(entryInfo->queueIt);
143 m_entryInfoMap.erase(i);
Minsheng Zhang9c903e02015-10-03 18:16:05 -0500144 delete entryInfo;
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500145}
146
147void
148PriorityFifoPolicy::moveToStaleQueue(iterator i)
149{
150 BOOST_ASSERT(m_entryInfoMap.find(i) != m_entryInfoMap.end());
151
152 EntryInfo* entryInfo = m_entryInfoMap[i];
153 BOOST_ASSERT(entryInfo->queueType == QUEUE_FIFO);
154
155 m_queues[QUEUE_FIFO].erase(entryInfo->queueIt);
156
157 entryInfo->queueType = QUEUE_STALE;
158 Queue& queue = m_queues[QUEUE_STALE];
159 entryInfo->queueIt = queue.insert(queue.end(), i);
160 m_entryInfoMap[i] = entryInfo;
161}
162
Junxiao Shi52555b02016-11-25 21:39:06 +0000163} // namespace priority_fifo
Minsheng Zhangcb6e05f2015-04-20 15:51:47 -0500164} // namespace cs
165} // namespace nfd