22struct TopologyPolicyHelpers {
40 return spec.name ==
name;
47 const std::regex matcher(re);
50 return std::regex_match(spec.name.data(),
m, matcher);
58 for (
size_t ii = 0; ii <
a.inputs.size(); ++ii) {
59 for (
size_t oi = 0; oi <
b.outputs.size(); ++oi) {
77 auto checkSporadic = [](
InputSpec const& input) {
78 return input.lifetime == Lifetime::Sporadic;
80 bool isBWithSporadicInput = std::find_if(
b.inputs.begin(),
b.inputs.end(), checkSporadic) !=
b.inputs.end();
81 bool isAWithSporadicInput = std::find_if(
a.inputs.begin(),
a.inputs.end(), checkSporadic) !=
a.inputs.end();
83 if (!isAWithSporadicInput && !isBWithSporadicInput) {
87 if (isAWithSporadicInput && isBWithSporadicInput) {
93 if (isAWithSporadicInput) {
95 return !hasDependency;
105 O2_SIGNPOST_START(topology, sid,
"expendableDataDeps",
"Checking if %s depends on %s",
a.name.c_str(),
b.name.c_str());
106 if (
a.name.find(
"internal-dpl-injected-dummy-sink") != std::string::npos &&
107 b.name.find(
"internal-dpl-injected-dummy-sink") != std::string::npos) {
108 O2_SIGNPOST_END(topology, sid,
"expendableDataDeps",
"false. Dummy sink never depends on itself.");
112 if (
b.name.find(
"internal-dpl-injected-dummy-sink") != std::string::npos) {
113 O2_SIGNPOST_END(topology, sid,
"expendableDataDeps",
"false. %s is dummy sink and it nothing can depend on it.",
b.name.c_str());
116 if (
a.name.find(
"internal-dpl-injected-dummy-sink") != std::string::npos) {
117 O2_SIGNPOST_END(topology, sid,
"expendableDataDeps",
"true. %s is dummy sink and it nothing can depend on it.",
a.name.c_str());
122 O2_SIGNPOST_END(topology, sid,
"expendableDataDeps",
"true. %s has a data dependency on %s",
a.name.c_str(),
b.name.c_str());
129 if (
label.value ==
"expendable") {
136 if (
label.value ==
"resilient") {
142 bool isBExpendable = std::find_if(
b.labels.begin(),
b.labels.end(), checkExpendable) !=
b.labels.end();
143 bool isAExpendable = std::find_if(
a.labels.begin(),
a.labels.end(), checkExpendable) !=
a.labels.end();
144 bool bResilient = std::find_if(
b.labels.begin(),
b.labels.end(), checkResilient) !=
b.labels.end();
145 const std::regex matcher(
".*output-proxy.*");
147 bool isBOutputProxy = std::regex_match(
b.name.data(),
m, matcher);
150 if (!isAExpendable && !isBExpendable) {
152 if (sporadic && !isBOutputProxy) {
153 O2_SIGNPOST_END(topology, sid,
"expendableDataDeps",
"true. Neither %s nor %s are expendable. However the former has sporadic inputs so we sort it after.",
154 a.name.c_str(),
b.name.c_str());
157 O2_SIGNPOST_END(topology, sid,
"expendableDataDeps",
"false. Neither %s nor %s are expendable. No dependency beyond data deps.",
158 a.name.c_str(),
b.name.c_str());
162 if (isAExpendable && isBExpendable) {
164 if (sporadic && !isBOutputProxy) {
165 O2_SIGNPOST_END(topology, sid,
"expendableDataDeps",
"true. Both %s and %s are expendable. However the former has sporadic inputs, so we sort it after.",
166 a.name.c_str(),
b.name.c_str());
169 O2_SIGNPOST_END(topology, sid,
"expendableDataDeps",
"false. Both %s and %s are expendable. No dependency.",
170 a.name.c_str(),
b.name.c_str());
175 if (isAExpendable && bResilient) {
177 if (sporadic && !isBOutputProxy) {
178 O2_SIGNPOST_END(topology, sid,
"expendableDataDeps",
"true. %s is expendable but %s is resilient, however the former also has sporadic inputs, so we sort it after.",
179 a.name.c_str(),
b.name.c_str());
182 O2_SIGNPOST_END(topology, sid,
"expendableDataDeps",
"false. %s is expendable but %s is resilient. No need to do do anything.",
183 a.name.c_str(),
b.name.c_str());
190 O2_SIGNPOST_END(topology, sid,
"expendableDataDeps",
"%s is expendable. %s from %s to %s => %s.",
191 a.name.c_str(), hasDependency ?
"There is however an inverse dependency" :
"No inverse dependency",
b.name.c_str(),
a.name.c_str(),
192 !hasDependency ?
"true" :
"false");
193 if (!hasDependency) {
197 if (sporadic && !isBOutputProxy) {
198 O2_SIGNPOST_END(topology, sid,
"expendableDataDeps",
"%s is expendable. No inverse dependency from %s to %s. However the former has an occasioanl input => true.",
199 a.name.c_str(),
b.name.c_str(),
a.name.c_str());
202 O2_SIGNPOST_END(topology, sid,
"expendableDataDeps",
"%s is expendable. No inverse dependency from %s to %s => false.",
203 a.name.c_str(),
b.name.c_str(),
a.name.c_str());
207 O2_SIGNPOST_END(topology, sid,
"expendableDataDeps",
"false. %s is expendable but %s is not. No need to add an unneeded dependency.",
208 b.name.c_str(),
a.name.c_str());
224 O2_SIGNPOST_START(topology, sid,
"alwaysDependent",
"Checking if %s depends on %s", dependent.
name.c_str(), ancestor.name.c_str());
225 if (dependent.
name == ancestor.name) {
226 O2_SIGNPOST_END(topology, sid,
"alwaysDependent",
"false. %s and %s are the same.", dependent.
name.c_str(), ancestor.name.c_str());
229 if (ancestor.name.find(
"internal-dpl-injected-dummy-sink") != std::string::npos) {
230 O2_SIGNPOST_END(topology, sid,
"alwaysDependent",
"false. Nothing can depend on %s by policy.", ancestor.name.c_str());
234 if (dependent.
name.find(
"internal-dpl-injected-dummy-sink") != std::string::npos) {
235 O2_SIGNPOST_END(topology, sid,
"alwaysDependent",
"true. %s is always last.", ancestor.name.c_str());
238 const std::regex matcher(
".*output-proxy.*");
241 bool isAncestorOutputProxy = std::regex_match(ancestor.name.data(),
m, matcher);
243 assert(std::regex_match(dependent.
name.data(),
m, matcher));
244 bool isAncestorExpendable = std::find_if(ancestor.labels.begin(), ancestor.labels.end(), [](
DataProcessorLabel const&
label) {
245 return label.value ==
"expendable";
246 }) != ancestor.labels.end();
249 return label.value ==
"resilient";
250 }) != dependent.
labels.end();
251 bool isAncestorResilient = std::find_if(ancestor.labels.begin(), ancestor.labels.end(), [](
DataProcessorLabel const&
label) {
252 return label.value ==
"resilient";
253 }) != ancestor.labels.end();
255 if (!isDependentResilient && isAncestorExpendable) {
256 O2_SIGNPOST_END(topology, sid,
"alwaysDependent",
"false. Ancestor %s is expendable while %s is non-resilient output proxy (dependent).",
257 ancestor.name.c_str(), dependent.
name.c_str());
261 if (isAncestorOutputProxy || (!isDependentResilient && isAncestorResilient)) {
262 bool hasDependency =
dataDeps(dependent, ancestor);
263 O2_SIGNPOST_END(topology, sid,
"alwaysDependent",
"%s. Dependent %s %s a dependency on ancestor %s.",
264 hasDependency ?
"true" :
"false", dependent.
name.c_str(), hasDependency ?
"has" :
"has not", ancestor.name.c_str());
265 return hasDependency;
268 O2_SIGNPOST_END(topology, sid,
"alwaysDependent",
"true by default. Ancestor %s is not an output proxy.", ancestor.name.c_str());
#define O2_DECLARE_DYNAMIC_LOG(name)
#define O2_SIGNPOST_END(log, id, name, format,...)
#define O2_SIGNPOST_ID_GENERATE(name, log)
#define O2_SIGNPOST_START(log, id, name, format,...)
GLuint const GLchar * name
GLboolean GLboolean GLboolean b
GLuint GLsizei const GLchar * label
GLboolean GLboolean GLboolean GLboolean a
Defining PrimaryVertex explicitly as messageable.
bool expendableDataDeps(DataProcessorSpec const &a, DataProcessorSpec const &b)
bool sporadicDataDeps(DataProcessorSpec const &a, DataProcessorSpec const &b)
bool dataDeps(DataProcessorSpec const &a, DataProcessorSpec const &b)
A label that can be associated to a DataProcessorSpec.
std::vector< DataProcessorLabel > labels
static bool match(InputSpec const &spec, ConcreteDataMatcher const &target)
static TopologyPolicy::DependencyChecker dataDependency()
static TopologyPolicy::DataProcessorMatcher matchByRegex(std::string const &re)
static TopologyPolicy::DataProcessorMatcher matchAll()
static TopologyPolicy::DependencyChecker alwaysDependent()
static TopologyPolicy::DataProcessorMatcher matchByName(std::string const &name)
static std::vector< TopologyPolicy > createDefaultPolicies()
std::function< bool(DataProcessorSpec const &dependent, DataProcessorSpec const &ascendant)> DependencyChecker
std::function< bool(DataProcessorSpec const &device)> DataProcessorMatcher