comparison Framework/Oracle/GenericOracleRunner.cpp @ 1124:a8bf81756839 broker

unsuccessful attempt to cache ParseDicomFileCommand
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 05 Nov 2019 18:49:06 +0100
parents a08699daf78b
children 8e3763d1736a
comparison
equal deleted inserted replaced
1117:383aa2a7d426 1124:a8bf81756839
224 return new ReadFileCommand::SuccessMessage(command, content); 224 return new ReadFileCommand::SuccessMessage(command, content);
225 } 225 }
226 226
227 227
228 #if ORTHANC_ENABLE_DCMTK == 1 228 #if ORTHANC_ENABLE_DCMTK == 1
229 static IMessage* Execute(const std::string& root, 229 static ParseDicomFileCommand::SuccessMessage* Execute(const std::string& root,
230 const ParseDicomFileCommand& command) 230 const ParseDicomFileCommand& command)
231 { 231 {
232 std::string path = GetPath(root, command.GetPath()); 232 std::string path = GetPath(root, command.GetPath());
233 233
234 if (!Orthanc::SystemToolbox::IsRegularFile(path)) 234 if (!Orthanc::SystemToolbox::IsRegularFile(path))
235 { 235 {
241 // Check for 32bit systems 241 // Check for 32bit systems
242 if (fileSize != static_cast<uint64_t>(static_cast<size_t>(fileSize))) 242 if (fileSize != static_cast<uint64_t>(static_cast<size_t>(fileSize)))
243 { 243 {
244 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory); 244 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory);
245 } 245 }
246 246
247 DcmFileFormat f; 247 DcmFileFormat dicom;
248 bool ok; 248 bool ok;
249 249
250 if (command.IsPixelDataIncluded()) 250 if (command.IsPixelDataIncluded())
251 { 251 {
252 ok = f.loadFile(path.c_str()).good(); 252 ok = dicom.loadFile(path.c_str()).good();
253 } 253 }
254 else 254 else
255 { 255 {
256 #if DCMTK_VERSION_NUMBER >= 362 256 #if DCMTK_VERSION_NUMBER >= 362
257 // NB : We could stop at (0x3007, 0x0000) instead of 257 // NB : We could stop at (0x3007, 0x0000) instead of
258 // DCM_PixelData, cf. the Orthanc::DICOM_TAG_* constants 258 // DCM_PixelData, cf. the Orthanc::DICOM_TAG_* constants
259 259
260 static const DcmTagKey STOP = DCM_PixelData; 260 static const DcmTagKey STOP = DCM_PixelData;
261 //static const DcmTagKey STOP(0x3007, 0x0000); 261 //static const DcmTagKey STOP(0x3007, 0x0000);
262 262
263 ok = f.loadFileUntilTag(path.c_str(), EXS_Unknown, EGL_noChange, 263 ok = dicom.loadFileUntilTag(path.c_str(), EXS_Unknown, EGL_noChange,
264 DCM_MaxReadLength, ERM_autoDetect, STOP).good(); 264 DCM_MaxReadLength, ERM_autoDetect, STOP).good();
265 #else 265 #else
266 // The primitive "loadFileUntilTag" was introduced in DCMTK 3.6.2 266 // The primitive "loadFileUntilTag" was introduced in DCMTK 3.6.2
267 ok = f.loadFile(path.c_str()).good(); 267 ok = dicom.loadFile(path.c_str()).good();
268 #endif 268 #endif
269 } 269 }
270
271 printf("Reading %s\n", path.c_str());
270 272
271 if (ok) 273 if (ok)
272 { 274 {
273 return new ParseDicomFileCommand::SuccessMessage(command, f, static_cast<size_t>(fileSize)); 275 return new ParseDicomFileCommand::SuccessMessage
276 (command, dicom, static_cast<size_t>(fileSize), command.IsPixelDataIncluded());
274 } 277 }
275 else 278 else
276 { 279 {
277 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, 280 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat,
278 "Cannot parse file: " + path); 281 "Cannot parse file: " + path);
279 } 282 }
280 } 283 }
284
285
286 static ParseDicomFileCommand::SuccessMessage* Execute(boost::shared_ptr<ParsedDicomFileCache> cache,
287 const std::string& root,
288 const ParseDicomFileCommand& command)
289 {
290 #if 0
291 // The code to use the cache is buggy in multithreaded environments => TODO FIX
292 if (cache.get())
293 {
294 {
295 ParsedDicomFileCache::Reader reader(*cache, command.GetPath());
296 if (reader.IsValid() &&
297 (!command.IsPixelDataIncluded() ||
298 reader.HasPixelData()))
299 {
300 // Reuse the DICOM file from the cache
301 return new ParseDicomFileCommand::SuccessMessage(
302 command, reader.GetDicom(), reader.GetFileSize(), reader.HasPixelData());
303 }
304 }
305
306 // Not in the cache, first read and parse the DICOM file
307 std::auto_ptr<ParseDicomFileCommand::SuccessMessage> message(Execute(root, command));
308
309 // Secondly, store it into the cache for future use
310 assert(&message->GetOrigin() == &command);
311 cache->Acquire(message->GetOrigin().GetPath(), message->GetDicom(),
312 message->GetFileSize(), message->HasPixelData());
313
314 return message.release();
315 }
316 else
317 {
318 // No cache available
319 return Execute(root, command);
320 }
321 #else
322 return Execute(root, command);
323 #endif
324 }
325
281 #endif 326 #endif
282 327
283 328
284 IMessage* GenericOracleRunner::Run(IOracleCommand& command) 329 IMessage* GenericOracleRunner::Run(IOracleCommand& command)
285 { 330 {
309 case IOracleCommand::Type_ReadFile: 354 case IOracleCommand::Type_ReadFile:
310 return Execute(rootDirectory_, dynamic_cast<const ReadFileCommand&>(command)); 355 return Execute(rootDirectory_, dynamic_cast<const ReadFileCommand&>(command));
311 356
312 case IOracleCommand::Type_ParseDicomFile: 357 case IOracleCommand::Type_ParseDicomFile:
313 #if ORTHANC_ENABLE_DCMTK == 1 358 #if ORTHANC_ENABLE_DCMTK == 1
314 return Execute(rootDirectory_, dynamic_cast<const ParseDicomFileCommand&>(command)); 359 return Execute(dicomCache_, rootDirectory_,
360 dynamic_cast<const ParseDicomFileCommand&>(command));
315 #else 361 #else
316 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, 362 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented,
317 "DCMTK must be enabled to parse DICOM files"); 363 "DCMTK must be enabled to parse DICOM files");
318 #endif 364 #endif
319 365