comparison Applications/Resources/Graveyard/LoaderCache.cpp @ 1591:5887a4f8594b

moving platform-specific files out of the "OrthancStone" folder
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 23 Oct 2020 13:15:03 +0200
parents OrthancStone/Sources/Loaders/LoaderCache.cpp@244ad1e4e76a
children 9ac2a65d4172
comparison
equal deleted inserted replaced
1590:7b963bccafef 1591:5887a4f8594b
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
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.
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
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
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21 #include "LoaderCache.h"
22
23 #include "../StoneException.h"
24 #include "OrthancSeriesVolumeProgressiveLoader.h"
25 #include "OrthancMultiframeVolumeLoader.h"
26 #include "DicomStructureSetLoader.h"
27 #include "../Toolbox/GenericToolbox.h"
28
29 #include "../Loaders/ILoadersContext.h"
30
31 #if ORTHANC_ENABLE_WASM == 1
32 # include <unistd.h>
33 # include "../Oracle/WebAssemblyOracle.h"
34 #else
35 # include "../Oracle/ThreadedOracle.h"
36 #endif
37
38 #include "../Volumes/DicomVolumeImage.h"
39 #include "../Volumes/DicomVolumeImageMPRSlicer.h"
40
41 #include <OrthancException.h>
42 #include <Toolbox.h>
43
44 namespace OrthancStone
45 {
46 LoaderCache::LoaderCache(OrthancStone::ILoadersContext& loadersContext, bool useCtProgressiveQuality)
47 : loadersContext_(loadersContext)
48 , useCtProgressiveQuality_(useCtProgressiveQuality)
49
50 {
51
52 }
53
54 boost::shared_ptr<OrthancSeriesVolumeProgressiveLoader>
55 LoaderCache::GetSeriesVolumeProgressiveLoader(std::string seriesUuid)
56 {
57 try
58 {
59 // normalize keys a little
60 GenericToolbox::NormalizeUuid(seriesUuid);
61
62 // find in cache
63 if (seriesVolumeProgressiveLoaders_.find(seriesUuid) == seriesVolumeProgressiveLoaders_.end())
64 {
65 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(loadersContext_.Lock());
66
67 boost::shared_ptr<OrthancStone::DicomVolumeImage> volumeImage(new OrthancStone::DicomVolumeImage);
68 boost::shared_ptr<OrthancSeriesVolumeProgressiveLoader> loader;
69
70 // true means "use progressive quality"
71 // false means "load high quality slices only"
72 loader = OrthancSeriesVolumeProgressiveLoader::Create(loadersContext_, volumeImage, useCtProgressiveQuality_);
73 loader->LoadSeries(seriesUuid);
74 seriesVolumeProgressiveLoaders_[seriesUuid] = loader;
75 }
76 else
77 {
78 // LOG(TRACE) << "LoaderCache::GetSeriesVolumeProgressiveLoader : returning cached loader for seriesUUid = " << seriesUuid;
79 }
80 return seriesVolumeProgressiveLoaders_[seriesUuid];
81 }
82 catch (const Orthanc::OrthancException& e)
83 {
84 if (e.HasDetails())
85 {
86 LOG(ERROR) << "OrthancException in LoaderCache: " << e.What() << " Details: " << e.GetDetails();
87 }
88 else
89 {
90 LOG(ERROR) << "OrthancException in LoaderCache: " << e.What();
91 }
92 throw;
93 }
94 catch (const std::exception& e)
95 {
96 LOG(ERROR) << "std::exception in LoaderCache: " << e.what();
97 throw;
98 }
99 catch (...)
100 {
101 LOG(ERROR) << "Unknown exception in LoaderCache";
102 throw;
103 }
104 }
105
106 boost::shared_ptr<OrthancMultiframeVolumeLoader> LoaderCache::GetMultiframeVolumeLoader(std::string instanceUuid)
107 {
108 // normalize keys a little
109 GenericToolbox::NormalizeUuid(instanceUuid);
110
111 // if the loader is not available, let's trigger its creation
112 if(multiframeVolumeLoaders_.find(instanceUuid) == multiframeVolumeLoaders_.end())
113 {
114 GetMultiframeDicomVolumeImageMPRSlicer(instanceUuid);
115 }
116 ORTHANC_ASSERT(multiframeVolumeLoaders_.find(instanceUuid) != multiframeVolumeLoaders_.end());
117
118 return multiframeVolumeLoaders_[instanceUuid];
119 }
120
121 boost::shared_ptr<OrthancStone::DicomVolumeImageMPRSlicer> LoaderCache::GetMultiframeDicomVolumeImageMPRSlicer(std::string instanceUuid)
122 {
123 try
124 {
125 // normalize keys a little
126 GenericToolbox::NormalizeUuid(instanceUuid);
127
128 // find in cache
129 if (dicomVolumeImageMPRSlicers_.find(instanceUuid) == dicomVolumeImageMPRSlicers_.end())
130 {
131 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(loadersContext_.Lock());
132 boost::shared_ptr<OrthancStone::DicomVolumeImage> volumeImage(new OrthancStone::DicomVolumeImage);
133 boost::shared_ptr<OrthancMultiframeVolumeLoader> loader;
134 {
135 loader = OrthancMultiframeVolumeLoader::Create(loadersContext_, volumeImage);
136 loader->LoadInstance(instanceUuid);
137 }
138 multiframeVolumeLoaders_[instanceUuid] = loader;
139 boost::shared_ptr<OrthancStone::DicomVolumeImageMPRSlicer> mprSlicer(new OrthancStone::DicomVolumeImageMPRSlicer(volumeImage));
140 dicomVolumeImageMPRSlicers_[instanceUuid] = mprSlicer;
141 }
142 return dicomVolumeImageMPRSlicers_[instanceUuid];
143 }
144 catch (const Orthanc::OrthancException& e)
145 {
146 if (e.HasDetails())
147 {
148 LOG(ERROR) << "OrthancException in LoaderCache: " << e.What() << " Details: " << e.GetDetails();
149 }
150 else
151 {
152 LOG(ERROR) << "OrthancException in LoaderCache: " << e.What();
153 }
154 throw;
155 }
156 catch (const std::exception& e)
157 {
158 LOG(ERROR) << "std::exception in LoaderCache: " << e.what();
159 throw;
160 }
161 catch (...)
162 {
163 LOG(ERROR) << "Unknown exception in LoaderCache";
164 throw;
165 }
166 }
167
168 std::string LoaderCache::BuildDicomStructureSetLoaderKey(
169 const std::string& instanceUuid,
170 const std::string& uniqueKey)
171 {
172 return instanceUuid + "_" + uniqueKey;
173 }
174
175 boost::shared_ptr<DicomStructureSetLoader> LoaderCache::GetDicomStructureSetLoader(
176 std::string inInstanceUuid,
177 const std::vector<std::string>& initiallyVisibleStructures,
178 const std::string& uniqueKey)
179 {
180 try
181 {
182 // normalize keys a little
183 GenericToolbox::NormalizeUuid(inInstanceUuid);
184
185 std::string entryKey = BuildDicomStructureSetLoaderKey(inInstanceUuid, uniqueKey);
186
187 // find in cache
188 if (dicomStructureSetLoaders_.find(entryKey) == dicomStructureSetLoaders_.end())
189 {
190 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(loadersContext_.Lock());
191
192 boost::shared_ptr<DicomStructureSetLoader> loader;
193 {
194 loader = DicomStructureSetLoader::Create(loadersContext_);
195 loader->LoadInstance(inInstanceUuid, initiallyVisibleStructures);
196 }
197 dicomStructureSetLoaders_[entryKey] = loader;
198 }
199 return dicomStructureSetLoaders_[entryKey];
200 }
201 catch (const Orthanc::OrthancException& e)
202 {
203 if (e.HasDetails())
204 {
205 LOG(ERROR) << "OrthancException in LoaderCache: " << e.What() << " Details: " << e.GetDetails();
206 }
207 else
208 {
209 LOG(ERROR) << "OrthancException in LoaderCache: " << e.What();
210 }
211 throw;
212 }
213 catch (const std::exception& e)
214 {
215 LOG(ERROR) << "std::exception in LoaderCache: " << e.what();
216 throw;
217 }
218 catch (...)
219 {
220 LOG(ERROR) << "Unknown exception in LoaderCache";
221 throw;
222 }
223 }
224
225 void LoaderCache::ClearCache()
226 {
227 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(loadersContext_.Lock());
228
229 #ifndef NDEBUG
230 // ISO way of checking for debug builds
231 DebugDisplayObjRefCounts();
232 #endif
233 seriesVolumeProgressiveLoaders_.clear();
234 multiframeVolumeLoaders_.clear();
235 dicomVolumeImageMPRSlicers_.clear();
236 dicomStructureSetLoaders_.clear();
237
238 }
239
240 template<typename T> void DebugDisplayObjRefCountsInMap(
241 const std::string& name, const std::map<std::string, boost::shared_ptr<T> >& myMap)
242 {
243 LOG(TRACE) << "Map \"" << name << "\" ref counts:";
244 size_t i = 0;
245 for (typename std::map<std::string, boost::shared_ptr<T> >::const_iterator
246 it = myMap.begin(); it != myMap.end(); ++it)
247 {
248 LOG(TRACE) << " element #" << i << ": ref count = " << it->second.use_count();
249 i++;
250 }
251 }
252
253 void LoaderCache::DebugDisplayObjRefCounts()
254 {
255 DebugDisplayObjRefCountsInMap("seriesVolumeProgressiveLoaders_", seriesVolumeProgressiveLoaders_);
256 DebugDisplayObjRefCountsInMap("multiframeVolumeLoaders_", multiframeVolumeLoaders_);
257 DebugDisplayObjRefCountsInMap("dicomVolumeImageMPRSlicers_", dicomVolumeImageMPRSlicers_);
258 DebugDisplayObjRefCountsInMap("dicomStructureSetLoaders_", dicomStructureSetLoaders_);
259 }
260 }