#!/usr/bin/bash

set -e

LABEL=$1
LOGDIR=$(date +%Y%m%d-%H%M)-$LABEL

PATH_OLD=$PATH
#DEVICES="data raid-sata raid-nvme"
DEVICES="data"
BUILDS="master patched"
#SCALES="50000000 500000000"
SCALES="50000000"

mkdir -p $LOGDIR

sudo nvme list > $LOGDIR/nvme.list

for dev in /dev/nvme*n1 /dev/sd[a-z] /dev/md1*; do
	ra=$(sudo blockdev --getra $dev)
	echo $dev $ra >> $LOGDIR/blockdev.log
done

for dev in /dev/nvme*n1 /dev/sd[a-z]; do
	sudo smartctl -a $dev >> $LOGDIR/smartctl.log 2>&1
done;

for dev in /dev/md1*; do
	sudo mdadm --detail $dev >> $LOGDIR/mdadm.log 2>&1
done;

rm -f parameters.list parameters.random
for eic in 0 1 4 8 16 32; do

	for ioc in 8kB 32kB 64kB 128kB 256kB 512kB; do

		for perc in 0.01 0.005 0.0025 0.001 0.0005 0.0002 0.0001 0.000075 0.00005 0.000025 0.00001 0.000001; do

			echo $eic $ioc $perc >> parameters.list

		done

	done

done


for rows in $SCALES; do

	for wal in logged unlogged; do

		for dev in $DEVICES; do

			DATADIR=/mnt/$dev/data-vacuum

			for build in $BUILDS; do

				OUTDIR=$LOGDIR/$rows/$wal/$dev/$build
				mkdir -p $OUTDIR

				PATH=/home/tomas/builds/$build/bin:$PATH_OLD

				# make sure no postgres is running
				killall -9 postgres || true
				rm -Rf /mnt/$dev/data-vacuum

				pg_ctl -D $DATADIR init > $OUTDIR/init.log 2>&1

				cp postgresql.conf /mnt/$dev/data-vacuum

				pg_ctl -D $DATADIR -l $OUTDIR/pg.log start

				dropdb --if-exists test
				createdb test

				if [ "$wal" == "logged" ]; then
					psql test -c "create table test_vacuum (a bigint) with (fillfactor=50)" > $OUTDIR/create.log 2>&1
				else
					psql test -c "create unlogged table test_vacuum (a bigint) with (fillfactor=50)" >> $OUTDIR/create.log 2>&1
				fi

				psql test -c "insert into test_vacuum select i from generate_series(1,$rows) s(i)" >> $OUTDIR/create.log 2>&1
				psql test -c "vacuum freeze test_vacuum" >> $OUTDIR/create.log 2>&1
				psql test -c "checkpoint" >> $OUTDIR/create.log 2>&1

				psql test -c "\d+" >> $OUTDIR/create.log 2>&1

				for run in $(seq 1 3); do

					# randomize the parameters
					shuf parameters.list > parameters.random

					while read -r line; do

						IFS=' ' read -r -a array <<< "$line"

						eic="${array[0]}"
						ioc="${array[1]}"
						perc="${array[2]}"

						echo "========== run $run eic $eic perc $perc ==========" >> $OUTDIR/test.log 2>&1

						pg_ctl -D $DATADIR -l $OUTDIR/pg.log stop >> $OUTDIR/test.log 2>&1
						pg_ctl -D $DATADIR -l $OUTDIR/pg.log start >> $OUTDIR/test.log 2>&1

						psql test -c "update test_vacuum set a=a where random() < $perc" >> $OUTDIR/test.log 2>&1

						# restart (shutdown) also does a checkpoint
						pg_ctl -D $DATADIR -l $OUTDIR/pg.log restart >> $OUTDIR/test.log 2>&1
						sudo ./drop-caches.sh

						s=$(psql -t -A test -c "select extract(epoch from now())")

						psql test > vacuum.log 2>&1 <<EOF
set effective_io_concurrency = $eic;
set maintenance_io_concurrency = $eic;
set io_combine_limit = '$ioc';
vacuum (verbose, freeze) test_vacuum;
EOF

						cat vacuum.log >> $OUTDIR/test.log 2>&1

						pages_remain=$(grep '^pages:' vacuum.log | awk '{print $4}')
						pages_scanned=$(grep '^pages:' vacuum.log | awk '{print $6}')
						avg_read=$(grep '^avg read rate:' vacuum.log | awk '{print $4}')
						avg_write=$(grep '^avg read rate:' vacuum.log | awk '{print $9}')

						e=$(psql -t -A test -c "select extract(epoch from now())")
						d=$(psql -t -A test -c "select ($e - $s)")

						echo "$rows $wal $dev $build $run $eic $ioc $perc $d $pages_remain $pages_scanned $avg_read $avg_write" >> $LOGDIR/results.csv

					done < parameters.random

				done

			done

		done

	done

done
