#!/usr/bin/env bash

set -e

BUILDDIR="/home/vnull/numabench/"
DATADIR=/db/numa
PATH_OLD=$PATH

#killall -q -9 postgres || true
pkill postgres || true
pkill -9 postgres || true

SCALE=1000
PARTITIONS=8
DURATION=20
RUNS=3

export PATH=$BUILDDIR/inst-master/bin:$PATH_OLD

TS=$(date +%Y%m%d-%H%M%S)

mkdir $TS

rm -rf $DATADIR/*
#pg_ctl -D $DATADIR init > $TS/init.log 2>&1
initdb -D $DATADIR --no-data-checksums > $TS/init.log 2>&1

echo 'shared_buffers = 8GB' > $DATADIR/postgresql.conf
echo 'max_parallel_maintenance_workers = 0' >> $DATADIR/postgresql.conf
echo 'max_parallel_workers_per_gather = 0' >> $DATADIR/postgresql.conf
echo 'huge_pages = on' >> $DATADIR/postgresql.conf
echo 'max_wal_size = 16GB' >> $DATADIR/postgresql.conf
echo 'max_connections = 1000' >> $DATADIR/postgresql.conf
echo 'synchronize_seqscans = off' >> $DATADIR/postgresql.conf
#echo "plan_cache_mode='force_generic_plan'" >> $DATADIR/postgresql.conf

cp $DATADIR/postgresql.conf ./

pg_ctl -D $DATADIR -l pg.log start >> $TS/init.log 2>&1

createdb test >> $TS/init.log 2>&1

pgbench -i -s $SCALE --partitions=$PARTITIONS test >> $TS/init.log 2>&1
psql test -c '\dt+' > $TS/psql_dt.log 2>&1

pg_ctl -D $DATADIR -l pg.log stop >> $TS/init.log 2>&1


for r in $(seq 1 $RUNS); do

	mkdir $TS/$r

	for b in inst-master inst-patched inst-optimized; do
	#for b in inst-master inst-patched ; do

		for i in interleave default; do

			export PATH=$BUILDDIR/$b/bin:$PATH_OLD
	
			#for q in pgbenchS100krows ; do
			#for q in pgbenchS ; do
			#for q in seqconcurrscans pgbenchS ; do
			#for q in pgbenchS; do
			for q in seqconcurrscans ; do

				#for c in 1 8 32; do
				#for c in 8 ; do
				for c in 8 32 ; do

					for numa in off on; do

						for balance in on off; do

							for iomethod in io_uring; do

								if [ "$b" == "inst-master" ] ; then
									if [ "$numa" == "on" ]; then
										continue
									fi

									if [ "$balance" == "on" ]; then
										continue
									fi
								else
									# NUMA builds

									# no point in numactl interlave for numa builds
									if [ "$i" == "interleave" ]; then
										continue
									fi

									# if NUMA is off, ignore balance
									if [ "$numa" == "off" ]; then
										if [ "$balance" == "on" ]; then
											continue
										fi
									fi
								fi

								if [ "$i" == "interleave" ]; then
									NUMACTL="numactl --interleave=all "
								else
									NUMACTL=""	
								fi

								cp postgresql.conf $DATADIR/
								echo "io_method = $iomethod" >> $DATADIR/postgresql.conf

								if [ "$numa" == "on" ]; then
									echo "shared_buffers_numa = on" >> $DATADIR/postgresql.conf
									echo "debug_shmem_populate = on" >> $DATADIR/postgresql.conf
									echo "debug_clocksweep_balance = ${balance}" >> $DATADIR/postgresql.conf
								fi


								echo 3 | sudo tee /proc/sys/vm/drop_caches > $TS/$r/drop_caches.log 2>&1
								$NUMACTL pg_ctl -D $DATADIR -l pg.log start >> $TS/$r/init.log 2>&1

								PATTERN="${b}-${i}-${q}-${c}-${numa}-${balance}-${iomethod}"

								psql test -c "select name,setting from pg_settings where source != 'default';" > $TS/$r/settings-$PATTERN.log 2>&1

								if [ "$q" == "seqconcurrscans" ]; then
									# _:num replacement doesnt work without it
									MODE="simple"
								else
									MODE="prepared"
								fi
								#warmup
								pgbench -n -M $MODE -f $q.sql -T 5 -l -c $c -j $c test > /dev/null 2>&1
								pgbench -n -M $MODE -f $q.sql -T $DURATION -l -c $c -j $c --log-prefix=$TS/$r/log-$PATTERN test > $TS/$r/pgbench-$PATTERN.log 2>&1

								if [ "$b" != "inst-master" ] ; then
									psql test -c 'CREATE EXTENSION IF NOT EXISTS pg_buffercache;' >> $TS/$r/partitions-$PATTERN.log 2>&1
									psql test -c 'select * from pg_buffercache_partitions;' >> $TS/$r/partitions-$PATTERN.log 2>&1
								fi

								pg_ctl -D $DATADIR -l pg.log stop >> $TS/$r/init.log 2>&1

								tps=$(grep 'tps = ' $TS/$r/pgbench-$PATTERN.log | awk '{print $3}')

								cat $TS/$r/log-$PATTERN.* | awk '{print $3}' | sort -n > $TS/$r/log-$PATTERN.sorted

								n=$(wc -l $TS/$r/log-$PATTERN.sorted | awk '{print $1}')

								median=$(cat $TS/$r/log-$PATTERN.sorted | head -n $((n/2)) | tail -n 1)

								pct25=$(cat $TS/$r/log-$PATTERN.sorted | head -n $((n/4)) | tail -n 1)
								pct75=$(cat $TS/$r/log-$PATTERN.sorted | head -n $((n*3/4)) | tail -n 1)
								pct95=$(cat $TS/$r/log-$PATTERN.sorted | head -n $((n*95/100)) | tail -n 1)
								pct99=$(cat $TS/$r/log-$PATTERN.sorted | head -n $((n*99/100)) | tail -n 1)

								echo $r $b $i $q $c $numa $balance $iomethod $tps $median $pct25 $pct75 $pct95 $pct99 >> $TS/results.csv
								rm -f $TS/r/log-$PATTERN.* $TS/r/log-$PATTERN
							done
						done
					done

				done

			done

		done

	done

done
