Mercurial > hg > orthanc
comparison OrthancServer/OrthancFindRequestHandler.cpp @ 3012:af1530b45290
Optimization: On finds, do not read JSON (disk) if main DICOM tags (DB) are sufficient
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 13 Dec 2018 17:54:06 +0100 |
parents | 8265a6b56100 |
children | abe49ca61cd5 |
comparison
equal
deleted
inserted
replaced
3010:9f859a18cbc2 | 3012:af1530b45290 |
---|---|
363 return result.release(); | 363 return result.release(); |
364 } | 364 } |
365 | 365 |
366 | 366 |
367 static void AddAnswer(DicomFindAnswers& answers, | 367 static void AddAnswer(DicomFindAnswers& answers, |
368 const Json::Value& resource, | 368 const DicomMap& mainDicomTags, |
369 const Json::Value* dicomAsJson, // only used for sequences | |
369 const DicomArray& query, | 370 const DicomArray& query, |
370 const std::list<DicomTag>& sequencesToReturn, | 371 const std::list<DicomTag>& sequencesToReturn, |
371 const DicomMap* counters) | 372 const DicomMap* counters) |
372 { | 373 { |
373 DicomMap result; | 374 DicomMap result; |
381 } | 382 } |
382 else if (query.GetElement(i).GetTag() == DICOM_TAG_SPECIFIC_CHARACTER_SET) | 383 else if (query.GetElement(i).GetTag() == DICOM_TAG_SPECIFIC_CHARACTER_SET) |
383 { | 384 { |
384 // Do not include the encoding, this is handled by class ParsedDicomFile | 385 // Do not include the encoding, this is handled by class ParsedDicomFile |
385 } | 386 } |
386 else | 387 else if (dicomAsJson != NULL) |
387 { | 388 { |
388 std::string tag = query.GetElement(i).GetTag().Format(); | 389 std::string tag = query.GetElement(i).GetTag().Format(); |
389 std::string value; | 390 std::string value; |
390 if (resource.isMember(tag)) | 391 if (dicomAsJson->isMember(tag)) |
391 { | 392 { |
392 value = resource.get(tag, Json::arrayValue).get("Value", "").asString(); | 393 value = dicomAsJson->get(tag, Json::arrayValue).get("Value", "").asString(); |
393 result.SetValue(query.GetElement(i).GetTag(), value, false); | 394 result.SetValue(query.GetElement(i).GetTag(), value, false); |
394 } | 395 } |
395 else | 396 else |
396 { | 397 { |
397 result.SetValue(query.GetElement(i).GetTag(), "", false); | 398 result.SetValue(query.GetElement(i).GetTag(), "", false); |
398 } | 399 } |
400 } | |
401 else | |
402 { | |
403 // Best-effort | |
404 // TODO | |
405 throw OrthancException(ErrorCode_NotImplemented); | |
399 } | 406 } |
400 } | 407 } |
401 | 408 |
402 if (counters != NULL) | 409 if (counters != NULL) |
403 { | 410 { |
411 if (result.GetSize() == 0 && | 418 if (result.GetSize() == 0 && |
412 sequencesToReturn.empty()) | 419 sequencesToReturn.empty()) |
413 { | 420 { |
414 LOG(WARNING) << "The C-FIND request does not return any DICOM tag"; | 421 LOG(WARNING) << "The C-FIND request does not return any DICOM tag"; |
415 } | 422 } |
416 else if (sequencesToReturn.empty()) | 423 else if (sequencesToReturn.empty() || |
424 dicomAsJson == NULL) | |
417 { | 425 { |
418 answers.Add(result); | 426 answers.Add(result); |
419 } | 427 } |
420 else | 428 else |
421 { | 429 { |
422 ParsedDicomFile dicom(result); | 430 ParsedDicomFile dicom(result); |
423 | 431 |
424 for (std::list<DicomTag>::const_iterator tag = sequencesToReturn.begin(); | 432 for (std::list<DicomTag>::const_iterator tag = sequencesToReturn.begin(); |
425 tag != sequencesToReturn.end(); ++tag) | 433 tag != sequencesToReturn.end(); ++tag) |
426 { | 434 { |
427 const Json::Value& source = resource[tag->Format()]; | 435 assert(dicomAsJson != NULL); |
436 const Json::Value& source = (*dicomAsJson) [tag->Format()]; | |
428 | 437 |
429 if (source.type() == Json::objectValue && | 438 if (source.type() == Json::objectValue && |
430 source.isMember("Type") && | 439 source.isMember("Type") && |
431 source.isMember("Value") && | 440 source.isMember("Value") && |
432 source["Type"].asString() == "Sequence" && | 441 source["Type"].asString() == "Sequence" && |
544 sequencesToReturn_(sequencesToReturn), | 553 sequencesToReturn_(sequencesToReturn), |
545 query_(filteredInput) | 554 query_(filteredInput) |
546 { | 555 { |
547 answers_.SetComplete(false); | 556 answers_.SetComplete(false); |
548 } | 557 } |
558 | |
559 virtual bool IsDicomAsJsonNeeded() const | |
560 { | |
561 #if 1 | |
562 return true; | |
563 | |
564 #else | |
565 // TODO | |
566 | |
567 // Ask the "DICOM-as-JSON" attachment only if sequences are to | |
568 // be returned OR if "query_" contains non-main DICOM tags! | |
569 | |
570 // TODO - configuration option | |
571 bool findFromDatabase; | |
572 | |
573 { | |
574 // New configuration option in 1.5.1 | |
575 OrthancConfiguration::ReaderLock lock; | |
576 findFromDatabase = lock.GetConfiguration().GetUnsignedIntegerParameter("FindFromDatabase", false); | |
577 } | |
578 | |
579 return !sequencesToReturn_.empty(); | |
580 #endif | |
581 } | |
549 | 582 |
550 virtual void MarkAsComplete() | 583 virtual void MarkAsComplete() |
551 { | 584 { |
552 answers_.SetComplete(true); | 585 answers_.SetComplete(true); |
553 } | 586 } |
554 | 587 |
555 virtual void Visit(const std::string& publicId, | 588 virtual void Visit(const std::string& publicId, |
556 const std::string& instanceId, | 589 const std::string& instanceId, |
557 const Json::Value& dicom) | 590 const DicomMap& mainDicomTags, |
591 const Json::Value* dicomAsJson) | |
558 { | 592 { |
559 std::auto_ptr<DicomMap> counters(ComputeCounters(context_, instanceId, level_, filteredInput_)); | 593 std::auto_ptr<DicomMap> counters(ComputeCounters(context_, instanceId, level_, filteredInput_)); |
560 AddAnswer(answers_, dicom, query_, sequencesToReturn_, counters.get()); | 594 AddAnswer(answers_, mainDicomTags, dicomAsJson, query_, sequencesToReturn_, counters.get()); |
561 } | 595 } |
562 }; | 596 }; |
563 | 597 |
564 | 598 |
565 void OrthancFindRequestHandler::Handle(DicomFindAnswers& answers, | 599 void OrthancFindRequestHandler::Handle(DicomFindAnswers& answers, |
688 * Run the query. | 722 * Run the query. |
689 **/ | 723 **/ |
690 | 724 |
691 size_t limit = (level == ResourceType_Instance) ? maxInstances_ : maxResults_; | 725 size_t limit = (level == ResourceType_Instance) ? maxInstances_ : maxResults_; |
692 | 726 |
727 | |
693 LookupVisitor visitor(answers, context_, level, *filteredInput, sequencesToReturn); | 728 LookupVisitor visitor(answers, context_, level, *filteredInput, sequencesToReturn); |
694 context_.Apply(visitor, lookup, 0 /* "since" is not relevant to C-FIND */, limit); | 729 context_.Apply(visitor, lookup, 0 /* "since" is not relevant to C-FIND */, limit); |
695 } | 730 } |
696 | 731 |
697 | 732 |