#!/bin/ksh
#set -x
#
##############################################################################
#                                                                            #
#  RCS Filename : gd,v
#  RCS Date     : 1996/07/12 15:44:47
#  RCS Revision : 1.8
#  RCS Author   : lamberts
#  RCS State    : V2_0_B
#                                                                            #
#  Authors: Stefan Lamberts                                                  #
#                                                                            #
##############################################################################

#
# Inputfile format
# OP MA CC ND C  I  O  M  EI II  BYTES MIN MAX AVG STD
# $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11   $12 $13 $14 $15
#

USAGE='Usage: \n'$0'\n
\t[-w {bdw|lat}]\t\t# Latency | Bandwidth; Default: lat\n
\t[-d <data directory>]\t# Default: DATA\n
\t<DESCRIPTION> ....\n\n
\tDESCRIPTION :== <OPERATION>:<CLNTSYNC>:<IODSYNC>:<O_SYNC>:<MODE>:<CLIENTS>:<NODE>:<MACHINES>\n
\tOPERATION   :== {CWR|CRD|IWRW|IRDW|IWRIOW|IRDIOW}\n
\tCLNTSYNC    :== {A|S}\t# Client asynchronous(A),synchronous(S)\n
\tIODSYNC     :== {A|S}\t# Iod asynchronous(A),synchronous(S)\n
\tO_SYNC      :== {T|F}\t# O_SYNC flag set(T), not set(F)\n
\tMODE        :== {U|L|R|S|G}\t# M_UNIX,M_LOG,M_RECORD,M_SYNC,M_GLOBAL\n
\tCLIENTS     :== <Number>\t# Number of Clients\n
\tNODE        :== <Number>|N|C\t# Nodenumber\n
\t\t\t\t# N : Average over all nodes per measurement\n
\t\t\t\t# C : Collective of all nodes\n
\tMACHINES    :== <Number>\t# Number of Machines used'


######################################################################
# Defaults
######################################################################

WHAT="lat"
DATADIR="DATA"

######################################################################
# Get and check command line options
######################################################################

while getopts "w:d:" opt
do	case $opt in
	d)	DATADIR=$OPTARG;;
	w)	WHAT=$OPTARG;;
	*)	echo $USAGE; exit 1;;
	esac
done

shift `expr $OPTIND - 1`

if [[ $# -lt 1 ]]
then
	echo $USAGE; exit 1
fi

case $WHAT in
bdw|lat)		:;;
*)			echo $USAGE; exit 1;;
esac			

######################################################################
# Check descriptor
######################################################################

chkdsc () # OP CS IS OS MD CC ND MA
{
	if [[ $# -ne 8 ]]
	then
		return 1
	fi

	case $1 in
	CWR|CRD|IWRW|IRDW|IWRIOW|IRDIOW)	;;
	*)					return 1;;
	esac

	case $2 in
	A|S)	;;
	*)	return 1;;
	esac

	case $3 in
	A|S)	;;
	*)	return 1;;
	esac

	case $4 in
	T|F)	;;
	*)	return 1;;
	esac

	case $5 in
	U|S|L|R|G)	;;
	*)		return 1;;
	esac

	case $6 in
	[1-9]|[1-9][0-9])	;;
	*)			return 1;;
	esac

	case $7 in
	[0-9]|[1-9][0-9])	if [[ $7 -ge $6 ]]
				then	return 1
				fi
				;;
	N)			:;;
	C)			if [[ "$WHAT" = "lat" ]]
				then	return 1
				fi;;
	*)			return 1;;
	esac
	case $8 in
	[0-9]|[1-9][0-9])	;;
	*)			return 1;;
	esac

	return 0
}

######################################################################
# Build awk argument
######################################################################

awkarg () # OP CS IS OS MD CC ND MA Filename
{

	if [[ "$7" = "C" ]]
	then
		######################################################
		# Cumulated bandwidth of all nodes
		######################################################

		if [[ ($5 = "G") && (($1 = "CWR") || ($1 = "IWRW")) ]]
		then
			##############################################
			# In M_GLOBAL bandwidth of write operations
			# is calculated only from operations of node 0
			# Use only lines with matching parameters and
			# ND == 0
			##############################################

			MATCH='($1=="'$1'")&&($2=='$8')&&($3=='$6')&&($4==0)&&($5=="'$2'")&&($6=="'$3'")&&($7=="'$4'")&&($8=="'$5'")'
		else
			##############################################
			# Cumulated bandwidth is calculated by adding
			# the bandwidth of all nodes
			# Use only lines with matching parameters and
			# ND < CC
			##############################################

			MATCH='($1=="'$1'")&&($2=='$8')&&($3=='$6')&&($4<'$6')&&($5=="'$2'")&&($6=="'$3'")&&($7=="'$4'")&&($8=="'$5'")'
		fi
	elif [[ "$7" = "N" ]]
		######################################################
		# Use only lines with matching parameters
		######################################################
	then
		MATCH='($1=="'$1'")&&($2=='$8')&&($3=='$6')&&($4=='$6')&&($5=="'$2'")&&($6=="'$3'")&&($7=="'$4'")&&($8=="'$5'")'
	else
		MATCH='($1=="'$1'")&&($2=='$8')&&($3=='$6')&&($4=='$7')&&($5=="'$2'")&&($6=="'$3'")&&($7=="'$4'")&&($8=="'$5'")'
	fi

	if [[ "$WHAT" = "bdw" ]]
	then
		######################################################
		# Cumlated bandwidth of all nodes is calculated by 
		# adding the bandwith of all nodes.
		# In M_GLOBAL write operations the bandwidth of node 
		# 1 to N is 0.
		######################################################

		######################################################
		# Bandwidth is calculated by dividing number of bytes
		# by the time.
		######################################################

		######################################################
		# Specify which field to extract.
		# Divide time by internal iterations.
		######################################################
		if [[ "$7" = "C" ]]
		then
			##############################################
			# Calulate the sum of the bandwidth of all
			# matching lines and print it at the end
			##############################################

			AWKARG="$AWKARG"'
'"$MATCH"'{
	min'$1$2$3$4$5$6$8'[$11] += $11/($13/$10);
	max'$1$2$3$4$5$6$8'[$11] += $11/($12/$10);
	avg'$1$2$3$4$5$6$8'[$11] += $11/($14/$10)}
END{	for (b in min'$1$2$3$4$5$6$8'){
		printf(" %d\t%f\t%f\t%f\n",b,avg'$1$2$3$4$5$6$8'[b],min'$1$2$3$4$5$6$8'[b],max'$1$2$3$4$5$6$8'[b])>>"'$9'"}}'

		else
			##############################################
			# Calculate the bandwidth and print it for all
			# matching lines.
			##############################################
			if [[ ($5 = "G") && ($7 != 0) && (($1 = "CWR") || ($1 = "IWRW")) ]]
			then
				######################################
				# In M_GLOBAL the bandwith of nodes
				# which are not node 0 is 0 since they
				# do not transfer data.
				######################################

				 AWKARG="$AWKARG"'
'"$MATCH"'{printf(" %d\t0\t0\t0\n",$11)>>"'$9'"}'
			else
				######################################
				# Calculate bandwidth and print it
				######################################		
				 AWKARG="$AWKARG"'
'"$MATCH"'{printf(" %d\t%f\t%f\t%f\n",$11,$11/($14/$10),$11/($13/$10),$11/($12/$10))>>"'$9'"}'
			fi
		fi
	else
		######################################################
		# Print the time for all matching lines.
		# Divide time by internal iterations.
		######################################################

		AWKARG="$AWKARG"'
'"$MATCH"'{printf(" %d\t%f\t%f\t%f\n",$11,$14/$10,$12/$10,$13/$10)>>"'$9'"}'
	fi
}

######################################################################
# Generate Filename
######################################################################
fname () # OP CS IS OS MD CC ND MA
{
	typeset -Z2 MA=$8
	typeset -Z2 CC=$6
	
	echo $1:$2:$3:$4:$5:$CC:$7:$MA
}

######################################################################
# Build command line for awk
######################################################################

AWKARG=""
FNS=""
for arg in $*
do	ARG=`echo $arg | sed -e 's/:/ /g'`
	FN="$DATADIR/$WHAT:"`fname $ARG`
	if [[ -r $FN ]]
	then	echo "File $FN exists; Won't extract."
		continue
	fi
	if chkdsc $ARG
	then	:
	else	echo "Invalid DESCRIPTION $arg; Skipping."
		continue
	fi

	echo "Extracting $FN"

	awkarg $ARG $FN
	FNS="$FNS $FN"
done

######################################################################
# Run awk.
######################################################################

#set -x
if [[ "$AWKARG" != "" ]]
then
	awk "$AWKARG"
fi

for f in $FNS
do	case $f in
	*C*)	if [[ -r $f ]]
		then	mv $f $f.tmp
			sort -n < $f.tmp > $f
			rm -f $f.tmp
		fi;;
	esac
done

exit 0
