<commit_before>#!/usr/bin/perl
# Converts 'perf script' output to data consumable by google charts.

use warnings;
use strict;

use Data::Dumper;

my %times;                    # {tid} -> [samples]
my %funcs;                    # {tid} -> [lvl] -> [[func, b_index, e_eindex]...] (indices of time samples for tid)

sub process_input
{
    my $startTime;
    my @event;
    my @bt;

    while (<>) {
        if (!/^\s+/) {          # new stack trace
            @bt = ();
            @event = split /\s+/;
            $event[2] =~ s/://;
            $startTime = $event[2] unless $startTime;
        } elsif (/([0-9a-f]+)\s(.+?)\s\((.+)\)$/) {
            my ($func, $dso) = ($2, $3);
            #$func =~ s/\(.+?\)$//;
            push @bt, $func if $dso =~ /regression$/;
        }
        elsif (/^$/) {
            process_bt($event[1], $event[2] - $startTime, reverse @bt) if @bt;
        }
    }
}

sub process_bt
{
    my $tid = shift;
    my $sample = shift;

    $times{$tid} ||= [];

    for my $lvl (0 .. scalar @_) {
	my $func = $_[$lvl];
	$times{$tid}->[$lvl] ||= [];
	process_fn($tid, $sample, $func, $times{$tid}->[$lvl]);
    }

    # Must come last, needed for coalescing of intervals.
    push @{$times{$tid}}, $sample;
}

sub process_fn
{
    my ($tid, $sample, $func, $intervals) = @_;
    my $sample_idx = @{$times{$tid}};

    # Extend interval if no gaps and history exists, otherwise new interval.
    if ($sample_idx && @$intervals && ($intervals->[-1][0] eq $func) && ($intervals->[-1][-1]+1 == $sample_idx)) {
	++$intervals->[-1][-1];
    }
    else {
	push @$intervals, [$sample, $sample, scalar @{$times{$tid}}];
    }
}

process_input;

print Dumper(%funcs);
 
<commit_msg>Fixed bugs in timeline construction.<commit_after>#!/usr/bin/perl
# Converts 'perf script' output to data consumable by google charts.

use warnings;
use strict;

use Data::Dumper;

my %times;                    # {tid} -> [samples]
my %funcs;                    # {tid} -> [lvl] -> [[func, b_index, e_eindex]...] (indices of time samples for tid)

sub process_input
{
    my $startTime;
    my @event;
    my @bt;

    while (<>) {
        if (!/^\s+/) {          # new stack trace
            @bt = ();
            @event = split /\s+/;
            $event[2] =~ s/://;
            $startTime = $event[2] unless $startTime;
        } elsif (/([0-9a-f]+)\s(.+?)\s\((.+)\)$/) {
            my ($func, $dso) = ($2, $3);
            #$func =~ s/\(.+?\)$//;
            push @bt, $func if $dso =~ /regression$/;
        }
        elsif (/^$/) {
            process_bt($event[1], $event[2] - $startTime, reverse @bt) if @bt;
        }
    }
}

sub process_bt
{
    my $tid = shift;
    my $sample = shift;

    $times{$tid} ||= [];

    foreach my $lvl (0 .. $#_) {
	my $func = $_[$lvl];
	$funcs{$tid}->[$lvl] ||= [];
	process_fn($tid, $sample, $func, $funcs{$tid}->[$lvl]);
    }

    # Must come last, needed for coalescing of intervals.
    push @{$times{$tid}}, $sample;
}

sub process_fn
{
    my ($tid, $sample, $func, $intervals) = @_;
    my $sample_idx = @{$times{$tid}};

    # Extend interval if no gaps and history exists, otherwise new interval.
    if ($sample_idx && @$intervals && ($intervals->[-1][0] eq $func) && ($intervals->[-1][-1]+1 == $sample_idx)) {
	++$intervals->[-1][-1];
    }
    else {
	push @$intervals, [$func, $sample_idx, $sample_idx];
    }
}

process_input;

print Dumper(%funcs);
 

{'fraction_non_alphanumeric': 0.21721311475409835, 'fraction_numerical': 0.00936768149882904, 'mean_word_length': 2.134862385321101, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4297891', 'n_tokens_mistral': 1291, 'n_tokens_neox': 1250, 'n_words': 310}