Commit dca5477c authored by Robert Ricci's avatar Robert Ricci
Browse files

Re-arrange some functions to get speed improvments: approximately 20%

for large experiments. Not as much of an improvement as I had hoped,
but further improvement will probably take a lot more rearranging.
parent bdb9504f
......@@ -774,12 +774,7 @@ sub doReset($@) {
# list and do them all at once for efficiency.
#
foreach my $stack (@$stacks) {
my @existant_vlans = ();
foreach my $vlan (@vlans) {
if ($stack->vlanExists($vlan)) {
push @existant_vlans, $vlan;
}
}
my @existant_vlans = $stack->existantVlans(@vlans);
if (!$stack->removeVlan(@existant_vlans)) {
$errors++;
}
......
......@@ -417,6 +417,48 @@ sub vlanUnlock($;$) {
return $ApplyRetVal;
}
#
# Given VLAN indentifiers from the database, finds the cisco-specific VLAN
# number for them. If not VLAN id is given, returns mappings for the entire
# switch.
#
# usage: findVlans($self, @vlan_ids)
# returns a hash mapping VLAN ids to Cisco VLAN numbers
# any VLANs not found have NULL VLAN numbers
#
sub findVlans($@) {
my $self = shift;
my @vlan_ids = @_;
my $VlanName = "vtpVlanName"; # index by 1.vlan #
#
# Walk the tree to find the VLAN names
# TODO - we could optimize a bit, since, if we find all VLAN, we can stop
# looking, potentially saving us a lot of time. But, it would require a
# more complex walk.
#
my %mapping = ();
@mapping{@vlan_ids} = undef;
my ($rows) = $self->{SESS}->bulkwalk(0,32,[$VlanName]);
foreach my $rowref (@$rows) {
my ($name,$vlan_number,$vlan_name) = @$rowref;
#
# We get the VLAN number in the form 1.number - we need to strip
# off the '1.' to make it useful
#
$vlan_number =~ s/^1\.//;
$self->debug("Got $name $vlan_number $vlan_name\n",2);
if (!@vlan_ids || exists $mapping{$vlan_name}) {
$self->debug("Putting in mapping from $vlan_name to $vlan_number\n",2);
$mapping{$vlan_name} = $vlan_number;
}
}
return %mapping;
}
#
# Given a VLAN identifier from the database, find the cisco-specific VLAN
# number that is assigned to that VLAN. Retries several times (to account
......@@ -438,30 +480,15 @@ sub findVlan($$;$) {
$max_tries = 10;
}
my $VlanName = "vtpVlanName"; # index by 1.vlan #
#
# We try this a few time, with 1 second sleeps, since it can take
# a while for VLAN information to propagate
#
foreach my $try (1 .. $max_tries) {
#
# Walk the tree to find the VLAN names
#
my ($rows) = $self->{SESS}->bulkwalk(0,32,[$VlanName]);
foreach my $rowref (@$rows) {
my ($name,$vlan_number,$vlan_name) = @$rowref;
#
# We get the VLAN number in the form 1.number - we need to strip
# off the '1.' to make it useful
#
$vlan_number =~ s/^1\.//;
$self->debug("Got $name $vlan_number $vlan_name\n",2);
if ($vlan_name eq $vlan_id) {
return $vlan_number;
}
my %mapping = $self->findVlans($vlan_id);
if (defined($mapping{$vlan_id})) {
return $mapping{$vlan_id};
}
#
......
......@@ -129,7 +129,7 @@ sub new($$$#@) {
#
# List all VLANs on all switches in the stack
#
# usage: vlistVlans(self)
# usage: listVlans(self)
#
# returns: A list of VLAN information. Each entry is an array reference. The
# array is in the form [id, ddep, members] where:
......@@ -238,7 +238,7 @@ sub setPortVlan($$@) {
if ($vlan_id ne 'default') {
my $vlan_number = $self->{LEADER}->findVlan($vlan_id);
$errors += (!$self->setVlanOnTrunks($vlan_number,1));
$errors += (!$self->setVlanOnTrunks($vlan_number,1,@ports));
}
return $errors;
......@@ -328,6 +328,35 @@ sub vlanExists($$) {
}
#
# Return a list of which VLANs from the input set exist on this stack
#
# usage: existantVlans(self, vlan identifiers)
#
# returns: a list containing the VLANs from the input set that exist on this
# stack
#
sub existantVlans($@) {
my $self = shift;
my @vlan_ids = @_;
#
# The leader holds the list of which VLANs exist
#
my %mapping = $self->{LEADER}->findVlans(@vlan_ids);
my @existant = ();
foreach my $vlan_id (@vlan_ids) {
if (defined $mapping{$vlan_id}) {
push @existant, $vlan_id;
}
}
return @existant;
}
#
# Removes a VLAN from the stack. This implicitly removes all ports from the
# VLAN. It is an error to remove a VLAN that does not exist.
......@@ -342,11 +371,12 @@ sub removeVlan($@) {
my (@vlan_ids) = @_;
my $errors = 0;
my %vlan_numbers = $self->{LEADER}->findVlans(@vlan_ids);
foreach my $vlan_id (@vlan_ids) {
#
# First, make sure that the VLAN really does exist
#
my $vlan_number = $self->{LEADER}->findVlan($vlan_id);
my $vlan_number = $vlan_numbers{$vlan_id};
if (!$vlan_number) {
warn "ERROR: VLAN $vlan_id not found on switch!";
return 0;
......@@ -371,13 +401,14 @@ sub removeVlan($@) {
foreach my $devicename (sort {tbsort($a,$b)} keys %{$self->{DEVICES}}) {
my $device = $self->{DEVICES}{$devicename};
my @existant_vlans = ();
my %vlan_numbers = $device->findVlans(@vlan_ids);
foreach my $vlan_id (@vlan_ids) {
#
# Only remove ports from the VLAN if it exists on this
# device. Do it in one pass for efficiency
#
if (defined(my $number = $device->findVlan($vlan_id))) {
if (defined $vlan_numbers{$vlan_id}) {
push @existant_vlans, $vlan_id;
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment