comparison Resources/Graveyard/DatabaseOptimizations/LookupIdentifierQuery.cpp @ 3036:8fd203510d8b db-changes

moving LookupIdentifierQuery to the graveyard
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 19 Dec 2018 16:27:07 +0100
parents OrthancServer/Search/LookupIdentifierQuery.cpp@7695a9c81099
children ce272138f15e
comparison
equal deleted inserted replaced
3034:54e422fe31ce 3036:8fd203510d8b
1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2018 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
11 *
12 * In addition, as a special exception, the copyright holders of this
13 * program give permission to link the code of its release with the
14 * OpenSSL project's "OpenSSL" library (or with modified versions of it
15 * that use the same license as the "OpenSSL" library), and distribute
16 * the linked executables. You must obey the GNU General Public License
17 * in all respects for all of the code used other than "OpenSSL". If you
18 * modify file(s) with this exception, you may extend this exception to
19 * your version of the file(s), but you are not obligated to do so. If
20 * you do not wish to do so, delete this exception statement from your
21 * version. If you delete this exception statement from all source files
22 * in the program, then also delete it here.
23 *
24 * This program is distributed in the hope that it will be useful, but
25 * WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program. If not, see <http://www.gnu.org/licenses/>.
31 **/
32
33
34 #include "../PrecompiledHeadersServer.h"
35 #include "LookupIdentifierQuery.h"
36
37 #include "../../Core/DicomParsing/FromDcmtkBridge.h"
38 #include "../../Core/OrthancException.h"
39 #include "../ServerToolbox.h"
40 #include "SetOfResources.h"
41
42 #include <cassert>
43
44
45
46 namespace Orthanc
47 {
48 LookupIdentifierQuery::SingleConstraint::
49 SingleConstraint(const DicomTag& tag,
50 IdentifierConstraintType type,
51 const std::string& value) :
52 tag_(tag),
53 type_(type),
54 value_(ServerToolbox::NormalizeIdentifier(value))
55 {
56 }
57
58
59 LookupIdentifierQuery::RangeConstraint::
60 RangeConstraint(const DicomTag& tag,
61 const std::string& start,
62 const std::string& end) :
63 tag_(tag),
64 start_(ServerToolbox::NormalizeIdentifier(start)),
65 end_(ServerToolbox::NormalizeIdentifier(end))
66 {
67 }
68
69
70 LookupIdentifierQuery::Disjunction::~Disjunction()
71 {
72 for (size_t i = 0; i < singleConstraints_.size(); i++)
73 {
74 delete singleConstraints_[i];
75 }
76
77 for (size_t i = 0; i < rangeConstraints_.size(); i++)
78 {
79 delete rangeConstraints_[i];
80 }
81 }
82
83
84 void LookupIdentifierQuery::Disjunction::Add(const DicomTag& tag,
85 IdentifierConstraintType type,
86 const std::string& value)
87 {
88 singleConstraints_.push_back(new SingleConstraint(tag, type, value));
89 }
90
91
92 void LookupIdentifierQuery::Disjunction::AddRange(const DicomTag& tag,
93 const std::string& start,
94 const std::string& end)
95 {
96 rangeConstraints_.push_back(new RangeConstraint(tag, start, end));
97 }
98
99
100 LookupIdentifierQuery::~LookupIdentifierQuery()
101 {
102 for (Disjunctions::iterator it = disjunctions_.begin();
103 it != disjunctions_.end(); ++it)
104 {
105 delete *it;
106 }
107 }
108
109
110 bool LookupIdentifierQuery::IsIdentifier(const DicomTag& tag)
111 {
112 return ServerToolbox::IsIdentifier(tag, level_);
113 }
114
115
116 void LookupIdentifierQuery::AddConstraint(DicomTag tag,
117 IdentifierConstraintType type,
118 const std::string& value)
119 {
120 assert(IsIdentifier(tag));
121 disjunctions_.push_back(new Disjunction);
122 disjunctions_.back()->Add(tag, type, value);
123 }
124
125
126 void LookupIdentifierQuery::AddRange(DicomTag tag,
127 const std::string& start,
128 const std::string& end)
129 {
130 assert(IsIdentifier(tag));
131 disjunctions_.push_back(new Disjunction);
132 disjunctions_.back()->AddRange(tag, start, end);
133 }
134
135
136 LookupIdentifierQuery::Disjunction& LookupIdentifierQuery::AddDisjunction()
137 {
138 disjunctions_.push_back(new Disjunction);
139 return *disjunctions_.back();
140 }
141
142
143 void LookupIdentifierQuery::Apply(std::list<std::string>& result,
144 IDatabaseWrapper& database)
145 {
146 SetOfResources resources(database, level_);
147 Apply(resources, database);
148
149 resources.Flatten(result);
150 }
151
152
153 void LookupIdentifierQuery::Apply(SetOfResources& result,
154 IDatabaseWrapper& database)
155 {
156 for (size_t i = 0; i < disjunctions_.size(); i++)
157 {
158 std::list<int64_t> a;
159
160 for (size_t j = 0; j < disjunctions_[i]->GetSingleConstraintsCount(); j++)
161 {
162 const SingleConstraint& constraint = disjunctions_[i]->GetSingleConstraint(j);
163 std::list<int64_t> b;
164 database.LookupIdentifier(b, level_, constraint.GetTag(),
165 constraint.GetType(), constraint.GetValue());
166
167 a.splice(a.end(), b);
168 }
169
170 for (size_t j = 0; j < disjunctions_[i]->GetRangeConstraintsCount(); j++)
171 {
172 const RangeConstraint& constraint = disjunctions_[i]->GetRangeConstraint(j);
173 std::list<int64_t> b;
174 database.LookupIdentifierRange(b, level_, constraint.GetTag(),
175 constraint.GetStart(), constraint.GetEnd());
176
177 a.splice(a.end(), b);
178 }
179
180 result.Intersect(a);
181 }
182 }
183
184
185 void LookupIdentifierQuery::Print(std::ostream& s) const
186 {
187 s << "Constraint: " << std::endl;
188 for (Disjunctions::const_iterator
189 it = disjunctions_.begin(); it != disjunctions_.end(); ++it)
190 {
191 if (it == disjunctions_.begin())
192 s << " ";
193 else
194 s << "OR ";
195
196 for (size_t j = 0; j < (*it)->GetSingleConstraintsCount(); j++)
197 {
198 const SingleConstraint& c = (*it)->GetSingleConstraint(j);
199 s << FromDcmtkBridge::GetTagName(c.GetTag(), "");
200
201 switch (c.GetType())
202 {
203 case IdentifierConstraintType_Equal: s << " == "; break;
204 case IdentifierConstraintType_SmallerOrEqual: s << " <= "; break;
205 case IdentifierConstraintType_GreaterOrEqual: s << " >= "; break;
206 case IdentifierConstraintType_Wildcard: s << " ~= "; break;
207 default:
208 s << " ? ";
209 }
210
211 s << c.GetValue() << std::endl;
212 }
213 }
214 }
215 }