comparison OrthancServer/Search/DatabaseLookup.cpp @ 3025:039a9d262d64 db-changes

preparing to speed up find in databases
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 17 Dec 2018 17:05:28 +0100
parents 1723cbba55c7
children fd587cf51a89
comparison
equal deleted inserted replaced
3024:ef17a587e10d 3025:039a9d262d64
37 #include "../ServerToolbox.h" 37 #include "../ServerToolbox.h"
38 #include "../../Core/DicomParsing/FromDcmtkBridge.h" 38 #include "../../Core/DicomParsing/FromDcmtkBridge.h"
39 39
40 namespace Orthanc 40 namespace Orthanc
41 { 41 {
42 void DatabaseLookup::LoadTags(ResourceType level)
43 {
44 const DicomTag* tags = NULL;
45 size_t size;
46
47 ServerToolbox::LoadIdentifiers(tags, size, level);
48
49 for (size_t i = 0; i < size; i++)
50 {
51 if (tags_.find(tags[i]) == tags_.end())
52 {
53 tags_[tags[i]] = TagInfo(DicomTagType_Identifier, level);
54 }
55 else
56 {
57 // These patient-level tags are copied in the study level
58 assert(level == ResourceType_Study &&
59 (tags[i] == DICOM_TAG_PATIENT_ID ||
60 tags[i] == DICOM_TAG_PATIENT_NAME ||
61 tags[i] == DICOM_TAG_PATIENT_BIRTH_DATE));
62 }
63 }
64
65 DicomMap::LoadMainDicomTags(tags, size, level);
66
67 for (size_t i = 0; i < size; i++)
68 {
69 if (tags_.find(tags[i]) == tags_.end())
70 {
71 tags_[tags[i]] = TagInfo(DicomTagType_Main, level);
72 }
73 }
74 }
75
76
77 DatabaseLookup::DatabaseLookup()
78 {
79 LoadTags(ResourceType_Patient);
80 LoadTags(ResourceType_Study);
81 LoadTags(ResourceType_Series);
82 LoadTags(ResourceType_Instance);
83 }
84
85
86 DatabaseLookup::~DatabaseLookup() 42 DatabaseLookup::~DatabaseLookup()
87 { 43 {
88 for (size_t i = 0; i < constraints_.size(); i++) 44 for (size_t i = 0; i < constraints_.size(); i++)
89 { 45 {
90 assert(constraints_[i] != NULL); 46 assert(constraints_[i] != NULL);
114 throw OrthancException(ErrorCode_NullPointer); 70 throw OrthancException(ErrorCode_NullPointer);
115 } 71 }
116 else 72 else
117 { 73 {
118 constraints_.push_back(constraint); 74 constraints_.push_back(constraint);
119
120 std::map<DicomTag, TagInfo>::const_iterator tag = tags_.find(constraint->GetTag());
121
122 if (tag == tags_.end())
123 {
124 constraint->SetTagInfo(DicomTagType_Generic, ResourceType_Instance);
125 }
126 else
127 {
128 constraint->SetTagInfo(tag->second.GetType(), tag->second.GetLevel());
129 }
130 } 75 }
131 } 76 }
132 77
133 78
134 bool DatabaseLookup::IsMatch(const DicomMap& value) 79 bool DatabaseLookup::IsMatch(const DicomMap& value)
146 } 91 }
147 92
148 93
149 void DatabaseLookup::AddDicomConstraint(const DicomTag& tag, 94 void DatabaseLookup::AddDicomConstraint(const DicomTag& tag,
150 const std::string& dicomQuery, 95 const std::string& dicomQuery,
151 bool caseSensitivePN) 96 bool caseSensitivePN,
97 bool mandatoryTag)
152 { 98 {
153 ValueRepresentation vr = FromDcmtkBridge::LookupValueRepresentation(tag); 99 ValueRepresentation vr = FromDcmtkBridge::LookupValueRepresentation(tag);
154 100
155 if (vr == ValueRepresentation_Sequence) 101 if (vr == ValueRepresentation_Sequence)
156 { 102 {
212 std::string upper = dicomQuery.substr(separator + 1); 158 std::string upper = dicomQuery.substr(separator + 1);
213 159
214 if (!lower.empty()) 160 if (!lower.empty())
215 { 161 {
216 AddConstraint(new DicomTagConstraint 162 AddConstraint(new DicomTagConstraint
217 (tag, ConstraintType_GreaterOrEqual, lower, caseSensitive)); 163 (tag, ConstraintType_GreaterOrEqual, lower, caseSensitive, mandatoryTag));
218 } 164 }
219 165
220 if (!upper.empty()) 166 if (!upper.empty())
221 { 167 {
222 AddConstraint(new DicomTagConstraint 168 AddConstraint(new DicomTagConstraint
223 (tag, ConstraintType_SmallerOrEqual, upper, caseSensitive)); 169 (tag, ConstraintType_SmallerOrEqual, upper, caseSensitive, mandatoryTag));
224 } 170 }
225 } 171 }
226 else if (dicomQuery.find('\\') != std::string::npos) 172 else if (dicomQuery.find('\\') != std::string::npos)
227 { 173 {
228 DicomTag fixedTag(tag); 174 DicomTag fixedTag(tag);
233 // http://dicomiseasy.blogspot.be/2012/01/dicom-queryretrieve-part-i.html 179 // http://dicomiseasy.blogspot.be/2012/01/dicom-queryretrieve-part-i.html
234 fixedTag = DICOM_TAG_MODALITY; 180 fixedTag = DICOM_TAG_MODALITY;
235 } 181 }
236 182
237 std::auto_ptr<DicomTagConstraint> constraint 183 std::auto_ptr<DicomTagConstraint> constraint
238 (new DicomTagConstraint(fixedTag, ConstraintType_List, caseSensitive)); 184 (new DicomTagConstraint(fixedTag, ConstraintType_List, caseSensitive, mandatoryTag));
239 185
240 std::vector<std::string> items; 186 std::vector<std::string> items;
241 Toolbox::TokenizeString(items, dicomQuery, '\\'); 187 Toolbox::TokenizeString(items, dicomQuery, '\\');
242 188
243 for (size_t i = 0; i < items.size(); i++) 189 for (size_t i = 0; i < items.size(); i++)
249 } 195 }
250 else if (dicomQuery.find('*') != std::string::npos || 196 else if (dicomQuery.find('*') != std::string::npos ||
251 dicomQuery.find('?') != std::string::npos) 197 dicomQuery.find('?') != std::string::npos)
252 { 198 {
253 AddConstraint(new DicomTagConstraint 199 AddConstraint(new DicomTagConstraint
254 (tag, ConstraintType_Wildcard, dicomQuery, caseSensitive)); 200 (tag, ConstraintType_Wildcard, dicomQuery, caseSensitive, mandatoryTag));
255 } 201 }
256 else 202 else
257 { 203 {
258 AddConstraint(new DicomTagConstraint 204 AddConstraint(new DicomTagConstraint
259 (tag, ConstraintType_Equal, dicomQuery, caseSensitive)); 205 (tag, ConstraintType_Equal, dicomQuery, caseSensitive, mandatoryTag));
260 } 206 }
261 } 207 }
262 } 208 }