77using namespace icinga ;
88
99/* *
10- * The maximum number of dependency recursion levels allowed .
10+ * The maximum number of allowed dependency recursion levels.
1111 *
1212 * This is a subjective limit how deep the dependency tree should be allowed to go, as anything beyond this level
1313 * is just madness and will likely result in a stack overflow or other undefined behavior.
@@ -315,7 +315,7 @@ size_t Checkable::GetAllChildrenCount() const
315315
316316std::set<Checkable::Ptr> Checkable::GetAllChildren () const
317317{
318- std::set<Checkable::Ptr> children = GetChildren () ;
318+ std::set<Checkable::Ptr> children;
319319
320320 GetAllChildrenInternal (children, 0 );
321321
@@ -328,31 +328,23 @@ std::set<Checkable::Ptr> Checkable::GetAllChildren() const
328328 * Note, this function performs a recursive call chain traversing all the children of the current Checkable
329329 * up to a certain limit (256). When that limit is reached, it will log a warning message and abort the operation.
330330 *
331- * @param children - The set of children to be filled with all the children of the current Checkable .
331+ * @param seenChildren - A container to store all the traversed children into .
332332 * @param level - The current level of recursion.
333333 */
334- void Checkable::GetAllChildrenInternal (std::set<Checkable::Ptr>& children , int level) const
334+ void Checkable::GetAllChildrenInternal (std::set<Checkable::Ptr>& seenChildren , int level) const
335335{
336336 if (level > l_MaxDependencyRecursionLevel) {
337337 Log (LogWarning, " Checkable" )
338338 << " Too many nested dependencies (>" << l_MaxDependencyRecursionLevel << " ) for checkable '" << GetName () << " ': aborting traversal." ;
339- return ;
339+ return ;
340340 }
341341
342- std::set<Checkable::Ptr> localChildren;
343-
344- for (const Checkable::Ptr& checkable : children) {
345- if (auto cChildren (checkable->GetChildren ()); !cChildren.empty ()) {
346- GetAllChildrenInternal (cChildren, level + 1 );
347- localChildren.insert (cChildren.begin (), cChildren.end ());
348- }
349-
350- if (level != 0 ) { // Recursion level 0 is the initiator, so checkable is already in the set.
351- localChildren.insert (checkable);
342+ for (const Checkable::Ptr& checkable : GetChildren ()) {
343+ if (seenChildren.find (checkable) == seenChildren.end ()) {
344+ seenChildren.emplace (checkable);
345+ checkable->GetAllChildrenInternal (seenChildren, level + 1 );
352346 }
353347 }
354-
355- children.insert (localChildren.begin (), localChildren.end ());
356348}
357349
358350/* *
0 commit comments