summaryrefslogtreecommitdiffstats
path: root/bm/bm_rebase.pl
diff options
context:
space:
mode:
authorSadeep Madurange <sadeep@asciimx.com>2026-04-29 14:05:46 +0800
committerSadeep Madurange <sadeep@asciimx.com>2026-04-29 14:05:46 +0800
commit1b64a87816c06526229f9dc03b12f1092541ae59 (patch)
tree354deb4fa8cfc2ec54e1ddfca5eca6422cfce4f9 /bm/bm_rebase.pl
parent49ae7748e4a95afa1fd9d08f4886952dfc1deca4 (diff)
downloadurn-1b64a87816c06526229f9dc03b12f1092541ae59.tar.gz
Fix mtime change <1s bug.
Diffstat (limited to 'bm/bm_rebase.pl')
-rw-r--r--bm/bm_rebase.pl83
1 files changed, 50 insertions, 33 deletions
diff --git a/bm/bm_rebase.pl b/bm/bm_rebase.pl
index 3cb0fd5..e89e7f5 100644
--- a/bm/bm_rebase.pl
+++ b/bm/bm_rebase.pl
@@ -1,10 +1,13 @@
#!/usr/bin/perl
use strict;
use warnings;
+use File::Copy;
use File::Spec;
-use File::Path qw(remove_tree);
+use File::Path qw(remove_tree make_path);
use File::Find;
+use File::Basename;
use Cwd qw(getcwd abs_path);
+use Time::HiRes qw(time);
my ($files, $depth, $total_commits, $file_perc, $change_perc) = @ARGV;
if (!defined $files || !defined $depth || !defined $total_commits || !defined $file_perc || !defined $change_perc) {
@@ -14,15 +17,16 @@ if (!defined $files || !defined $depth || !defined $total_commits || !defined $f
my $base_dir = getcwd();
my $urn_bin = abs_path(File::Spec->catfile("..", "urn"));
my $seed_bin = abs_path("seed.pl");
-my $bm_repo = "bm_repo";
+my $bm_repo = "sandbox";
my $sample_rate = int($total_commits / 5) || 1;
my %results;
my $initial_repo_size = "0 KB";
-
my $rebase_count = 0;
my %last_base_hashes;
+my $global_tick = 0;
+
sub get_size {
my $dir = shift;
return "0 KB" unless -d $dir;
@@ -62,10 +66,7 @@ sub run_rebase_benchmark {
remove_tree($bm_repo) if -d $bm_repo;
system("perl $seed_bin $files $depth > /dev/null 2>&1");
- # Capture raw directory size before VCS initialization
- if ($initial_repo_size eq "0 KB") {
- $initial_repo_size = get_size($bm_repo);
- }
+ if ($initial_repo_size eq "0 KB") { $initial_repo_size = get_size($bm_repo); }
chdir($bm_repo) or die $!;
@@ -84,19 +85,37 @@ sub run_rebase_benchmark {
my $num_to_change = int(scalar(@file_list) * ($file_perc / 100)) || 1;
my @target_files = @file_list[0 .. $num_to_change - 1];
- for my $i (1 .. $total_commits) {
- for my $target (@target_files) {
- open(my $fh, '<', $target) or next;
- my @lines = <$fh>;
- close($fh);
+ for my $i (2 .. $total_commits) {
+ my $debug_dir = "/tmp/urn/commit_$i";
+ make_path($debug_dir) unless -d $debug_dir;
- my $lines_to_change = int(scalar(@lines) * ($change_perc / 100)) || 1;
- splice(@lines, 0, $lines_to_change, "Commit $i: block change\n");
-
- if (open(my $out, '>', $target)) {
- print $out @lines;
- close($out);
- }
+ for my $target (@target_files) {
+ open(my $fh, '<:raw', $target) or die "Read fail: $target - $!";
+ my $content = do { local $/; <$fh> };
+ close($fh);
+
+ $global_tick++;
+ my $ts = time();
+ my $header = "C$i-T$ts-N$global_tick ";
+
+ my $total_bytes = length($content);
+ my $min_len = length($header);
+ my $to_change = int($total_bytes * ($change_perc / 100));
+
+ $to_change = $min_len if $to_change < $min_len;
+ $to_change = $total_bytes if $to_change > $total_bytes;
+
+ my $new_segment = substr($header . ("." x $to_change), 0, $to_change);
+ substr($content, 0, $to_change, $new_segment);
+
+ open(my $out, '>:raw', $target) or die "Write fail: $target - $!";
+ print $out $content;
+ close($out);
+
+ my $target_name = basename($target);
+ copy($target, "$debug_dir/$target_name") or warn "Backup failed: $!";
+
+ utime(undef, undef, $target);
}
my $cmd = ($tool_name eq "URN")
@@ -104,14 +123,17 @@ sub run_rebase_benchmark {
: "git add . && git commit -m 'c$i'";
if ($i % $sample_rate == 0 || $i == $total_commits) {
- my $stats = `/usr/bin/time -l sh -c "$cmd" 2>&1 > /dev/null`;
- my ($real, $rss, $maj, $min) = (0, 0, 0, 0);
- if ($stats =~ /(\d+\.\d+)\s+real/) { $real = $1; }
- if ($stats =~ /(\d+)\s+maximum resident set size/) { $rss = sprintf("%.2f MB", $1 / 1024 / 1024); }
- if ($stats =~ /(\d+)\s+page reclaims/) { $min = $1; }
- if ($stats =~ /(\d+)\s+page faults/) { $maj = $1; }
+ my $raw_output = `/usr/bin/time -l sh -c "$cmd" 2>&1`;
+
+ if ($tool_name eq "URN") {
+ track_rebases();
+ }
- if ($tool_name eq "URN") { track_rebases(); }
+ my ($real, $rss, $maj, $min) = (0, 0, 0, 0);
+ $real = $1 if $raw_output =~ /(\d+\.\d+)\s+real/;
+ $rss = sprintf("%.2f MB", $1 / 1024 / 1024) if $raw_output =~ /(\d+)\s+maximum resident set size/;
+ $min = $1 if $raw_output =~ /(\d+)\s+page reclaims/;
+ $maj = $1 if $raw_output =~ /(\d+)\s+page faults/;
my $meta = ($tool_name eq "URN") ? ".urn" : ".git";
$results{$i}{$tool_name} = {
@@ -124,11 +146,10 @@ sub run_rebase_benchmark {
print " [Commit $i] $tool_name sampled.\n";
} else {
system("$cmd > /dev/null 2>&1");
- if ($tool_name eq "URN") { track_rebases(); }
+ track_rebases() if $tool_name eq "URN";
}
}
chdir($base_dir);
- remove_tree($bm_repo);
}
$rebase_count = 0;
@@ -141,7 +162,6 @@ open(my $res, '>', $out_file) or die $!;
print $res "=============================================================\n";
print $res " REBASE BENCHMARK: $files files ($total_commits commits)\n";
print $res " CONDITIONS: Depth=$depth, Files Mod=$file_perc%, Change=$change_perc%\n";
-print $res " INITIAL RAW DATA SIZE: $initial_repo_size\n";
print $res "=============================================================\n\n";
foreach my $i (sort { $a <=> $b } keys %results) {
@@ -158,10 +178,7 @@ foreach my $i (sort { $a <=> $b } keys %results) {
printf $res "%-15s | %20s | %20s\n", "Repo size", $u->{size}, $g->{size};
print $res "-------------------------------------------------------------\n\n";
}
-
print $res "TOTAL URN REBASES: $rebase_count\n";
close($res);
-my $pager = $ENV{PAGER} || 'less';
-exec $pager, $out_file;
-
+exec "less $out_file";