#!/usr/bin/perl

# Usage:
# o Execute the following comment shell-script (as root)
# o Execute this perl script (e.g. chunked-size-mem-advise.pl <log)
# o view plot/graph/image/whatever (figure.png) -- that's it

# #!/bin/bash
# 
# LARGEFILE="./largefile"
# DESTINATION="::1"
# LOGFILE="./log"
# 
# # create largefile
# if [ ! -f $LARGEFILE ]; then
#       echo "Creating file $LARGEFILE"
# 	dd if=/dev/urandom of=$LARGEFILE bs=1024 count=100000
# else
# 	echo "Not creating already existing file $LARGEFILE"
# fi
# 
# # make the 2.6 kernel not to store slow start threshold for a client
# # between TCP sessions
# sysctl -w net.ipv4.tcp_no_metrics_save=1;
# 
# # start the receiving side in background on the local machine
# while true
# do
#   netsend tcp receive /dev/null
# done &
# netsend_rx_pid=$!
# 
# # iterate through the possible madvise settings
# for advise in normal sequential random willneed dontneed
# do
#   echo "$advise"
#   # iterate through different chunk size settings
#   for i in 16 24 32 40 80 88 96 104 112 120 128 136
#   do
#     echo "  $i";
#     # drop clean pagecaches, dentries and inodes from memory
#     echo 3 > /proc/sys/vm/drop_caches;
#     netsend -m $advise -u mmap -T machine -b $i tcp transmit $LARGEFILE $DESTINATION 2>>$LOGFILE;
#     sleep 2s
#   done
# done
# 
# # stop the receiving side on the local machine
# kill $netsend_rx_pid


use strict; use warnings;

my $gnuplot_bin  = "/usr/bin/gnuplot";
my $datafile = join ("", "/tmp/", $$, ".txt");
my $last_round_advise_mode = "";

my %mem_advise_lookup = (
   "normal"     => 0,
   "sequential" => 1,
   "random"     => 2,
   "willneed"   => 3,
   "dontneed"   => 4
);

die "Can't open: $!\n" unless open (DATA_FILE, ">" . $datafile);

#002 tx mmap normal 136 0 986896 134217728 4.5223 0.1040 1.6761 1.7801 0 2062 1

while(<>) {
   my @line = split(/\s/, $_);
   die "Invalid netsend format\n" unless ($line[0] =~ m/^002$/);

   my $mem_advise_mode = $line[3];
   my $chunk_size      = $line[4];
   my $real_time       = $line[8];

   # we print a additional newline if we reach another adivse mode
   # This is necessary for gnuplot to distinguish between data-sets
   print DATA_FILE "\n" if $last_round_advise_mode ne $mem_advise_mode;
   $last_round_advise_mode = $mem_advise_mode;

   print DATA_FILE "$mem_advise_lookup{$mem_advise_mode} ";
   print DATA_FILE "$chunk_size ";
   print DATA_FILE "$real_time";

   print DATA_FILE "\n";

}

open (GNUPLOT, "|$gnuplot_bin") or die "Can't call gnuplot: $!\n";

print GNUPLOT <<"EOPLOT";
unset surface
unset contour
set xtics ("normal" 0, "sequentiell" 1, "random" 2, "willneed" 3, "dontneed" 4)
set title 'Read-ahead and caching techniques with madvise()'
set xlabel 'Advise Strategie'
set ylabel 'Chunksize [bytes]'
set zlabel '         Realtime for transfer [seconds]'
set view 70, 236
set pm3d at s
set term png small size 900,700 xFFFFFF
set output "figure.png"
#set terminal x11
splot "$datafile"  using 1:2:3 with lines
EOPLOT

close(GNUPLOT);

unlink $datafile;
