see #2373 first fix for this problem

The change in UsageResolver
eliminates unnecessary scanning of all rule sets to check if the
affected rule set might be used as a branch. The program used to
scan the same objects many times.
.
This commit is contained in:
Vadim Kurland
2011-04-29 18:50:37 -07:00
parent 97ed9bf03a
commit 7627a82cfe
3 changed files with 56 additions and 16 deletions
+9
View File
@@ -1,5 +1,14 @@
2011-04-29 vadim <vadim@netcitadel.com>
* UsageResolver.cpp (findFirewallsForObject): see #2373 "GUI
becomes unresponsive for a long time when an object that is used
in a large number of rules is modified". This bug only affected
configurations with very large rule sets (1500 rules) where lots
of rules used the same object. The change in UsageResolver
eliminates unnecessary scanning of all rule sets to check if the
affected rule set might be used as a branch. The program used to
scan the same objects many times.
* iosaclAdvancedDialog.cpp (accept): fixes #2368 and SF bug
3294457 "External install script". External install script name
and arguments weren't saved for IOS firewall objects.
+6
View File
@@ -1247,9 +1247,15 @@ void RuleSetModel::objectChanged(FWObject* object)
{
QModelIndexList relatedIndexes = findObject(object);
if (fwbdebug)
qDebug() << "RuleSetModel::objectChanged"
<< "object=" << object->getName().c_str()
<< "relatedIndexes.size()=" << relatedIndexes.size();
foreach(QModelIndex index, relatedIndexes)
{
emit dataChanged(index, index);
break; // temporary for #2373
}
}
+41 -16
View File
@@ -36,6 +36,8 @@
#include "fwbuilder/Interface.h"
#include "fwbuilder/FWOptions.h"
#include "fwbuilder/Management.h"
#include "fwbuilder/RuleSet.h"
#include <algorithm>
@@ -124,7 +126,8 @@ void UsageResolver::findWhereUsedRecursively(
}
}
list<Firewall*> UsageResolver::findFirewallsForObject(FWObject *o, FWObjectDatabase *db)
list<Firewall*> UsageResolver::findFirewallsForObject(FWObject *o,
FWObjectDatabase *db)
{
if (fwbdebug)
qDebug("UsageResolver::findFirewallsForObject");
@@ -156,7 +159,17 @@ list<Firewall*> UsageResolver::findFirewallsForObject(FWObject *o, FWObjectDatab
}
}
set<FWObject *>::iterator i = resset.begin();
// whenever we find that a rule has been modified by the change in
// the object @o, we record rule set it belongs to. We should scan
// other rule sets to see if some rule somewhere might be using
// one of the rule sets that changed as a branch. However in a
// common situation where many rules of the same rule set are
// affected, it won't make sense to search for the dependencies on
// the same rule set many times.
set<RuleSet*> modified_rule_sets;
set<FWObject*>::iterator i = resset.begin();
for ( ;i!=resset.end(); ++i)
{
FWObject *obj = *i;
@@ -169,9 +182,6 @@ list<Firewall*> UsageResolver::findFirewallsForObject(FWObject *o, FWObjectDatab
{
obj = ref->getParent();
}
// else
// continue;
Rule *r = Rule::cast(obj);
if (r == NULL) r = Rule::cast(obj->getParent());
@@ -185,27 +195,42 @@ list<Firewall*> UsageResolver::findFirewallsForObject(FWObject *o, FWObjectDatab
fws.push_back(Firewall::cast(f));
}
// check if some rule somewhere may use ruleset r belongs to as a branch
FWObject *ruleset = r->getParent();
list<Firewall*> other_fws =
UsageResolver::findFirewallsForObject(ruleset, db);
for (list<Firewall*>::iterator fit = other_fws.begin(); fit != other_fws.end(); ++fit)
{
if (std::find(fws.begin(), fws.end(), *fit) == fws.end())
fws.push_back(*fit);
}
// check if some rule somewhere may use @ruleset as a
// branch
RuleSet *ruleset = RuleSet::cast(r->getParent());
assert(ruleset != NULL);
modified_rule_sets.insert(ruleset);
}
}
set<RuleSet*>::iterator i1 = modified_rule_sets.begin();
for ( ;i1!=modified_rule_sets.end(); ++i1)
{
RuleSet *ruleset = *i1;
list<Firewall*> other_fws =
UsageResolver::findFirewallsForObject(ruleset, db);
for (list<Firewall*>::iterator fit = other_fws.begin();
fit != other_fws.end(); ++fit)
{
if (std::find(fws.begin(), fws.end(), *fit) == fws.end())
fws.push_back(*fit);
}
}
if (fwbdebug)
{
qDebug() << QString("Program spent %1 ms searching for firewalls.") .arg(tt.elapsed());
qDebug() << QString("Program spent %1 ms searching for firewalls.")
.arg(tt.elapsed());
qDebug() << "UsageResolver::findFirewallsForObject returns";
for (list<Firewall*>::iterator i = fws.begin(); i!=fws.end(); ++i)
{
qDebug() << " " << (*i)->getName().c_str();
}
}
return fws;