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 }