Mercurial > hg > orthanc-stone
comparison Framework/Loaders/LoaderCache.cpp @ 1381:f4a06ad1580b
Branch broker is now the new default
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Wed, 22 Apr 2020 14:05:47 +0200 |
parents | 2d8ab34c8c91 e92c516adcbd |
children | cde379b9d1d2 |
comparison
equal
deleted
inserted
replaced
1375:4431ffdcc2a4 | 1381:f4a06ad1580b |
---|---|
23 #include "../StoneException.h" | 23 #include "../StoneException.h" |
24 #include "OrthancSeriesVolumeProgressiveLoader.h" | 24 #include "OrthancSeriesVolumeProgressiveLoader.h" |
25 #include "OrthancMultiframeVolumeLoader.h" | 25 #include "OrthancMultiframeVolumeLoader.h" |
26 #include "DicomStructureSetLoader.h" | 26 #include "DicomStructureSetLoader.h" |
27 | 27 |
28 #ifdef BGO_ENABLE_DICOMSTRUCTURESETLOADER2 | 28 #include "../Loaders/ILoadersContext.h" |
29 #include "DicomStructureSetLoader2.h" | |
30 #endif | |
31 //BGO_ENABLE_DICOMSTRUCTURESETLOADER2 | |
32 | |
33 | 29 |
34 #if ORTHANC_ENABLE_WASM == 1 | 30 #if ORTHANC_ENABLE_WASM == 1 |
35 # include <unistd.h> | 31 # include <unistd.h> |
36 # include "../Oracle/WebAssemblyOracle.h" | 32 # include "../Oracle/WebAssemblyOracle.h" |
37 #else | 33 #else |
38 # include "../Oracle/ThreadedOracle.h" | 34 # include "../Oracle/ThreadedOracle.h" |
39 #endif | 35 #endif |
40 | 36 |
41 #include "../Messages/LockingEmitter.h" | |
42 | |
43 #ifdef BGO_ENABLE_DICOMSTRUCTURESETLOADER2 | |
44 #include "../Toolbox/DicomStructureSet2.h" | |
45 #endif | |
46 //BGO_ENABLE_DICOMSTRUCTURESETLOADER2 | |
47 | |
48 #include "../Volumes/DicomVolumeImage.h" | 37 #include "../Volumes/DicomVolumeImage.h" |
49 #include "../Volumes/DicomVolumeImageMPRSlicer.h" | 38 #include "../Volumes/DicomVolumeImageMPRSlicer.h" |
50 | 39 |
51 #ifdef BGO_ENABLE_DICOMSTRUCTURESETLOADER2 | |
52 #include "../Volumes/DicomStructureSetSlicer2.h" | |
53 #endif | |
54 //BGO_ENABLE_DICOMSTRUCTURESETLOADER2 | |
55 | |
56 #include <Core/OrthancException.h> | 40 #include <Core/OrthancException.h> |
57 #include <Core/Toolbox.h> | 41 #include <Core/Toolbox.h> |
58 | 42 |
59 namespace OrthancStone | 43 namespace OrthancStone |
60 { | 44 { |
61 #if ORTHANC_ENABLE_WASM == 1 | 45 LoaderCache::LoaderCache(OrthancStone::ILoadersContext& loadersContext) |
62 LoaderCache::LoaderCache(WebAssemblyOracle& oracle) | 46 : loadersContext_(loadersContext) |
63 : oracle_(oracle) | 47 { |
64 { | 48 |
65 | 49 } |
66 } | 50 |
67 #else | 51 boost::shared_ptr<OrthancSeriesVolumeProgressiveLoader> |
68 LoaderCache::LoaderCache(ThreadedOracle& oracle, LockingEmitter& lockingEmitter) | |
69 : oracle_(oracle) | |
70 , lockingEmitter_(lockingEmitter) | |
71 { | |
72 } | |
73 #endif | |
74 | |
75 boost::shared_ptr<OrthancStone::OrthancSeriesVolumeProgressiveLoader> | |
76 LoaderCache::GetSeriesVolumeProgressiveLoader(std::string seriesUuid) | 52 LoaderCache::GetSeriesVolumeProgressiveLoader(std::string seriesUuid) |
77 { | 53 { |
78 try | 54 try |
79 { | 55 { |
80 | 56 |
83 Orthanc::Toolbox::ToLowerCase(seriesUuid); | 59 Orthanc::Toolbox::ToLowerCase(seriesUuid); |
84 | 60 |
85 // find in cache | 61 // find in cache |
86 if (seriesVolumeProgressiveLoaders_.find(seriesUuid) == seriesVolumeProgressiveLoaders_.end()) | 62 if (seriesVolumeProgressiveLoaders_.find(seriesUuid) == seriesVolumeProgressiveLoaders_.end()) |
87 { | 63 { |
88 // LOG(TRACE) << "LoaderCache::GetSeriesVolumeProgressiveLoader : CACHEMISS --> need to load seriesUUid = " << seriesUuid; | 64 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(loadersContext_.Lock()); |
89 #if ORTHANC_ENABLE_WASM == 1 | 65 |
90 // LOG(TRACE) << "Performing request for series " << seriesUuid << " sbrk(0) = " << sbrk(0); | 66 boost::shared_ptr<OrthancStone::DicomVolumeImage> volumeImage(new OrthancStone::DicomVolumeImage); |
91 #else | |
92 // LOG(TRACE) << "Performing request for series " << seriesUuid; | |
93 #endif | |
94 boost::shared_ptr<DicomVolumeImage> volumeImage(new DicomVolumeImage); | |
95 boost::shared_ptr<OrthancSeriesVolumeProgressiveLoader> loader; | 67 boost::shared_ptr<OrthancSeriesVolumeProgressiveLoader> loader; |
96 // LOG(TRACE) << "volumeImage = " << volumeImage.get(); | 68 |
97 { | 69 // true means "use progressive quality" |
98 #if ORTHANC_ENABLE_WASM == 1 | 70 // false means "load high quality slices only" |
99 loader.reset(new OrthancSeriesVolumeProgressiveLoader(volumeImage, oracle_, oracle_)); | 71 loader = OrthancSeriesVolumeProgressiveLoader::Create(loadersContext_, volumeImage, false); |
100 #else | 72 loader->LoadSeries(seriesUuid); |
101 LockingEmitter::WriterLock lock(lockingEmitter_); | |
102 loader.reset(new OrthancSeriesVolumeProgressiveLoader(volumeImage, oracle_, lock.GetOracleObservable())); | |
103 #endif | |
104 // LOG(TRACE) << "LoaderCache::GetSeriesVolumeProgressiveLoader : loader = " << loader.get(); | |
105 loader->LoadSeries(seriesUuid); | |
106 // LOG(TRACE) << "LoaderCache::GetSeriesVolumeProgressiveLoader : loader->LoadSeries successful"; | |
107 } | |
108 seriesVolumeProgressiveLoaders_[seriesUuid] = loader; | 73 seriesVolumeProgressiveLoaders_[seriesUuid] = loader; |
109 } | 74 } |
110 else | 75 else |
111 { | 76 { |
112 // LOG(TRACE) << "LoaderCache::GetSeriesVolumeProgressiveLoader : returning cached loader for seriesUUid = " << seriesUuid; | 77 // LOG(TRACE) << "LoaderCache::GetSeriesVolumeProgressiveLoader : returning cached loader for seriesUUid = " << seriesUuid; |
147 ORTHANC_ASSERT(multiframeVolumeLoaders_.find(instanceUuid) != multiframeVolumeLoaders_.end()); | 112 ORTHANC_ASSERT(multiframeVolumeLoaders_.find(instanceUuid) != multiframeVolumeLoaders_.end()); |
148 | 113 |
149 return multiframeVolumeLoaders_[instanceUuid]; | 114 return multiframeVolumeLoaders_[instanceUuid]; |
150 } | 115 } |
151 | 116 |
152 boost::shared_ptr<DicomVolumeImageMPRSlicer> LoaderCache::GetMultiframeDicomVolumeImageMPRSlicer(std::string instanceUuid) | 117 boost::shared_ptr<OrthancStone::DicomVolumeImageMPRSlicer> LoaderCache::GetMultiframeDicomVolumeImageMPRSlicer(std::string instanceUuid) |
153 { | 118 { |
154 try | 119 try |
155 { | 120 { |
156 // normalize keys a little | 121 // normalize keys a little |
157 instanceUuid = Orthanc::Toolbox::StripSpaces(instanceUuid); | 122 instanceUuid = Orthanc::Toolbox::StripSpaces(instanceUuid); |
158 Orthanc::Toolbox::ToLowerCase(instanceUuid); | 123 Orthanc::Toolbox::ToLowerCase(instanceUuid); |
159 | 124 |
160 // find in cache | 125 // find in cache |
161 if (dicomVolumeImageMPRSlicers_.find(instanceUuid) == dicomVolumeImageMPRSlicers_.end()) | 126 if (dicomVolumeImageMPRSlicers_.find(instanceUuid) == dicomVolumeImageMPRSlicers_.end()) |
162 { | 127 { |
163 boost::shared_ptr<DicomVolumeImage> volumeImage(new DicomVolumeImage); | 128 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(loadersContext_.Lock()); |
129 boost::shared_ptr<OrthancStone::DicomVolumeImage> volumeImage(new OrthancStone::DicomVolumeImage); | |
164 boost::shared_ptr<OrthancMultiframeVolumeLoader> loader; | 130 boost::shared_ptr<OrthancMultiframeVolumeLoader> loader; |
165 | |
166 { | 131 { |
167 #if ORTHANC_ENABLE_WASM == 1 | 132 loader = OrthancMultiframeVolumeLoader::Create(loadersContext_, volumeImage); |
168 loader.reset(new OrthancMultiframeVolumeLoader(volumeImage, oracle_, oracle_)); | |
169 #else | |
170 LockingEmitter::WriterLock lock(lockingEmitter_); | |
171 loader.reset(new OrthancMultiframeVolumeLoader(volumeImage, | |
172 oracle_, | |
173 lock.GetOracleObservable())); | |
174 #endif | |
175 loader->LoadInstance(instanceUuid); | 133 loader->LoadInstance(instanceUuid); |
176 } | 134 } |
177 multiframeVolumeLoaders_[instanceUuid] = loader; | 135 multiframeVolumeLoaders_[instanceUuid] = loader; |
178 boost::shared_ptr<DicomVolumeImageMPRSlicer> mprSlicer(new DicomVolumeImageMPRSlicer(volumeImage)); | 136 boost::shared_ptr<OrthancStone::DicomVolumeImageMPRSlicer> mprSlicer(new OrthancStone::DicomVolumeImageMPRSlicer(volumeImage)); |
179 dicomVolumeImageMPRSlicers_[instanceUuid] = mprSlicer; | 137 dicomVolumeImageMPRSlicers_[instanceUuid] = mprSlicer; |
180 } | 138 } |
181 return dicomVolumeImageMPRSlicers_[instanceUuid]; | 139 return dicomVolumeImageMPRSlicers_[instanceUuid]; |
182 } | 140 } |
183 catch (const Orthanc::OrthancException& e) | 141 catch (const Orthanc::OrthancException& e) |
202 LOG(ERROR) << "Unknown exception in LoaderCache"; | 160 LOG(ERROR) << "Unknown exception in LoaderCache"; |
203 throw; | 161 throw; |
204 } | 162 } |
205 } | 163 } |
206 | 164 |
207 #ifdef BGO_ENABLE_DICOMSTRUCTURESETLOADER2 | |
208 | |
209 boost::shared_ptr<DicomStructureSetSlicer2> LoaderCache::GetDicomStructureSetSlicer2(std::string instanceUuid) | |
210 { | |
211 // if the loader is not available, let's trigger its creation | |
212 if (dicomStructureSetSlicers2_.find(instanceUuid) == dicomStructureSetSlicers2_.end()) | |
213 { | |
214 GetDicomStructureSetLoader2(instanceUuid); | |
215 } | |
216 ORTHANC_ASSERT(dicomStructureSetSlicers2_.find(instanceUuid) != dicomStructureSetSlicers2_.end()); | |
217 | |
218 return dicomStructureSetSlicers2_[instanceUuid]; | |
219 } | |
220 #endif | |
221 //BGO_ENABLE_DICOMSTRUCTURESETLOADER2 | |
222 | |
223 | |
224 /** | 165 /** |
225 This method allows to convert a list of string into a string by | 166 This method allows to convert a list of string into a string by |
226 sorting the strings then joining them | 167 sorting the strings then joining them |
227 */ | 168 */ |
228 static std::string SortAndJoin(const std::vector<std::string>& stringList) | 169 static std::string SortAndJoin(const std::vector<std::string>& stringList) |
262 std::string entryKey = inInstanceUuid + "_" + initiallyVisibleStructuresKey; | 203 std::string entryKey = inInstanceUuid + "_" + initiallyVisibleStructuresKey; |
263 | 204 |
264 // find in cache | 205 // find in cache |
265 if (dicomStructureSetLoaders_.find(entryKey) == dicomStructureSetLoaders_.end()) | 206 if (dicomStructureSetLoaders_.find(entryKey) == dicomStructureSetLoaders_.end()) |
266 { | 207 { |
208 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(loadersContext_.Lock()); | |
209 | |
267 boost::shared_ptr<DicomStructureSetLoader> loader; | 210 boost::shared_ptr<DicomStructureSetLoader> loader; |
268 | |
269 { | 211 { |
270 #if ORTHANC_ENABLE_WASM == 1 | 212 loader = DicomStructureSetLoader::Create(loadersContext_); |
271 loader.reset(new DicomStructureSetLoader(oracle_, oracle_)); | |
272 #else | |
273 LockingEmitter::WriterLock lock(lockingEmitter_); | |
274 loader.reset(new DicomStructureSetLoader(oracle_, lock.GetOracleObservable())); | |
275 #endif | |
276 loader->LoadInstance(inInstanceUuid, initiallyVisibleStructures); | 213 loader->LoadInstance(inInstanceUuid, initiallyVisibleStructures); |
277 } | 214 } |
278 dicomStructureSetLoaders_[entryKey] = loader; | 215 dicomStructureSetLoaders_[entryKey] = loader; |
279 } | 216 } |
280 return dicomStructureSetLoaders_[entryKey]; | 217 return dicomStructureSetLoaders_[entryKey]; |
301 LOG(ERROR) << "Unknown exception in LoaderCache"; | 238 LOG(ERROR) << "Unknown exception in LoaderCache"; |
302 throw; | 239 throw; |
303 } | 240 } |
304 } | 241 } |
305 | 242 |
306 #ifdef BGO_ENABLE_DICOMSTRUCTURESETLOADER2 | |
307 | |
308 boost::shared_ptr<DicomStructureSetLoader2> LoaderCache::GetDicomStructureSetLoader2(std::string instanceUuid) | |
309 { | |
310 try | |
311 { | |
312 // normalize keys a little | |
313 instanceUuid = Orthanc::Toolbox::StripSpaces(instanceUuid); | |
314 Orthanc::Toolbox::ToLowerCase(instanceUuid); | |
315 | |
316 // find in cache | |
317 if (dicomStructureSetLoaders2_.find(instanceUuid) == dicomStructureSetLoaders2_.end()) | |
318 { | |
319 boost::shared_ptr<DicomStructureSetLoader2> loader; | |
320 boost::shared_ptr<DicomStructureSet2> structureSet(new DicomStructureSet2()); | |
321 boost::shared_ptr<DicomStructureSetSlicer2> rtSlicer(new DicomStructureSetSlicer2(structureSet)); | |
322 dicomStructureSetSlicers2_[instanceUuid] = rtSlicer; | |
323 dicomStructureSets2_[instanceUuid] = structureSet; // to prevent it from being deleted | |
324 { | |
325 #if ORTHANC_ENABLE_WASM == 1 | |
326 loader.reset(new DicomStructureSetLoader2(*(structureSet.get()), oracle_, oracle_)); | |
327 #else | |
328 LockingEmitter::WriterLock lock(lockingEmitter_); | |
329 // TODO: clarify lifetimes... this is DANGEROUS! | |
330 loader.reset(new DicomStructureSetLoader2(*(structureSet.get()), oracle_, lock.GetOracleObservable())); | |
331 #endif | |
332 loader->LoadInstance(instanceUuid); | |
333 } | |
334 dicomStructureSetLoaders2_[instanceUuid] = loader; | |
335 } | |
336 return dicomStructureSetLoaders2_[instanceUuid]; | |
337 } | |
338 catch (const Orthanc::OrthancException& e) | |
339 { | |
340 if (e.HasDetails()) | |
341 { | |
342 LOG(ERROR) << "OrthancException in GetDicomStructureSetLoader2: " << e.What() << " Details: " << e.GetDetails(); | |
343 } | |
344 else | |
345 { | |
346 LOG(ERROR) << "OrthancException in GetDicomStructureSetLoader2: " << e.What(); | |
347 } | |
348 throw; | |
349 } | |
350 catch (const std::exception& e) | |
351 { | |
352 LOG(ERROR) << "std::exception in GetDicomStructureSetLoader2: " << e.what(); | |
353 throw; | |
354 } | |
355 catch (...) | |
356 { | |
357 LOG(ERROR) << "Unknown exception in GetDicomStructureSetLoader2"; | |
358 throw; | |
359 } | |
360 } | |
361 | |
362 #endif | |
363 // BGO_ENABLE_DICOMSTRUCTURESETLOADER2 | |
364 | |
365 | |
366 void LoaderCache::ClearCache() | 243 void LoaderCache::ClearCache() |
367 { | 244 { |
368 #if ORTHANC_ENABLE_WASM != 1 | 245 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(loadersContext_.Lock()); |
369 LockingEmitter::WriterLock lock(lockingEmitter_); | |
370 #endif | |
371 | 246 |
372 //#ifndef NDEBUG | 247 #ifndef NDEBUG |
373 // ISO way of checking for debug builds | 248 // ISO way of checking for debug builds |
374 DebugDisplayObjRefCounts(); | 249 DebugDisplayObjRefCounts(); |
375 //#endif | 250 #endif |
376 seriesVolumeProgressiveLoaders_.clear(); | 251 seriesVolumeProgressiveLoaders_.clear(); |
377 multiframeVolumeLoaders_.clear(); | 252 multiframeVolumeLoaders_.clear(); |
378 dicomVolumeImageMPRSlicers_.clear(); | 253 dicomVolumeImageMPRSlicers_.clear(); |
379 dicomStructureSetLoaders_.clear(); | 254 dicomStructureSetLoaders_.clear(); |
380 | 255 |
381 #ifdef BGO_ENABLE_DICOMSTRUCTURESETLOADER2 | |
382 // order is important! | |
383 dicomStructureSetLoaders2_.clear(); | |
384 dicomStructureSetSlicers2_.clear(); | |
385 dicomStructureSets2_.clear(); | |
386 #endif | |
387 // BGO_ENABLE_DICOMSTRUCTURESETLOADER2 | |
388 } | 256 } |
389 | 257 |
390 template<typename T> void DebugDisplayObjRefCountsInMap( | 258 template<typename T> void DebugDisplayObjRefCountsInMap( |
391 const std::string& name, const std::map<std::string, boost::shared_ptr<T> >& myMap) | 259 const std::string& name, const std::map<std::string, boost::shared_ptr<T> >& myMap) |
392 { | 260 { |
404 { | 272 { |
405 DebugDisplayObjRefCountsInMap("seriesVolumeProgressiveLoaders_", seriesVolumeProgressiveLoaders_); | 273 DebugDisplayObjRefCountsInMap("seriesVolumeProgressiveLoaders_", seriesVolumeProgressiveLoaders_); |
406 DebugDisplayObjRefCountsInMap("multiframeVolumeLoaders_", multiframeVolumeLoaders_); | 274 DebugDisplayObjRefCountsInMap("multiframeVolumeLoaders_", multiframeVolumeLoaders_); |
407 DebugDisplayObjRefCountsInMap("dicomVolumeImageMPRSlicers_", dicomVolumeImageMPRSlicers_); | 275 DebugDisplayObjRefCountsInMap("dicomVolumeImageMPRSlicers_", dicomVolumeImageMPRSlicers_); |
408 DebugDisplayObjRefCountsInMap("dicomStructureSetLoaders_", dicomStructureSetLoaders_); | 276 DebugDisplayObjRefCountsInMap("dicomStructureSetLoaders_", dicomStructureSetLoaders_); |
409 #ifdef BGO_ENABLE_DICOMSTRUCTURESETLOADER2 | |
410 DebugDisplayObjRefCountsInMap("dicomStructureSetLoaders2_", dicomStructureSetLoaders2_); | |
411 DebugDisplayObjRefCountsInMap("dicomStructureSetSlicers2_", dicomStructureSetSlicers2_); | |
412 #endif | |
413 //BGO_ENABLE_DICOMSTRUCTURESETLOADER2 | |
414 } | 277 } |
415 } | 278 } |