comparison OrthancServer/Search/LookupIdentifierQuery.cpp @ 2697:e583478e0c6c jobs

New primitive in database SDK: "lookupIdentifierRange" to speed up range searches
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 03 Jul 2018 15:59:17 +0200
parents 1b736d151ea1
children 7695a9c81099
comparison
equal deleted inserted replaced
2696:1b736d151ea1 2697:e583478e0c6c
44 44
45 namespace Orthanc 45 namespace Orthanc
46 { 46 {
47 LookupIdentifierQuery::Disjunction::~Disjunction() 47 LookupIdentifierQuery::Disjunction::~Disjunction()
48 { 48 {
49 for (size_t i = 0; i < constraints_.size(); i++) 49 for (size_t i = 0; i < singleConstraints_.size(); i++)
50 { 50 {
51 delete constraints_[i]; 51 delete singleConstraints_[i];
52 }
53
54 for (size_t i = 0; i < rangeConstraints_.size(); i++)
55 {
56 delete rangeConstraints_[i];
52 } 57 }
53 } 58 }
54 59
55 60
56 void LookupIdentifierQuery::Disjunction::Add(const DicomTag& tag, 61 void LookupIdentifierQuery::Disjunction::Add(const DicomTag& tag,
57 IdentifierConstraintType type, 62 IdentifierConstraintType type,
58 const std::string& value) 63 const std::string& value)
59 { 64 {
60 constraints_.push_back(new Constraint(tag, type, value)); 65 singleConstraints_.push_back(new SingleConstraint(tag, type, value));
66 }
67
68
69 void LookupIdentifierQuery::Disjunction::AddRange(const DicomTag& tag,
70 const std::string& start,
71 const std::string& end)
72 {
73 rangeConstraints_.push_back(new RangeConstraint(tag, start, end));
61 } 74 }
62 75
63 76
64 LookupIdentifierQuery::~LookupIdentifierQuery() 77 LookupIdentifierQuery::~LookupIdentifierQuery()
65 { 78 {
66 for (Disjuntions::iterator it = disjuntions_.begin(); 79 for (Disjunctions::iterator it = disjunctions_.begin();
67 it != disjuntions_.end(); ++it) 80 it != disjunctions_.end(); ++it)
68 { 81 {
69 delete *it; 82 delete *it;
70 } 83 }
71 } 84 }
72 85
74 void LookupIdentifierQuery::AddConstraint(DicomTag tag, 87 void LookupIdentifierQuery::AddConstraint(DicomTag tag,
75 IdentifierConstraintType type, 88 IdentifierConstraintType type,
76 const std::string& value) 89 const std::string& value)
77 { 90 {
78 assert(IsIdentifier(tag)); 91 assert(IsIdentifier(tag));
79 disjuntions_.push_back(new Disjunction); 92 disjunctions_.push_back(new Disjunction);
80 disjuntions_.back()->Add(tag, type, value); 93 disjunctions_.back()->Add(tag, type, value);
94 }
95
96
97 void LookupIdentifierQuery::AddRange(DicomTag tag,
98 const std::string& start,
99 const std::string& end)
100 {
101 assert(IsIdentifier(tag));
102 disjunctions_.push_back(new Disjunction);
103 disjunctions_.back()->AddRange(tag, start, end);
81 } 104 }
82 105
83 106
84 LookupIdentifierQuery::Disjunction& LookupIdentifierQuery::AddDisjunction() 107 LookupIdentifierQuery::Disjunction& LookupIdentifierQuery::AddDisjunction()
85 { 108 {
86 disjuntions_.push_back(new Disjunction); 109 disjunctions_.push_back(new Disjunction);
87 return *disjuntions_.back(); 110 return *disjunctions_.back();
88 } 111 }
89 112
90 113
91 void LookupIdentifierQuery::Apply(std::list<std::string>& result, 114 void LookupIdentifierQuery::Apply(std::list<std::string>& result,
92 IDatabaseWrapper& database) 115 IDatabaseWrapper& database)
99 122
100 123
101 void LookupIdentifierQuery::Apply(SetOfResources& result, 124 void LookupIdentifierQuery::Apply(SetOfResources& result,
102 IDatabaseWrapper& database) 125 IDatabaseWrapper& database)
103 { 126 {
104 for (size_t i = 0; i < GetSize(); i++) 127 for (size_t i = 0; i < disjunctions_.size(); i++)
105 { 128 {
106 std::list<int64_t> a; 129 std::list<int64_t> a;
107 130
108 for (size_t j = 0; j < disjuntions_[i]->GetSize(); j++) 131 for (size_t j = 0; j < disjunctions_[i]->GetSingleConstraintsCount(); j++)
109 { 132 {
110 const Constraint& constraint = disjuntions_[i]->GetConstraint(j); 133 const SingleConstraint& constraint = disjunctions_[i]->GetSingleConstraint(j);
111 std::list<int64_t> b; 134 std::list<int64_t> b;
112 database.LookupIdentifier(b, level_, constraint.GetTag(), constraint.GetType(), constraint.GetValue()); 135 database.LookupIdentifier(b, level_, constraint.GetTag(),
136 constraint.GetType(), constraint.GetValue());
137
138 a.splice(a.end(), b);
139 }
140
141 for (size_t j = 0; j < disjunctions_[i]->GetRangeConstraintsCount(); j++)
142 {
143 const RangeConstraint& constraint = disjunctions_[i]->GetRangeConstraint(j);
144 std::list<int64_t> b;
145 database.LookupIdentifierRange(b, level_, constraint.GetTag(),
146 constraint.GetStart(), constraint.GetEnd());
113 147
114 a.splice(a.end(), b); 148 a.splice(a.end(), b);
115 } 149 }
116 150
117 result.Intersect(a); 151 result.Intersect(a);
120 154
121 155
122 void LookupIdentifierQuery::Print(std::ostream& s) const 156 void LookupIdentifierQuery::Print(std::ostream& s) const
123 { 157 {
124 s << "Constraint: " << std::endl; 158 s << "Constraint: " << std::endl;
125 for (Disjuntions::const_iterator 159 for (Disjunctions::const_iterator
126 it = disjuntions_.begin(); it != disjuntions_.end(); ++it) 160 it = disjunctions_.begin(); it != disjunctions_.end(); ++it)
127 { 161 {
128 if (it == disjuntions_.begin()) 162 if (it == disjunctions_.begin())
129 s << " "; 163 s << " ";
130 else 164 else
131 s << "OR "; 165 s << "OR ";
132 166
133 for (size_t j = 0; j < (*it)->GetSize(); j++) 167 for (size_t j = 0; j < (*it)->GetSingleConstraintsCount(); j++)
134 { 168 {
135 const Constraint& c = (*it)->GetConstraint(j); 169 const SingleConstraint& c = (*it)->GetSingleConstraint(j);
136 s << FromDcmtkBridge::GetTagName(c.GetTag(), ""); 170 s << FromDcmtkBridge::GetTagName(c.GetTag(), "");
137 171
138 switch (c.GetType()) 172 switch (c.GetType())
139 { 173 {
140 case IdentifierConstraintType_Equal: s << " == "; break; 174 case IdentifierConstraintType_Equal: s << " == "; break;