Update of /cvsroot/perl-ldap/ldap/contrib
In directory usw-pr-cvs1:/tmp/cvs-serv28810
Modified Files:
ldifdiff.pl
Log Message:
Speeded up attribute value comparisons significantly.
Index: ldifdiff.pl
===================================================================
RCS file: /cvsroot/perl-ldap/ldap/contrib/ldifdiff.pl,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- ldifdiff.pl 22 Oct 2001 13:34:43 -0000 1.1
+++ ldifdiff.pl 3 Nov 2002 01:47:45 -0000 1.2
@@ -60,7 +60,7 @@
my $keyattr = $args{k};
my @sourceattrs = split(/,/, $args{a});
-my %ciscmp = (objectclass => 1, manager => 1, owner => 1);
+my %ciscmp = (objectclass => 1, manager => 1, owner => 1, uniquemember => 1);
foreach (split(/,/, $args{c})) { $ciscmp{$_} = 1 }
@@ -80,8 +80,8 @@
$ldifout->{change} = 1;
$ldifout->{wrap} = 78;
-
diff($source, $target);
+exit;
# Gets the relative distinguished name (RDN) attribute
@@ -182,21 +182,12 @@
}
}
-sub grepval
-{
- my ($val, $vals, $ciscmp) = @_;
-
- return $ciscmp ? grep(/^\Q$val\E$/i, @$vals)
- : grep(/^\Q$val\E$/, @$vals);
-}
-
-
# Generate LDIF to update $target with information in $source.
# Optionally restrict the set of attributes to consider.
sub updateFromEntry
{
my ($source, $target, @attrs) = @_;
- my (%modhash, $attr, $val, $ldifstr);
+ my ($attr, $val, $ldifstr);
my %sharedattrs = (objectclass => 1);
@@ -214,40 +205,44 @@
foreach $attr (@attrs) {
my $lcattr = lc $attr;
next if $lcattr eq 'dn'; # Can't handle modrdn here
- if (!$source->exists($attr) && !$sharedattrs{$lcattr}) {
- # Source doesn't have this attribute, delete it from the target
- # if necessary.
- $target->delete($attr) if $target->exists($attr);
+
+ # Build lists of unique values in the source and target, to
+ # speed up comparisons.
+ my @sourcevals = $source->get_value($attr);
+ my @targetvals = $target->get_value($attr);
+ my (%sourceuniqvals, %targetuniqvals);
+ if ($ciscmp{$lcattr}) {
+ @sourceuniqvals{map { lc($_) } @sourcevals} = ();
+ @targetuniqvals{map { lc($_) } @targetvals} = ();
}
else {
- my $replaceattr;
- my @sourcevals = $source->get_value($attr);
- my @targetvals = $target->get_value($attr);
+ @sourceuniqvals{@sourcevals} = ();
+ @targetuniqvals{@targetvals} = ();
+ }
+ foreach my $val (keys %sourceuniqvals) {
+ if (exists $targetuniqvals{$val}) {
+ delete $sourceuniqvals{$val};
+ delete $targetuniqvals{$val};
+ }
+ }
+ # Move on if there are no differences
+ next unless keys(%sourceuniqvals) || keys(%targetuniqvals);
+
+ # Make changes as appropriate
+ if ($sharedattrs{$lcattr}) {
# For 'shared' attributes (e.g. objectclass) where $source may not
- # be a sole authoritative source, we issue issue 'delete' and
- # 'add' modifications instead of a single 'replace'.
- foreach $val (@targetvals) {
- next if $val eq ''; # Skip attributes with empty values
- if (!grepval($val, \@sourcevals, $ciscmp{$lcattr} ? 1 : 0)) {
- if ($sharedattrs{$lcattr}) {
- $target->delete($attr => [$val]);
- }
- else { $replaceattr = 1 }
- }
- }
- foreach $val (@sourcevals) {
- next if $val eq ''; # Skip attributes with empty values
- if (!grepval($val, \@targetvals, $ciscmp{$lcattr} ? 1 : 0)) {
- if ($sharedattrs{$lcattr}) {
- $target->add($attr => $val);
- }
- else { $replaceattr = 1 }
- }
- }
- # source is authoritative for this attribute, issue a replace.
- $target->replace($attr => [ @sourcevals ])
- if !$sharedattrs{$lcattr} && $replaceattr;
+ # be a sole authoritative source, we issue separate delete and
+ # add modifications instead of a single replace.
+ $target->delete($attr => [ keys(%targetuniqvals) ])
+ if keys(%targetuniqvals);
+ $target->add($attr => [ keys(%sourceuniqvals) ])
+ if keys(%sourceuniqvals);
+ }
+ else {
+ # Issue a replace or delete as needed
+ if (@sourcevals) { $target->replace($attr => [ @sourcevals ]) }
+ else { $target->delete($attr) }
}
}
|