#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-only

# Sergey Senozhatsky, 2015
# sergey.senozhatsky.work@gmail.com
#


# This program is intended to plot a `slabinfo -X' stats, collected,
# for example, using the following command:
#   while [ 1 ]; do slabinfo -X >> stats; sleep 1; done
#
# Use `slabinfo-gnuplot.sh stats' to pre-process collected records
# and generate graphs (totals, slabs sorted by size, slabs sorted
# by size).
#
# Graphs can be [individually] regenerate with different ranges and
# size (-r %d,%d and -s %d,%d options).
#
# To visually compare N `totals' graphs, do
# slabinfo-gnuplot.sh -t FILE1-totals FILE2-totals ... FILEN-totals
#

min_slab_name_size=11
xmin=0
xmax=0
width=1500
height=700
mode=preprocess

usage()
{
	echo "Usage: [-s W,H] [-r MIN,MAX] [-t|-l] FILE1 [FILE2 ..]"
	echo "FILEs must contain 'slabinfo -X' samples"
	echo "-t 			- plot totals for FILE(s)"
	echo "-l 			- plot slabs stats for FILE(s)"
	echo "-s %d,%d		- set image width and height"
	echo "-r %d,%d		- use data samples from a given range"
}

check_file_exist()
{
	if [ ! -f "$1" ]; then
		echo "File '$1' does not exist"
		exit 1
	fi
}

do_slabs_plotting()
{
	local file=$1
	local out_file
	local range="every ::$xmin"
	local xtic=""
	local xtic_rotate="norotate"
	local lines=2000000
	local wc_lines

	check_file_exist "$file"

	out_file=`basename "$file"`
	if [ $xmax -ne 0 ]; then
		range="$range::$xmax"
		lines=$((xmax-xmin))
	fi

	wc_lines=`cat "$file" | wc -l`
	if [ $? -ne 0 ] || [ "$wc_lines" -eq 0 ] ; then
		wc_lines=$lines
	fi

	if [ "$wc_lines" -lt "$lines" ]; then
		lines=$wc_lines
	fi

	if [ $((width / lines)) -gt $min_slab_name_size ]; then
		xtic=":xtic(1)"
		xtic_rotate=90
	fi

gnuplot -p << EOF
#!/usr/bin/env gnuplot

set terminal png enhanced size $width,$height large
set output '$out_file.png'
set autoscale xy
set xlabel 'samples'
set ylabel 'bytes'
set style histogram columnstacked title textcolor lt -1
set style fill solid 0.15
set xtics rotate $xtic_rotate
set key left above Left title reverse

plot "$file" $range u 2$xtic title 'SIZE' with boxes,\
	'' $range u 3 title 'LOSS' with boxes
EOF

	if [ $? -eq 0 ]; then
		echo "$out_file.png"
	fi
}

do_totals_plotting()
{
	local gnuplot_cmd=""
	local range="every ::$xmin"
	local file=""

	if [ $xmax -ne 0 ]; then
		range="$range::$xmax"
	fi

	for i in "${t_files[@]}"; do
		check_file_exist "$i"

		file="$file"`basename "$i"`
		gnuplot_cmd="$gnuplot_cmd '$i' $range using 1 title\
			'$i Memory usage' with lines,"
		gnuplot_cmd="$gnuplot_cmd '' $range using 2 title \
			'$i Loss' with lines,"
	done

gnuplot -p << EOF
#!/usr/bin/env gnuplot

set terminal png enhanced size $width,$height large
set autoscale xy
set output '$file.png'
set xlabel 'samples'
set ylabel 'bytes'
set key left above Left title reverse

plot $gnuplot_cmd
EOF

	if [ $? -eq 0 ]; then
		echo "$file.png"
	fi
}

do_preprocess()
{
	local out
	local lines
	local in=$1

	check_file_exist "$in"

	# use only 'TOP' slab (biggest memory usage or loss)
	let lines=3
	out=`basename "$in"`"-slabs-by-loss"
	`cat "$in" | grep -A "$lines" 'Slabs sorted by loss' |\
		egrep -iv '\-\-|Name|Slabs'\
		| awk '{print $1" "$4+$2*$3" "$4}' > "$out"`
	if [ $? -eq 0 ]; then
		do_slabs_plotting "$out"
	fi

	let lines=3
	out=`basename "$in"`"-slabs-by-size"
	`cat "$in" | grep -A "$lines" 'Slabs sorted by size' |\
		egrep -iv '\-\-|Name|Slabs'\
		| awk '{print $1" "$4" "$4-$2*$3}' > "$out"`
	if [ $? -eq 0 ]; then
		do_slabs_plotting "$out"
	fi

	out=`basename "$in"`"-totals"
	`cat "$in" | grep "Memory used" |\
		awk '{print $3" "$7}' > "$out"`
	if [ $? -eq 0 ]; then
		t_files[0]=$out
		do_totals_plotting
	fi
}

parse_opts()
{
	local opt

	while getopts "tlr::s::h" opt; do
		case $opt in
			t)
				mode=totals
				;;
			l)
				mode=slabs
				;;
			s)
				array=(${OPTARG//,/ })
				width=${array[0]}
				height=${array[1]}
				;;
			r)
				array=(${OPTARG//,/ })
				xmin=${array[0]}
				xmax=${array[1]}
				;;
			h)
				usage
				exit 0
				;;
			\?)
				echo "Invalid option: -$OPTARG" >&2
				exit 1
				;;
			:)
				echo "-$OPTARG requires an argument." >&2
				exit 1
				;;
		esac
	done

	return $OPTIND
}

parse_args()
{
	local idx=0
	local p

	for p in "$@"; do
		case $mode in
			preprocess)
				files[$idx]=$p
				idx=$idx+1
				;;
			totals)
				t_files[$idx]=$p
				idx=$idx+1
				;;
			slabs)
				files[$idx]=$p
				idx=$idx+1
				;;
		esac
	done
}

parse_opts "$@"
argstart=$?
parse_args "${@:$argstart}"

if [ ${#files[@]} -eq 0 ] && [ ${#t_files[@]} -eq 0 ]; then
	usage
	exit 1
fi

case $mode in
	preprocess)
		for i in "${files[@]}"; do
			do_preprocess "$i"
		done
		;;
	totals)
		do_totals_plotting
		;;
	slabs)
		for i in "${files[@]}"; do
			do_slabs_plotting "$i"
		done
		;;
	*)
		echo "Unknown mode $mode" >&2
		usage
		exit 1
	;;
esac
