Skip to content

Commit 1741811

Browse files
committed
DPL: add support for DataDescriptorMatcher operator==
The final goal is to support changing InputRoute::matcher from a InputSpec to a DataDescriptorMatcher, always with the intent of supporting wildcards as inputs and sub-timeframe queries. This actual change is needed because DataSampling code has an hashmap with the InputSpec which would need to use DataDescriptorMatcher instead.
1 parent d906710 commit 1741811

File tree

2 files changed

+260
-36
lines changed

2 files changed

+260
-36
lines changed

Framework/Core/include/Framework/DataDescriptorMatcher.h

Lines changed: 168 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ struct None {
3232
/// A typesafe reference to an element of the context.
3333
struct ContextRef {
3434
size_t index;
35+
36+
bool operator==(ContextRef const& other) const
37+
{
38+
return index == other.index;
39+
}
3540
};
3641

3742
/// An element of the matching context. Context itself is really a vector of
@@ -43,23 +48,59 @@ struct ContextElement {
4348
std::variant<uint64_t, std::string, None> value; /// The actual contents of the element.
4449
};
4550

46-
/// Something which can be matched against a header::DataOrigin
47-
class OriginValueMatcher
51+
/// Can hold either an actual value of type T or a reference to
52+
/// a variable of the same type in the Context.
53+
template <typename T>
54+
class ValueHolder
4855
{
4956
public:
50-
/// Initialise the matcher with an actual value
51-
OriginValueMatcher(std::string const& s)
57+
ValueHolder(T const& s)
5258
: mValue{ s }
5359
{
5460
}
55-
5661
/// This means that the matcher will fill a variable in the context if
5762
/// the ref points to none or use the dereferenced value, if not.
58-
OriginValueMatcher(ContextRef variableId)
63+
ValueHolder(ContextRef variableId)
5964
: mValue{ variableId }
6065
{
6166
}
6267

68+
bool operator==(ValueHolder<T> const& other) const
69+
{
70+
auto s1 = std::get_if<T>(&mValue);
71+
auto s2 = std::get_if<T>(&other.mValue);
72+
73+
if (s1 && s2) {
74+
return *s1 == *s2;
75+
}
76+
77+
auto c1 = std::get_if<ContextRef>(&mValue);
78+
auto c2 = std::get_if<ContextRef>(&other.mValue);
79+
if (c1 && c2) {
80+
return *c1 == *c2;
81+
}
82+
83+
return false;
84+
}
85+
86+
protected:
87+
std::variant<T, ContextRef> mValue;
88+
};
89+
90+
/// Something which can be matched against a header::DataOrigin
91+
class OriginValueMatcher : public ValueHolder<std::string>
92+
{
93+
public:
94+
OriginValueMatcher(std::string const& s)
95+
: ValueHolder{ s }
96+
{
97+
}
98+
99+
OriginValueMatcher(ContextRef variableId)
100+
: ValueHolder{ variableId }
101+
{
102+
}
103+
63104
bool match(header::DataHeader const& header, std::vector<ContextElement>& context) const
64105
{
65106
if (auto ref = std::get_if<ContextRef>(&mValue)) {
@@ -75,24 +116,19 @@ class OriginValueMatcher
75116
}
76117
throw std::runtime_error("Mismatching type for variable");
77118
}
78-
79-
private:
80-
std::variant<std::string, ContextRef> mValue;
81119
};
82120

83121
/// Something which can be matched against a header::DataDescription
84-
class DescriptionValueMatcher
122+
class DescriptionValueMatcher : public ValueHolder<std::string>
85123
{
86124
public:
87125
DescriptionValueMatcher(std::string const& s)
88-
: mValue{ s }
126+
: ValueHolder{ s }
89127
{
90128
}
91129

92-
/// This means that the matcher will fill a variable in the context if
93-
/// the ref points to none or use the dereferenced value, if not.
94-
DescriptionValueMatcher(ContextRef ref)
95-
: mValue{ ref }
130+
DescriptionValueMatcher(ContextRef variableId)
131+
: ValueHolder{ variableId }
96132
{
97133
}
98134

@@ -106,37 +142,32 @@ class DescriptionValueMatcher
106142
auto maxSize = strnlen(header.dataDescription.str, 16);
107143
variable.value = std::string(header.dataDescription.str, maxSize);
108144
return true;
109-
} else if (auto s = std::get_if<std::string>(&mValue)) {
145+
} else if (auto s = std::get_if<std::string>(&this->mValue)) {
110146
return strncmp(header.dataDescription.str, s->c_str(), 16) == 0;
111147
}
112148
throw std::runtime_error("Mismatching type for variable");
113149
}
114-
115-
private:
116-
std::variant<std::string, ContextRef> mValue;
117150
};
118151

119152
/// Something which can be matched against a header::SubSpecificationType
120-
class SubSpecificationTypeValueMatcher
153+
class SubSpecificationTypeValueMatcher : public ValueHolder<uint64_t>
121154
{
122155
public:
156+
SubSpecificationTypeValueMatcher(ContextRef variableId)
157+
: ValueHolder{ variableId }
158+
{
159+
}
160+
123161
/// The passed string @a s is the expected numerical value for
124162
/// the SubSpecification type.
125163
SubSpecificationTypeValueMatcher(std::string const& s)
126-
: SubSpecificationTypeValueMatcher(strtoull(s.c_str(), nullptr, 10))
164+
: ValueHolder<uint64_t>{ strtoull(s.c_str(), nullptr, 10) }
127165
{
128166
}
129167

130168
/// This means that the matcher is looking for a constant.
131169
SubSpecificationTypeValueMatcher(uint64_t v)
132-
: mValue{ v }
133-
{
134-
}
135-
136-
/// This means that the matcher will fill a variable in the context if
137-
/// the ref points to none or use the dereferenced value, if not.
138-
SubSpecificationTypeValueMatcher(ContextRef ref)
139-
: mValue{ ref }
170+
: ValueHolder<uint64_t>{ v }
140171
{
141172
}
142173

@@ -154,9 +185,6 @@ class SubSpecificationTypeValueMatcher
154185
}
155186
throw std::runtime_error("Mismatching type for variable");
156187
}
157-
158-
private:
159-
std::variant<uint64_t, ContextRef> mValue;
160188
};
161189

162190
/// Something which can be matched against a header::SubSpecificationType
@@ -175,6 +203,11 @@ class ConstantValueMatcher
175203
return mValue;
176204
}
177205

206+
bool operator==(ConstantValueMatcher const& other) const
207+
{
208+
return mValue == other.mValue;
209+
}
210+
178211
private:
179212
bool mValue;
180213
};
@@ -217,9 +250,9 @@ class DataDescriptorMatcher
217250
/// contents mLeft and mRight into a new unique_ptr, if
218251
/// needed.
219252
DataDescriptorMatcher(DataDescriptorMatcher const& other)
220-
: mOp{other.mOp},
221-
mLeft{ConstantValueMatcher{false}},
222-
mRight{ConstantValueMatcher{false}}
253+
: mOp{ other.mOp },
254+
mLeft{ ConstantValueMatcher{ false } },
255+
mRight{ ConstantValueMatcher{ false } }
223256
{
224257
if (auto pval0 = std::get_if<OriginValueMatcher>(&other.mLeft)) {
225258
mLeft = *pval0;
@@ -346,6 +379,106 @@ class DataDescriptorMatcher
346379
}
347380
};
348381

382+
bool operator==(DataDescriptorMatcher const& other) const
383+
{
384+
if (mOp != this->mOp) {
385+
return false;
386+
}
387+
388+
bool leftValue = false;
389+
bool rightValue = false;
390+
391+
{
392+
auto v1 = std::get_if<OriginValueMatcher>(&this->mLeft);
393+
auto v2 = std::get_if<OriginValueMatcher>(&other.mLeft);
394+
if (v1 && v2 && *v1 == *v2) {
395+
leftValue = true;
396+
}
397+
}
398+
399+
{
400+
auto v1 = std::get_if<DescriptionValueMatcher>(&this->mLeft);
401+
auto v2 = std::get_if<DescriptionValueMatcher>(&other.mLeft);
402+
if (v1 && v2 && *v1 == *v2) {
403+
leftValue = true;
404+
}
405+
}
406+
407+
{
408+
auto v1 = std::get_if<SubSpecificationTypeValueMatcher>(&this->mLeft);
409+
auto v2 = std::get_if<SubSpecificationTypeValueMatcher>(&other.mLeft);
410+
if (v1 && v2 && *v1 == *v2) {
411+
leftValue = true;
412+
}
413+
}
414+
415+
{
416+
auto v1 = std::get_if<ConstantValueMatcher>(&this->mLeft);
417+
auto v2 = std::get_if<ConstantValueMatcher>(&other.mLeft);
418+
if (v1 && v2 && *v1 == *v2) {
419+
leftValue = true;
420+
}
421+
}
422+
423+
{
424+
auto v1 = std::get_if<std::unique_ptr<DataDescriptorMatcher>>(&this->mLeft);
425+
auto v2 = std::get_if<std::unique_ptr<DataDescriptorMatcher>>(&other.mLeft);
426+
if (v1 && v2 && v1->get() && v2->get() && (**v1 == **v2)) {
427+
leftValue = true;
428+
}
429+
}
430+
431+
// Shortcut the fact that the left side is different.
432+
if (leftValue == false) {
433+
return false;
434+
}
435+
436+
if (mOp == Op::Just) {
437+
return true;
438+
}
439+
440+
{
441+
auto v1 = std::get_if<OriginValueMatcher>(&this->mRight);
442+
auto v2 = std::get_if<OriginValueMatcher>(&other.mRight);
443+
if (v1 && v2 && *v1 == *v2) {
444+
return true;
445+
}
446+
}
447+
448+
{
449+
auto v1 = std::get_if<DescriptionValueMatcher>(&this->mRight);
450+
auto v2 = std::get_if<DescriptionValueMatcher>(&other.mRight);
451+
if (v1 && v2 && *v1 == *v2) {
452+
return true;
453+
}
454+
}
455+
456+
{
457+
auto v1 = std::get_if<SubSpecificationTypeValueMatcher>(&this->mRight);
458+
auto v2 = std::get_if<SubSpecificationTypeValueMatcher>(&other.mRight);
459+
if (v1 && v2 && *v1 == *v2) {
460+
return true;
461+
}
462+
}
463+
464+
{
465+
auto v1 = std::get_if<ConstantValueMatcher>(&this->mRight);
466+
auto v2 = std::get_if<ConstantValueMatcher>(&other.mRight);
467+
if (v1 && v2 && *v1 == *v2) {
468+
return true;
469+
}
470+
}
471+
472+
{
473+
auto v1 = std::get_if<std::unique_ptr<DataDescriptorMatcher>>(&this->mRight);
474+
auto v2 = std::get_if<std::unique_ptr<DataDescriptorMatcher>>(&other.mRight);
475+
if (v1 && v2 && v1->get() && v2->get() && (**v1 == **v2)) {
476+
return true;
477+
}
478+
}
479+
// We alredy know the left side is true.
480+
return false;
481+
}
349482
Node const& getLeft() const { return mLeft; };
350483
Node const& getRight() const { return mRight; };
351484
Op getOp() const { return mOp; };

0 commit comments

Comments
 (0)