#!/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' |\
		grep -E -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' |\
		grep -E -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
