Mercurial > hg > orthanc
comparison OrthancServer/ServerContext.cpp @ 3015:abe49ca61cd5
On C-FIND, avoid accessing the storage area whenever possible
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 14 Dec 2018 12:10:03 +0100 |
parents | af1530b45290 |
children | 2cbafb5d5a62 |
comparison
equal
deleted
inserted
replaced
3014:b9f0b0c0b36f | 3015:abe49ca61cd5 |
---|---|
776 void ServerContext::Apply(LookupResource::IVisitor& visitor, | 776 void ServerContext::Apply(LookupResource::IVisitor& visitor, |
777 const ::Orthanc::LookupResource& lookup, | 777 const ::Orthanc::LookupResource& lookup, |
778 size_t since, | 778 size_t since, |
779 size_t limit) | 779 size_t limit) |
780 { | 780 { |
781 LookupMode mode; | |
782 | |
783 { | |
784 // New configuration option in 1.5.1 | |
785 OrthancConfiguration::ReaderLock lock; | |
786 | |
787 std::string value = lock.GetConfiguration().GetStringParameter("StorageAccessOnFind", "Always"); | |
788 | |
789 if (value == "Always") | |
790 { | |
791 mode = LookupMode_DiskOnLookupAndAnswer; | |
792 } | |
793 else if (value == "Never") | |
794 { | |
795 mode = LookupMode_DatabaseOnly; | |
796 } | |
797 else if (value == "Answers") | |
798 { | |
799 mode = LookupMode_DiskOnAnswer; | |
800 } | |
801 else | |
802 { | |
803 throw OrthancException(ErrorCode_ParameterOutOfRange, | |
804 "Configuration option \"StorageAccessOnFind\" " | |
805 "should be \"Always\", \"Never\" or \"Answers\": " + value); | |
806 } | |
807 } | |
808 | |
809 | |
781 std::vector<std::string> resources, instances; | 810 std::vector<std::string> resources, instances; |
782 GetIndex().FindCandidates(resources, instances, lookup); | 811 GetIndex().FindCandidates(resources, instances, lookup); |
783 | 812 |
784 LOG(INFO) << "Number of candidate resources after fast DB filtering on main DICOM tags: " << resources.size(); | 813 LOG(INFO) << "Number of candidate resources after fast DB filtering on main DICOM tags: " << resources.size(); |
785 | 814 |
786 assert(resources.size() == instances.size()); | 815 assert(resources.size() == instances.size()); |
787 | 816 |
788 size_t countResults = 0; | 817 size_t countResults = 0; |
789 size_t skipped = 0; | 818 size_t skipped = 0; |
790 bool complete = true; | 819 bool complete = true; |
820 | |
821 const bool isDicomAsJsonNeeded = visitor.IsDicomAsJsonNeeded(); | |
791 | 822 |
792 for (size_t i = 0; i < instances.size(); i++) | 823 for (size_t i = 0; i < instances.size(); i++) |
793 { | 824 { |
794 // Optimization in Orthanc 1.5.1 - Don't read the full JSON from | 825 // Optimization in Orthanc 1.5.1 - Don't read the full JSON from |
795 // the disk if only "main DICOM tags" are to be returned | 826 // the disk if only "main DICOM tags" are to be returned |
797 std::auto_ptr<Json::Value> dicomAsJson; | 828 std::auto_ptr<Json::Value> dicomAsJson; |
798 | 829 |
799 bool hasOnlyMainDicomTags; | 830 bool hasOnlyMainDicomTags; |
800 DicomMap dicom; | 831 DicomMap dicom; |
801 | 832 |
802 if (lookup.HasOnlyMainDicomTags() && | 833 if (mode == LookupMode_DatabaseOnly || |
803 GetIndex().GetAllMainDicomTags(dicom, instances[i])) | 834 mode == LookupMode_DiskOnAnswer || |
835 lookup.HasOnlyMainDicomTags()) | |
804 { | 836 { |
805 // Case (1): The main DICOM tags, as stored in the database, | 837 // Case (1): The main DICOM tags, as stored in the database, |
806 // are sufficient to look for match | 838 // are sufficient to look for match |
839 | |
840 if (!GetIndex().GetAllMainDicomTags(dicom, instances[i])) | |
841 { | |
842 // The instance has been removed during the execution of the | |
843 // lookup, ignore it | |
844 continue; | |
845 } | |
846 | |
807 hasOnlyMainDicomTags = true; | 847 hasOnlyMainDicomTags = true; |
808 } | 848 } |
809 else | 849 else |
810 { | 850 { |
811 // Case (2): Need to read the "DICOM-as-JSON" attachment from | 851 // Case (2): Need to read the "DICOM-as-JSON" attachment from |
832 complete = false; | 872 complete = false; |
833 break; | 873 break; |
834 } | 874 } |
835 else | 875 else |
836 { | 876 { |
837 if (dicomAsJson.get() == NULL && | 877 if ((mode == LookupMode_DiskOnLookupAndAnswer || |
838 visitor.IsDicomAsJsonNeeded()) | 878 mode == LookupMode_DiskOnAnswer) && |
879 dicomAsJson.get() == NULL && | |
880 isDicomAsJsonNeeded) | |
839 { | 881 { |
840 dicomAsJson.reset(new Json::Value); | 882 dicomAsJson.reset(new Json::Value); |
841 ReadDicomAsJson(*dicomAsJson, instances[i]); | 883 ReadDicomAsJson(*dicomAsJson, instances[i]); |
842 } | 884 } |
843 | 885 |
868 | 910 |
869 LOG(INFO) << "Number of matching resources: " << countResults; | 911 LOG(INFO) << "Number of matching resources: " << countResults; |
870 } | 912 } |
871 | 913 |
872 | 914 |
915 bool ServerContext::LookupOrReconstructMetadata(std::string& target, | |
916 const std::string& publicId, | |
917 MetadataType metadata) | |
918 { | |
919 // This is a backwards-compatibility function, that can | |
920 // reconstruct metadata that were not generated by an older | |
921 // release of Orthanc | |
922 | |
923 if (metadata == MetadataType_Instance_SopClassUid || | |
924 metadata == MetadataType_Instance_TransferSyntax) | |
925 { | |
926 if (index_.LookupMetadata(target, publicId, metadata)) | |
927 { | |
928 return true; | |
929 } | |
930 else | |
931 { | |
932 // These metadata are mandatory in DICOM instances, and were | |
933 // introduced in Orthanc 1.2.0. The fact that | |
934 // "LookupMetadata()" has failed indicates that this database | |
935 // comes from an older release of Orthanc. | |
936 | |
937 DicomTag tag(0, 0); | |
938 | |
939 switch (metadata) | |
940 { | |
941 case MetadataType_Instance_SopClassUid: | |
942 tag = DICOM_TAG_SOP_CLASS_UID; | |
943 break; | |
944 | |
945 case MetadataType_Instance_TransferSyntax: | |
946 tag = DICOM_TAG_TRANSFER_SYNTAX_UID; | |
947 break; | |
948 | |
949 default: | |
950 throw OrthancException(ErrorCode_InternalError); | |
951 } | |
952 | |
953 Json::Value dicomAsJson; | |
954 ReadDicomAsJson(dicomAsJson, publicId); | |
955 | |
956 DicomMap tags; | |
957 tags.FromDicomAsJson(dicomAsJson); | |
958 | |
959 const DicomValue* value = tags.TestAndGetValue(tag); | |
960 | |
961 if (value != NULL && | |
962 !value->IsNull() && | |
963 !value->IsBinary()) | |
964 { | |
965 target = value->GetContent(); | |
966 | |
967 // Store for reuse | |
968 index_.SetMetadata(publicId, metadata, target); | |
969 return true; | |
970 } | |
971 else | |
972 { | |
973 // Should never happen | |
974 return false; | |
975 } | |
976 } | |
977 } | |
978 else | |
979 { | |
980 // No backward | |
981 return index_.LookupMetadata(target, publicId, metadata); | |
982 } | |
983 } | |
984 | |
985 | |
873 void ServerContext::AddChildInstances(SetOfInstancesJob& job, | 986 void ServerContext::AddChildInstances(SetOfInstancesJob& job, |
874 const std::string& publicId) | 987 const std::string& publicId) |
875 { | 988 { |
876 std::list<std::string> instances; | 989 std::list<std::string> instances; |
877 GetIndex().GetChildInstances(instances, publicId); | 990 GetIndex().GetChildInstances(instances, publicId); |