#!/bin/bash
#
# Benchmark for the regexp cache (RE_compile_and_cache).
#
# Usage: regexp_cache_bench.sh <install-A> <install-B> [rounds]
#
# Starts a scratch server from each installation, then for each N runs
# a pgbench script that evaluates 10000 regexp matches whose patterns
# cycle through N distinct values.  Runs alternate between A and B so
# that thermal and background noise affect both sides equally.  Prints
# the median latency of each side and the B/A ratio.
#
# Environment: NS (list of N values), DURATION (seconds per run).
# Use release builds without --enable-cassert.

set -e

A=$1
B=$2
ROUNDS=${3:-5}
DURATION=${DURATION:-5}
NS=${NS:-"1 8 32 33 64 1024"}
TMP=$(mktemp -d)

start() {
	"$1/bin/initdb" -D "$TMP/data$2" -A trust >/dev/null
	"$1/bin/pg_ctl" -D "$TMP/data$2" -o "-p $2 -k $TMP" -l "$TMP/log$2" -w start >/dev/null
}

stop() {
	"$1/bin/pg_ctl" -D "$TMP/data$2" -m fast stop >/dev/null
}

run() {
	"$1/bin/pgbench" -n -h "$TMP" -p "$2" -c 1 -T "$DURATION" -f "$3" postgres 2>/dev/null |
		awk '/latency average/ {print $4}'
}

median() {
	printf '%s\n' "$@" | sort -n | awk '{a[NR]=$1} END {print a[int((NR+1)/2)]}'
}

start "$A" 55450
start "$B" 55451
trap 'stop "$A" 55450; stop "$B" 55451; rm -rf "$TMP"' EXIT

printf '%-6s %10s %10s %8s\n' N A_ms B_ms B/A
for N in $NS; do
	SQL=$TMP/q_$N.sql
	cat > "$SQL" <<EOF
SELECT count(*) FROM generate_series(1, 10000) g
WHERE ('item' || g) ~ ('^(item|thing)[0-9]*' || (g % $N) || '\$');
EOF
	as=()
	bs=()
	for r in $(seq 1 "$ROUNDS"); do
		as+=("$(run "$A" 55450 "$SQL")")
		bs+=("$(run "$B" 55451 "$SQL")")
	done
	ma=$(median "${as[@]}")
	mb=$(median "${bs[@]}")
	printf '%-6s %10s %10s %8.3f\n' "$N" "$ma" "$mb" "$(echo "$mb / $ma" | bc -l)"
done
