Mercurial > hg > orthanc-stone
annotate Framework/Toolbox/DownloadStack.cpp @ 134:4cff7b1ed31d
upgrade to year 2018
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 02 Jan 2018 09:51:36 +0100 |
parents | 28956ed68280 |
children | fccffbf99ba1 |
rev | line source |
---|---|
0 | 1 /** |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
134
4cff7b1ed31d
upgrade to year 2018
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
47
diff
changeset
|
5 * Copyright (C) 2017-2018 Osimis S.A., Belgium |
0 | 6 * |
7 * This program is free software: you can redistribute it and/or | |
47 | 8 * modify it under the terms of the GNU Affero General Public License |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
0 | 11 * |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
47 | 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 * Affero General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Affero General Public License | |
0 | 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 **/ | |
20 | |
21 | |
22 #include "DownloadStack.h" | |
23 | |
16 | 24 #include "../../Resources/Orthanc/Core/OrthancException.h" |
0 | 25 |
26 #include <cassert> | |
27 | |
28 namespace OrthancStone | |
29 { | |
30 bool DownloadStack::CheckInvariants() const | |
31 { | |
32 std::vector<bool> dequeued(nodes_.size(), true); | |
33 | |
34 int i = firstNode_; | |
35 while (i != NIL) | |
36 { | |
37 const Node& node = nodes_[i]; | |
38 | |
39 dequeued[i] = false; | |
40 | |
41 if (node.next_ != NIL && | |
42 nodes_[node.next_].prev_ != i) | |
43 { | |
44 return false; | |
45 } | |
46 | |
47 if (node.prev_ != NIL && | |
48 nodes_[node.prev_].next_ != i) | |
49 { | |
50 return false; | |
51 } | |
52 | |
53 i = nodes_[i].next_; | |
54 } | |
55 | |
56 for (size_t i = 0; i < nodes_.size(); i++) | |
57 { | |
58 if (nodes_[i].dequeued_ != dequeued[i]) | |
59 { | |
60 return false; | |
61 } | |
62 } | |
63 | |
64 return true; | |
65 } | |
66 | |
67 | |
68 DownloadStack::DownloadStack(unsigned int size) | |
69 { | |
70 nodes_.resize(size); | |
71 | |
72 if (size == 0) | |
73 { | |
74 firstNode_ = NIL; | |
75 } | |
76 else | |
77 { | |
78 for (size_t i = 0; i < size; i++) | |
79 { | |
80 nodes_[i].prev_ = i - 1; | |
81 nodes_[i].next_ = i + 1; | |
82 nodes_[i].dequeued_ = false; | |
83 } | |
84 | |
85 nodes_.front().prev_ = NIL; | |
86 nodes_.back().next_ = NIL; | |
87 firstNode_ = 0; | |
88 } | |
89 | |
90 assert(CheckInvariants()); | |
91 } | |
92 | |
93 | |
94 DownloadStack::~DownloadStack() | |
95 { | |
96 assert(CheckInvariants()); | |
97 } | |
98 | |
99 | |
100 bool DownloadStack::Pop(unsigned int& value) | |
101 { | |
102 boost::mutex::scoped_lock lock(mutex_); | |
103 | |
104 assert(CheckInvariants()); | |
105 | |
106 if (firstNode_ == NIL) | |
107 { | |
108 for (size_t i = 0; i < nodes_.size(); i++) | |
109 { | |
110 assert(nodes_[i].dequeued_); | |
111 } | |
112 | |
113 return false; | |
114 } | |
115 else | |
116 { | |
117 assert(firstNode_ >= 0 && firstNode_ < static_cast<int>(nodes_.size())); | |
118 value = firstNode_; | |
119 | |
120 Node& node = nodes_[firstNode_]; | |
121 assert(node.prev_ == NIL); | |
122 assert(!node.dequeued_); | |
123 | |
124 node.dequeued_ = true; | |
125 firstNode_ = node.next_; | |
126 | |
127 if (firstNode_ != NIL) | |
128 { | |
129 nodes_[firstNode_].prev_ = NIL; | |
130 } | |
131 | |
132 return true; | |
133 } | |
134 } | |
135 | |
136 | |
137 void DownloadStack::SetTopNodeInternal(unsigned int value) | |
138 { | |
139 assert(CheckInvariants()); | |
140 | |
141 Node& node = nodes_[value]; | |
142 | |
143 if (node.dequeued_) | |
144 { | |
145 // This node has already been processed by the download thread, nothing to do | |
146 return; | |
147 } | |
148 | |
149 // Remove the node from the list | |
150 if (node.prev_ == NIL) | |
151 { | |
152 assert(firstNode_ == static_cast<int>(value)); | |
153 | |
154 // This is already the top node in the list, nothing to do | |
155 return; | |
156 } | |
157 | |
158 nodes_[node.prev_].next_ = node.next_; | |
159 | |
160 if (node.next_ != NIL) | |
161 { | |
162 nodes_[node.next_].prev_ = node.prev_; | |
163 } | |
164 | |
165 // Add back the node at the top of the list | |
166 assert(firstNode_ != NIL); | |
167 | |
168 Node& old = nodes_[firstNode_]; | |
169 assert(old.prev_ == NIL); | |
170 assert(!old.dequeued_); | |
171 node.prev_ = NIL; | |
172 node.next_ = firstNode_; | |
173 old.prev_ = value; | |
174 | |
175 firstNode_ = value; | |
176 } | |
177 | |
178 | |
179 void DownloadStack::Writer::SetTopNode(unsigned int value) | |
180 { | |
181 if (value >= that_.nodes_.size()) | |
182 { | |
183 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
184 } | |
185 | |
186 that_.SetTopNodeInternal(value); | |
187 } | |
188 | |
189 | |
190 void DownloadStack::Writer::SetTopNodePermissive(int value) | |
191 { | |
192 if (value >= 0 && | |
193 value < static_cast<int>(that_.nodes_.size())) | |
194 { | |
195 that_.SetTopNodeInternal(value); | |
196 } | |
197 } | |
198 } |