#!/usr/bin/env perl # #Copyright (c) 2009, Perforce Software, Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #******************************************************************************* # use warnings; use strict; use FileHandle; use Text::Diff; use List::Util qw / shuffle /; #use IO::Handle; use Cwd; use autodie; sub compare_ckp { my $len_a_ref = shift; my $len_b_ref = shift; my $exclude_list_ref = shift; my $fd_lines = shift; my $fd_tx = shift; my $fd_diff = shift; #either pass file names or reference to the records. In this case, that would be a string my @diffs = split(/\n/, diff( $len_a_ref, $len_b_ref, { STYLE => "OldStyle" } )); foreach my $each_line (@diffs) { if($each_line =~ /^(\d+.*)$/ or $each_line =~ /^---.*$/) { print $fd_lines "$each_line\n"; } elsif ($each_line =~ /^(\>|\<)\s($exclude_list_ref->[0].*)$/) { print $fd_tx "$each_line\n"; } elsif ($each_line =~ /^(\>|\<)\s($exclude_list_ref->[1].*)$/) { print $fd_tx "$each_line\n"; } elsif ($each_line =~ /^(\>|\<)\s($exclude_list_ref->[2].*)$/) { print $fd_tx "$each_line\n"; } else { print $fd_diff "$each_line\n"; } } } sub shuffle_ckp { my $ckp_two = shift; my $ckp_shuffle = shift; my @file_names = ( 'single.txt', 'multi.txt' ); my %table_record = ( #multiline means 1, otherwise it's 0 'db.archive' => 0, 'db.archmap' => 0, 'db.boddate' => 1, 'db.bodtext' => 1, 'db.change' => 1, 'db.changex' => 1, 'db.config' => 0, 'db.counters' => 0, 'db.depot' => 1, 'db.desc' => 1, 'db.domain' => 1, 'db.fix' => 0, 'db.fixrev' => 0, 'db.group' => 0, 'db.have' => 0, 'db.integ' => 0, 'db.integed' => 0, 'db.integtx' => 0, 'db.ixdate' => 0, 'db.ixtext' => 0, 'db.job' => 0, 'db.jobdesc' => 1, 'db.jobpend' => 0, 'db.label' => 0, 'db.locks' => 0, 'db.logger' => 0, 'db.message' => 0, 'db.monitor' => 1, 'db.nameval' => 0, 'db.property' => 0, 'db.protect' => 1, 'db.resolve' => 0, 'db.resolvex' => 0, 'db.rev' => 0, 'db.revbx' => 0, 'db.revcx' => 0, 'db.revdx' => 0, 'db.revhx' => 0, 'db.review' => 0, 'db.revpx' => 0, 'db.revsh' => 0, 'db.revsx' => 0, 'db.revtx' => 0, 'db.revux' => 0, 'db.server' => 1, 'db.stream' => 1, 'db.svrview' => 1, 'db.template' => 0, 'db.traits' => 0, 'db.trigger' => 1, 'db.user' => 1, 'db.view' => 1, 'db.working' => 0, 'db.workingx' => 0, 'tiny.db' => 0, 'rdb.lbr' => 0, ); foreach (@file_names) { unlink $_; } open my( $ckptwo_fh ), "$ckp_two"; open my( $ckpthree_fh ), ">>$ckp_shuffle"; open my( $ckp_single ), ">$file_names[0]"; open my( $ckp_multi ), ">$file_names[1]"; while(<$ckptwo_fh>) { if(/^\@pv\@ \d+ \@(db\.\w+)\@.*$/) { if ( $table_record{$1} == 1 ) { print $ckp_multi "$_"; } else { print $ckp_single "$_"; } } else { print $ckp_multi "$_"; } } $ckp_single->flush; $ckp_multi->flush; close($ckp_single); close($ckp_multi); open $ckp_single , "$file_names[0]"; open $ckp_multi , "$file_names[1]"; my @ckp_single = <$ckp_single>; while(<$ckp_multi>) { print $ckpthree_fh "$_"; } $ckpthree_fh->flush; print $ckpthree_fh shuffle(@ckp_single); $ckpthree_fh->flush; close($ckpthree_fh); close($ckptwo_fh); } sub main { my $argc = @ARGV; if ($argc != 2) { die "Usage: " . $0 . " \n"; } my @exclude_list = ( '@mx@', '@ex@', '@nx@' ); my @files = ( 'line_count.txt', 'transaction_count.txt', 'real_diff.txt', 'shuffle.txt' ); foreach (@files) { if( -f $_) { unlink $_; } } my ($ckp_a, $ckp_b) = ($ARGV[0], $ARGV[1]); my $fd_a = FileHandle->new($ckp_a,"r"); my $fd_b = FileHandle->new($ckp_b,"r"); my $fd_lines = FileHandle->new($files[0],"w"); my $fd_tx = FileHandle->new($files[1],"w"); my $fd_diff = FileHandle->new($files[2],"w"); my $count = 0; while(1) { $count += 1; my ($chunk_a, $chunk_b); my $len_a = sysread($fd_a, $chunk_a, 100_000); my $len_b = sysread($fd_b, $chunk_b, 100_000); print "Chunk count#: $count: length identical\n" if $len_a == $len_b; last unless $len_a; &compare_ckp( \$chunk_a, \$chunk_b, \@exclude_list, $fd_lines, $fd_tx, $fd_diff ); #&shuffle_ckp( $ARGV[1], 'shuffle.txt' ); } $fd_a->close; $fd_b->close; $fd_lines->close; $fd_tx->close; } &main();