Mercurial > hg > orthanc
diff 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 |
line wrap: on
line diff
--- a/OrthancServer/ServerContext.cpp Thu Dec 13 17:58:27 2018 +0100 +++ b/OrthancServer/ServerContext.cpp Fri Dec 14 12:10:03 2018 +0100 @@ -778,6 +778,35 @@ size_t since, size_t limit) { + LookupMode mode; + + { + // New configuration option in 1.5.1 + OrthancConfiguration::ReaderLock lock; + + std::string value = lock.GetConfiguration().GetStringParameter("StorageAccessOnFind", "Always"); + + if (value == "Always") + { + mode = LookupMode_DiskOnLookupAndAnswer; + } + else if (value == "Never") + { + mode = LookupMode_DatabaseOnly; + } + else if (value == "Answers") + { + mode = LookupMode_DiskOnAnswer; + } + else + { + throw OrthancException(ErrorCode_ParameterOutOfRange, + "Configuration option \"StorageAccessOnFind\" " + "should be \"Always\", \"Never\" or \"Answers\": " + value); + } + } + + std::vector<std::string> resources, instances; GetIndex().FindCandidates(resources, instances, lookup); @@ -788,6 +817,8 @@ size_t countResults = 0; size_t skipped = 0; bool complete = true; + + const bool isDicomAsJsonNeeded = visitor.IsDicomAsJsonNeeded(); for (size_t i = 0; i < instances.size(); i++) { @@ -799,11 +830,20 @@ bool hasOnlyMainDicomTags; DicomMap dicom; - if (lookup.HasOnlyMainDicomTags() && - GetIndex().GetAllMainDicomTags(dicom, instances[i])) + if (mode == LookupMode_DatabaseOnly || + mode == LookupMode_DiskOnAnswer || + lookup.HasOnlyMainDicomTags()) { // Case (1): The main DICOM tags, as stored in the database, // are sufficient to look for match + + if (!GetIndex().GetAllMainDicomTags(dicom, instances[i])) + { + // The instance has been removed during the execution of the + // lookup, ignore it + continue; + } + hasOnlyMainDicomTags = true; } else @@ -834,8 +874,10 @@ } else { - if (dicomAsJson.get() == NULL && - visitor.IsDicomAsJsonNeeded()) + if ((mode == LookupMode_DiskOnLookupAndAnswer || + mode == LookupMode_DiskOnAnswer) && + dicomAsJson.get() == NULL && + isDicomAsJsonNeeded) { dicomAsJson.reset(new Json::Value); ReadDicomAsJson(*dicomAsJson, instances[i]); @@ -870,6 +912,77 @@ } + bool ServerContext::LookupOrReconstructMetadata(std::string& target, + const std::string& publicId, + MetadataType metadata) + { + // This is a backwards-compatibility function, that can + // reconstruct metadata that were not generated by an older + // release of Orthanc + + if (metadata == MetadataType_Instance_SopClassUid || + metadata == MetadataType_Instance_TransferSyntax) + { + if (index_.LookupMetadata(target, publicId, metadata)) + { + return true; + } + else + { + // These metadata are mandatory in DICOM instances, and were + // introduced in Orthanc 1.2.0. The fact that + // "LookupMetadata()" has failed indicates that this database + // comes from an older release of Orthanc. + + DicomTag tag(0, 0); + + switch (metadata) + { + case MetadataType_Instance_SopClassUid: + tag = DICOM_TAG_SOP_CLASS_UID; + break; + + case MetadataType_Instance_TransferSyntax: + tag = DICOM_TAG_TRANSFER_SYNTAX_UID; + break; + + default: + throw OrthancException(ErrorCode_InternalError); + } + + Json::Value dicomAsJson; + ReadDicomAsJson(dicomAsJson, publicId); + + DicomMap tags; + tags.FromDicomAsJson(dicomAsJson); + + const DicomValue* value = tags.TestAndGetValue(tag); + + if (value != NULL && + !value->IsNull() && + !value->IsBinary()) + { + target = value->GetContent(); + + // Store for reuse + index_.SetMetadata(publicId, metadata, target); + return true; + } + else + { + // Should never happen + return false; + } + } + } + else + { + // No backward + return index_.LookupMetadata(target, publicId, metadata); + } + } + + void ServerContext::AddChildInstances(SetOfInstancesJob& job, const std::string& publicId) {