diff options
| author | Jesse Morgan <jesse@jesterpm.net> | 2016-12-17 21:28:53 -0800 | 
|---|---|---|
| committer | Jesse Morgan <jesse@jesterpm.net> | 2016-12-17 21:28:53 -0800 | 
| commit | 54df2afaa61c6a03cbb4a33c9b90fa572b6d07b8 (patch) | |
| tree | 18147b92b969d25ffbe61935fb63035cac820dd0 /db-4.8.30/test_micro | |
Berkeley DB 4.8 with rust build script for linux.
Diffstat (limited to 'db-4.8.30/test_micro')
26 files changed, 4489 insertions, 0 deletions
| diff --git a/db-4.8.30/test_micro/README b/db-4.8.30/test_micro/README new file mode 100644 index 0000000..2d35358 --- /dev/null +++ b/db-4.8.30/test_micro/README @@ -0,0 +1,84 @@ +# $Id$ + +A simple framework for core Berkeley DB micro-benchmarks, intended for +two purposes: to certify a port of Berkeley DB to a new platform, and +to provide micro-benchmark information between different Berkeley DB +releases. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +To run the tests: + +1. Unpack and build the Berkeley DB releases you want to run against. +(Note that test_micro is only known to work on release 4.0 and later.) + +2. Run the tests: + +	% sh test_micro + +   By default, tests are run for all of the Berkeley DB builds found in +   the current working directory.  A build is identified by its +   top-level name, and is expected to be of the form: + +	   db-<major>.<minor>.<patch> + +   and the fact the Berkeley DB library has been built in the standard +   location in that directory tree (for example, "build_unix/libdb.a". +   Directories with other names and directories without a library will +   be ignored. + +   You can run a subset of the tests using command-line arguments: + +	% sh test_micro 3			# Run test 3 +	% sh test_micro 3-5			# Run tests 3-5 +	% sh test_micro 3-			# Run test 3 to the maximum test +	% sh test_micro -3			# Run tests 1-3 + +   You can run on a subset of the releases using the MAJOR and MINOR +   environment variables: + +	% env MAJOR=4 MINOR=2 sh test_micro	# Run on 4.2.XX +						# Run on 4.1.XX and 4.2.XX +	% env MAJOR=4 MINOR='[12]' sh test_micro + +3. If you want to generate the micro-benchmark output build the HTML +   page after the run: + +	% sh report + +   The output of the tests and the web page are created in the directory +   RUN.hostname (for example, "RUN.abyssinian").  The tests are numeric +   filenames in that directory (for example, "1", "2", "36").  The web +   page output is in the file "hostname.html". + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +To run different test configurations: + +1. Modify the configuration files in the configs/ directory to run the +   tests you want to run.  The configuration file configs/run.std is the +   tests that are run by the test_micro shell script. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +To add a new test program: + +1. Add a new file to the SOURCE directory, and build it as part of +   building the test_micro program.   This will require changes to +   the test_micro shell script, as well as the standard build rules +   for all of the Berkeley DB systems, found in the dist/ directory. + +   The file must output the following line on stdout: + +	# title +	major.minor.patch<tab>operations/second + +   For example: + +	# 10000 Btree database open/close pairs +	3.0.55  29600.69 +	3.1.17  30438.25 + +2. Modify the file test_micro/test_micro.c to exec your new command +   (this should only require changing the cmdlist structure at the top +   of that file). + +3. Modify the test_micro configuration files in the configs/ directory +   to run your new command. diff --git a/db-4.8.30/test_micro/configs/run.small b/db-4.8.30/test_micro/configs/run.small new file mode 100644 index 0000000..6bf408c --- /dev/null +++ b/db-4.8.30/test_micro/configs/run.small @@ -0,0 +1,115 @@ +b_curalloc -c 100 +b_curwalk -c 10 -d 10 -Ss -t btree -w 10 -C 524288 -P 1024 +b_curwalk -c 10 -d 10 -Ss -t hash -w 10 -C 524288 -P 1024 +b_curwalk -c 10 -d 10 -p -t btree -w 10 -C 524288 -P 1024 +b_curwalk -c 10 -d 10 -p -t hash -w 10 -C 524288 -P 1024 +b_curwalk -c 10 -d 10 -pSs -t btree -w 10 -C 524288 -P 1024 +b_curwalk -c 10 -d 10 -pSs -t hash -w 10 -C 524288 -P 1024 +b_curwalk -c 10 -d 10 -ps -t btree -w 10 -C 524288 -P 1024 +b_curwalk -c 10 -d 10 -ps -t hash -w 10 -C 524288 -P 1024 +b_curwalk -c 10 -d 10 -s -t btree -w 10 -C 524288 -P 1024 +b_curwalk -c 10 -d 10 -s -t hash -w 10 -C 524288 -P 1024 +b_curwalk -c 10 -d 100 -t btree -w 10 -C 524288 -P 1024 +b_curwalk -c 10 -d 100 -t hash -w 10 -C 524288 -P 1024 +b_curwalk -c 10 -d 10 -s -t btree -w 10 -C 524288 -P 1024 +b_curwalk -c 100 -d 10 -s -t hash -w 10 -C 524288 -P 1024 +b_curwalk -c 100 -d 10 -t btree -w 10 -C 524288 -P 1024 +b_curwalk -c 100 -d 10 -t hash -w 10 -C 524288 -P 1024 +b_curwalk -c 100 -p -t btree -w 10 -C 524288 -P 1024 +b_curwalk -c 100 -p -t hash -w 10 -C 524288 -P 1024 +b_curwalk -c 100 -p -t queue -w 10 -C 524288 -P 1024 +b_curwalk -c 100 -p -t recno -w 10 -C 524288 -P 1024 +b_curwalk -c 100 -t btree -w 10 -C 524288 -P 1024 +b_curwalk -c 100 -t hash -w 10 -C 524288 -P 1024 +b_curwalk -c 100 -t queue -w 10 -C 524288 -P 1024 +b_curwalk -c 100 -t recno -w 10 -C 524288 -P 1024 + +b_del -c 100 -t btree -C 524288 +b_del -c 100 -t hash -C 524288 +b_del -c 100 -t queue -C 524288 +b_del -c 100 -t recno -C 524288 +b_del -w -c 100 -t btree -C 524288 +b_del -w -c 100 -t hash -C 524288 +b_del -w -c 100 -t queue -C 524288 +b_del -w -c 100 -t recno -C 524288 + +b_get -c 100 -t btree -C 524288 +b_get -c 100 -t hash -C 524288 +b_get -c 100 -t queue -C 524288 +b_get -c 100 -t recno -C 524288 + +b_inmem -d 32 -k 8 -o 10 -P 1024  -C 524288 bulk +b_inmem -d 32 -k 8 -o 10 -P 1024  -C 524288 txn-sync +b_inmem -d 32 -k 8 -o 10 -P 1024  -C 524288 read +b_inmem -d 32 -k 8 -o 100 -P 1024 -C 524288 txn-nosync +b_inmem -d 32 -k 8 -o 100 -P 1024 -C 524288 txn-read +b_inmem -d 32 -k 8 -o 100 -P 1024 -C 524288 txn-write +b_inmem -d 32 -k 8 -o 100 -P 1024 -C 524288 txn-write-nosync +b_inmem -d 32 -k 8 -o 100 -P 1024 -C 524288 write + +b_load -c 100 -t hash -C 524288 +b_load -c 100 -t btree -C 524288 +b_load -c 100 -t queue -C 524288 +b_load -c 100 -t recno -C 524288 +b_load -d -c 100 -t btree -C 524288 +b_load -d -c 100 -t hash -C 524288 + +b_open -c 100 -d -t btree +b_open -c 100 -d -t hash +b_open -c 100 -d -t queue +b_open -c 100 -d -t recno +b_open -c 100 -f -t btree +b_open -c 100 -f -t hash +b_open -c 100 -f -t queue +b_open -c 100 -f -t recno +b_open -c 100 -fd -t btree +b_open -c 100 -fd -t hash +b_open -c 100 -fd -t recno +b_open -c 100 -t btree +b_open -c 100 -t hash +b_open -c 100 -t queue +b_open -c 100 -t recno + +b_put -c 10 -d 64 -t btree -C 524288 +b_put -c 10 -d 64 -t hash -C 524288 +b_put -c 10 -d 64 -t recno -C 524288 +b_put -c 100 -s 10 -t btree -C 524288 +b_put -c 100 -s 10 -t hash -C 524288 +b_put -c 100 -s 10 -t queue -C 524288 +b_put -c 100 -s 10 -t recno -C 524288 +b_put -c 100 -t btree -C 524288 +b_put -c 100 -t hash -C 524288 +b_put -c 100 -t queue -C 524288 +b_put -c 100 -t recno -C 524288 + +b_recover -c 100 -C 524288 + +b_txn -a -c 100 +b_txn -c 100 + +b_txn_write -a -c 100 +b_txn_write -ar -c 100 +b_txn_write -c 100 +b_txn_write -r -c 100 +b_txn_write -rw -c 100 +b_txn_write -w -c 100 + +b_workload -w A -c 100 -g 10 -d 20 -p 1024 -t btree +b_workload -w A -c 100 -g 10 -d 20 -p 1024 -t hash +b_workload -w A -c 100 -g 10 -d 20 -p 1024 -t btree +b_workload -w A -c 100 -g 10 -d 20 -p 1024 -t hash +b_workload -w A -c 100 -g 10 -d 20 -p 1024 -t btree +b_workload -w A -c 100 -g 10 -d 20 -p 1024 -t hash +b_workload -w A -c 100 -g 10 -d 20 -p 1024 -t btree +b_workload -w A -c 100 -g 10 -d 20 -p 1024 -t hash +b_workload -w A -c 100 -g 10 -d 256 -p 1024 -t btree +b_workload -w A -c 100 -g 10 -d 256 -p 1024 -t hash +b_workload -w A -c 100 -g 10 -o -t btree -p 1024 +b_workload -w A -c 100 -g 10 -o -t hash -p 1024 +b_workload -w E -c 100 -g 10 -d 20 -p 1024 -t btree +b_workload -w E -c 100 -g 10 -d 20 -p 1024 -t hash +b_workload -w F -c 100 -g 10 -d 20 -p 1024 -t btree +b_workload -w F -c 100 -g 10 -d 20 -p 1024 -t hash +b_workload -w G -c 100 -g 10 -d 20 -p 1024 -t btree +b_workload -w G -c 100 -g 10 -d 20 -p 1024 -t hash +b_workload -w H -c 100 -d 20 -p 1024 -t hash diff --git a/db-4.8.30/test_micro/configs/run.std b/db-4.8.30/test_micro/configs/run.std new file mode 100644 index 0000000..264e1d9 --- /dev/null +++ b/db-4.8.30/test_micro/configs/run.std @@ -0,0 +1,123 @@ +b_curalloc -c 1000000 + +b_curwalk -c 100 -d 1000 -Ss -t btree -w 100 +b_curwalk -c 100 -d 1000 -Ss -t hash -w 100 +b_curwalk -c 100 -d 1000 -p -t btree -w 100 +b_curwalk -c 100 -d 1000 -p -t hash -w 100 +b_curwalk -c 100 -d 1000 -pSs -t btree -w 100 +b_curwalk -c 100 -d 1000 -pSs -t hash -w 100 +b_curwalk -c 100 -d 1000 -ps -t btree -w 100 +b_curwalk -c 100 -d 1000 -ps -t hash -w 100 +b_curwalk -c 100 -d 1000 -s -t btree -w 100 +b_curwalk -c 100 -d 1000 -s -t hash -w 100 +b_curwalk -c 100 -d 1000 -t btree -w 100 +b_curwalk -c 100 -d 1000 -t hash -w 100 +b_curwalk -c 10000 -d 10 -s -t btree -w 100 +b_curwalk -c 10000 -d 10 -s -t hash -w 100 +b_curwalk -c 10000 -d 10 -t btree -w 100 +b_curwalk -c 10000 -d 10 -t hash -w 100 +b_curwalk -c 100000 -p -t btree -w 100 +b_curwalk -c 100000 -p -t hash -w 100 +b_curwalk -c 100000 -p -t queue -w 100 +b_curwalk -c 100000 -p -t recno -w 100 +b_curwalk -c 100000 -t btree -w 100 +b_curwalk -c 100000 -t hash -w 100 +b_curwalk -c 100000 -t queue -w 100 +b_curwalk -c 100000 -t recno -w 100 + +b_del -c 100000 -t btree +b_del -c 100000 -t hash +b_del -c 100000 -t queue +b_del -c 100000 -t recno +b_del -w -c 100000 -t btree +b_del -w -c 100000 -t hash +b_del -w -c 100000 -t queue +b_del -w -c 100000 -t recno + +b_get -c 1000000 -t btree +b_get -c 1000000 -t hash +b_get -c 1000000 -t queue +b_get -c 1000000 -t recno + +b_inmem -d 32 -k 8 -o 100000 -P 32768 bulk +b_inmem -d 32 -k 8 -o 100000 -P 32768 txn-sync +b_inmem -d 32 -k 8 -o 1000000 -P 32768 read +b_inmem -d 32 -k 8 -o 1000000 -P 32768 txn-nosync +b_inmem -d 32 -k 8 -o 1000000 -P 32768 txn-read +b_inmem -d 32 -k 8 -o 1000000 -P 32768 txn-write +b_inmem -d 32 -k 8 -o 1000000 -P 32768 txn-write-nosync +b_inmem -d 32 -k 8 -o 1000000 -P 32768 write + +b_load -c 100000 -t hash +b_load -c 1000000 -t btree +b_load -c 1000000 -t queue +b_load -c 1000000 -t recno +b_load -d -c 1000000 -t btree +b_load -d -c 1000000 -t hash + +b_open -c 10000 -d -t btree +b_open -c 10000 -d -t hash +b_open -c 10000 -d -t queue +b_open -c 10000 -d -t recno +b_open -c 10000 -f -t btree +b_open -c 10000 -f -t hash +b_open -c 10000 -f -t queue +b_open -c 10000 -f -t recno +b_open -c 10000 -fd -t btree +b_open -c 10000 -fd -t hash +b_open -c 10000 -fd -t recno +b_open -c 10000 -t btree +b_open -c 10000 -t hash +b_open -c 10000 -t queue +b_open -c 10000 -t recno + +b_put -c 100000 -d 204800 -t btree +b_put -c 100000 -d 204800 -t hash +b_put -c 100000 -d 204800 -t recno +b_put -c 1000000 -s 10 -t btree +b_put -c 1000000 -s 10 -t hash +b_put -c 1000000 -s 10 -t queue +b_put -c 1000000 -s 10 -t recno +b_put -c 1000000 -t btree +b_put -c 1000000 -t hash +b_put -c 1000000 -t queue +b_put -c 1000000 -t recno + +b_recover -c 1000000 + +b_txn -a -c 1000000 +b_txn -c 1000000 + +b_txn_write -a -c 100000 +b_txn_write -ar -c 100000 +b_txn_write -c 10000 +b_txn_write -r -c 10000 +b_txn_write -rw -c 100000 +b_txn_write -w -c 100000 + +b_workload -w A -c 100000 -g 10 -d 20 -p 1024 -t btree +b_workload -w A -c 100000 -g 10 -d 20 -p 1024 -t hash +b_workload -w A -c 100000 -g 10 -d 20 -p 32768 -t btree +b_workload -w A -c 100000 -g 10 -d 20 -p 32768 -t hash +b_workload -w A -c 100000 -g 10 -d 20 -p 4096 -t btree +b_workload -w A -c 100000 -g 10 -d 20 -p 4096 -t hash +b_workload -w A -c 100000 -g 10 -d 20 -p 8192 -t btree +b_workload -w A -c 100000 -g 10 -d 20 -p 8192 -t hash +b_workload -w A -c 100000 -g 10 -d 256 -p 1024 -t btree +b_workload -w A -c 100000 -g 10 -d 256 -p 1024 -t hash +b_workload -w A -c 100000 -o -t btree +b_workload -w A -c 100000 -o -t hash +b_workload -w E -c 100000 -g 10 -d 20 -p 1024 -t btree +b_workload -w E -c 100000 -g 10 -d 20 -p 1024 -t hash +b_workload -w F -c 100000 -g 10 -d 20 -p 1024 -t btree +b_workload -w F -c 100000 -g 10 -d 20 -p 1024 -t hash +b_workload -w G -c 100000 -g 10 -d 20 -p 1024 -t btree +b_workload -w G -c 100000 -g 10 -d 20 -p 1024 -t hash +b_workload -w H -c 10000000 -d 20 -p 1024 -t hash + +b_latch -c 100000000 +b_latch -c 100000000 -n 1 +b_latch -c 100000000 -n 2 +b_latch -c 100000000 -n 4 +b_latch -c 100000000 -n 8 +b_latch -c 100000000 -n 64 diff --git a/db-4.8.30/test_micro/configs/run.workload b/db-4.8.30/test_micro/configs/run.workload new file mode 100644 index 0000000..4d289e2 --- /dev/null +++ b/db-4.8.30/test_micro/configs/run.workload @@ -0,0 +1,38 @@ +b_workload -m 1 -w A -v -c 100000 -o -t hash +b_workload -m 2 -w A -v -c 100000 -o -t btree +b_workload -m 3 -w A -v -c 100000 -g 10 -d 20 -p 32768 -t hash +b_workload -m 4 -w A -v -c 100000 -g 10 -d 20 -p 32768 -t btree +b_workload -m 5 -w A -v -c 100000 -g 10 -d 20 -p 8192 -t hash +b_workload -m 6 -w A -v -c 100000 -g 10 -d 20 -p 8192 -t btree +b_workload -m 7 -w A -v -c 100000 -g 10 -d 20 -p 4096 -t hash +b_workload -m 8 -w A -v -c 100000 -g 10 -d 20 -p 4096 -t btree +b_workload -m 9 -w A -v -c 100000 -g 10 -d 20 -p 1024 -t hash +b_workload -m 10 -w A -v -c 100000 -g 10 -d 20 -p 1024 -t btree +b_workload -m 11 -w A -v -c 10000 -g 10 -d 256 -p 1024 -t hash +b_workload -m 12 -w A -v -c 10000 -g 10 -d 256 -p 1024 -t btree +b_workload -m 13 -w F -v -c 100000 -g 10 -d 20 -p 1024 -t hash +b_workload -m 14 -w F -v -c 100000 -g 10 -d 20 -p 1024 -t btree +b_workload -m 15 -w G -v -c 100000 -g 10 -d 20 -p 1024 -t hash +b_workload -m 16 -w G -v -c 100000 -g 10 -d 20 -p 1024 -t btree +# Run put/get(G) with different page sizes, since fill factor +# is interesting when not deleting all of the elements. +b_workload -m 17 -w E -v -c 100000 -g 10 -d 20 -p 32768 -t hash +b_workload -m 18 -w E -v -c 100000 -g 10 -d 20 -p 32768 -t btree +b_workload -m 19 -w E -v -c 100000 -g 10 -d 20 -p 8192 -t hash +b_workload -m 20 -w E -v -c 100000 -g 10 -d 20 -p 8192 -t btree +b_workload -m 21 -w E -v -c 100000 -g 10 -d 20 -p 4096 -t hash +b_workload -m 22 -w E -v -c 100000 -g 10 -d 20 -p 4096 -t btree +b_workload -m 23 -w E -v -c 100000 -g 10 -d 20 -p 1024 -t hash +b_workload -m 24 -w E -v -c 100000 -g 10 -d 20 -p 1024 -t btree +b_workload -m 25 -w E -v -c 10000 -g 10 -d 256 -p 1024 -t hash +b_workload -m 26 -w E -v -c 10000 -g 10 -d 256 -p 1024 -t btree +b_workload -m 27 -w E -v -c 100000 -g 10 -o -d 10 -p 1024 -t hash +b_workload -m 28 -w E -v -c 100000 -g 10 -o -d 10 -p 1024 -t btree +b_workload -m 29 -w A -v -c 10000 -g 10 -d 1024 -p 512 -t hash +b_workload -m 30 -w A -v -c 10000 -g 10 -d 1024 -p 512 -t btree +b_workload -m 31 -w H -v -c 1000000 -d 20 -p 8192 -t hash +b_workload -m 32 -w H -v -c 1000000 -d 20 -p 8192 -t btree +b_workload -m 33 -w H -v -c 1000000 -d 20 -p 512 -t hash +b_workload -m 34 -w H -v -c 1000000 -d 20 -p 512 -t btree +b_workload -m 35 -w H -v -c 10000000 -d 20 -p 512 -t hash +b_workload -m 36 -w H -v -c 10000000 -d 20 -p 512 -t btree diff --git a/db-4.8.30/test_micro/report b/db-4.8.30/test_micro/report new file mode 100644 index 0000000..c7358db --- /dev/null +++ b/db-4.8.30/test_micro/report @@ -0,0 +1,121 @@ +#! /bin/sh +# +# $Id$ + +# Use our pathname to locate the absolute path for our awk scripts. +t=`dirname $0` +h=`(cd $t && echo $PWD)` + +# We need a temporary file, and we need to clean it up after failure. +tmp="$PWD/__t" +trap 'rm -f $tmp; exit 1' 1 2 3 13 15 +trap 'rm -f $tmp; exit 0' 0 + +# header -- +#	Output HTML page header. +#	$1: directory name. +header() +{ +	echo "<html>" +	echo "<head>" +	machine=`echo $1 | sed 's/.*\.//'` +	echo "<title>Berkeley DB test_micro run: $machine</title>" +	echo "</head>" +	echo "<body bgcolor=white>" +	echo "<center><h1>Berkeley DB test_micro run: $machine</h1></center>" +	echo "<p align=right>`date`</p>" +	test -f UNAME && cat UNAME +} + +# footer -- +#	Output HTML page footer. +footer() +{ +	echo "</body>" +	echo "</html>" +} + +# table -- +#	Create a table. +#	$1: output file +table() +{ +	title="Test $1: `egrep '^#' $1 | sort -u | sed 's/^#[	 ]*//'`" +	echo "<hr size=1 noshade>" +	echo "<table cellspacing=0 cellpadding=0 border=0>" +	echo "<th align=left colspan=2>$title</th>" +	echo "<tr>" +	echo "<th align=right>Release</th>" +	echo "<th align=center>Operations/second</th>" +	echo "</tr>" + +	# You can set the MAJOR and MINOR environment variables to limit +	# the BDB releases for which a report is created. +	# +	# Process the output into a single line per release. +	egrep "^${MAJOR:-[0-9][0-9]*}.${MINOR:-*}" $1 | +	awk -f $h/report.awk | +	sort -n > $tmp + +	# Get the release count, and maximum value. +	nrel=`wc -l $tmp` +	max=`sort -k 2 -n -t ":" < $tmp | tail -1 | awk -F: '{print $2}'` + +	# Display the output. +	IFS=":" +	cat $tmp | while true; do +		# release, average, runs, percent, standard deviation +		read rel avg runs percent rsd +		if test "X$rel" = "X" ; then +			break; +		fi + +		# echo "read: rel $rel, avg $avg, runs $runs, percent $percent, rsd $rsd" > /dev/stderr + +		echo "<tr>" +		echo "<td align=right width=80><pre>$rel</pre></td>" +		echo "<td>" +		echo "<table>" +		echo "<tr>" +		if [ "$max" = "0.00" ];then +			t=0 +		else +			t=`echo "400 * ($avg/($max + $max/10))" | bc -l` +		fi +		t=`printf %.0f $t` +		echo "<td bgcolor='#003366' width=$t> </td>" +		t=`echo "400 - $t" | bc` +		echo "<td bgcolor='#CCCCCC' width=$t> </td>" +		echo "<td>  </td>" +		echo "<td align=right width=100><pre>$avg</pre></td>" +		if test "X$percent" != "X" -o "X$rsd" != "X"; then +			echo -n "<td align=right><pre>  (" +			if test "X$percent" = "X"; then +				echo -n '***' +			else +				echo -n "-$percent" +			fi +			if test "X$rsd" != "X"; then +				echo -n ", $rsd rsd, $runs runs" +			fi +			echo ")</pre></td>" +		fi +		echo "</tr>" +		echo "</table>" +		echo "</tr>" +	done +	echo "</table>" +} + +for i in RUN.*; do +	echo "Building $i..." +	name=`echo $i | sed 's/RUN.//'` +	(cd $i +	header $i +	for j in `ls [0-9]* | sort -n`; do +		table $j +	done +	footer) > $i/$name.html +done + +exit 0 diff --git a/db-4.8.30/test_micro/report.awk b/db-4.8.30/test_micro/report.awk new file mode 100644 index 0000000..6ae3303 --- /dev/null +++ b/db-4.8.30/test_micro/report.awk @@ -0,0 +1,40 @@ +# $Id$ + +/^[^#]/ { +	total[$1] += $2 +	sum[$1] += $2 * $2 +	++count[$1]; +} +END { +	# Compute the average, find the maximum. +	for (i in total) { +		avg[i] = total[i] / count[i]; +		if (max < avg[i]) +			max = avg[i] +	} + +	for (i in total) { +		# Calculate variance by raw score method. +		var = (sum[i] - ((total[i] * total[i]) / count[i])) / count[i]; + +		# The standard deviation is the square root of the variance. +		stdv = sqrt(var); + +		# Display the release value, the average score, and run count. +		printf("%s:%.2f:%d:", i, avg[i],  count[i]); + +		# If this run wasn't the fastest, display the percent by which +		# this run was slower. +		if (max != avg[i]) +			printf("%.0f%%", ((max - avg[i]) / max) * 100); + +		printf(":"); + +		# If there was more than a single run, display the relative +		# standard deviation. +		if (count[i] >  1) +			printf("%.0f%%", stdv * 100 / avg[i]); + +		printf("\n"); +	} +} diff --git a/db-4.8.30/test_micro/source/LIST b/db-4.8.30/test_micro/source/LIST new file mode 100644 index 0000000..8c02b4a --- /dev/null +++ b/db-4.8.30/test_micro/source/LIST @@ -0,0 +1,101 @@ +Test list: + +b_curalloc +	Cursor allocation + +	usage: b_curalloc [-c count] + +	-c	Cursor count + +b_curwalk +	Walk a cursor through N records + +	usage: b_curwalk [-pSs] [-C cachesz] +	    [-c cnt] [-d dupcnt] [-P pagesz] [-t type] [-w walkcnt] +	-C	Cache size +	-c	Record count +	-d	Duplicate record count +	-P	Page size +	-p	Walk backward instead of forward +	-S	Skip duplicates +	-s	Sort duplicates +	-t	Database type (B | H | Q | R) + +b_del +	Delete records + +	usage: b_del [-w] [-C cachesz] [-c count] [-t type] + +	-C	Cache size +	-c	Record count +	-t	Database type (B | H | Q | R) +	-w	Delete through cursor + +b_get +	Read records + +	usage: b_get [-C cachesz] [-c count] [-t type] + +	-C	Cache size +	-c	Record count +	-t	Database type (B | H | Q | R) + +b_load +	Insert records + +	usage: b_load [-d] [-C cachesz] [-c count] [-t type] + +	-C	Cache size +	-c	Record count +	-d	Use duplicate records +	-t	Database type (B | H | Q | R) + +b_open +	Database open/close + +	usage: b_open [-df] [-c count] [-t type] + +	-d	Open/close a subdatabase +	-f	Open/close a physical file +	-c	Open/close count +	-t	Database type (B | H | Q | R) + +b_put +	Overwrite record  + +	usage: b_put [-C cachesz] +	    [-c count] [-d bytes] [-s secondaries] [-t type] + +	-C	Cache size +	-c	Record count +	-d	Data size +	-s	Number of secondaries +	-t	Database type (B | H | Q | R) + +b_recover +	Run recovery + +	usage: b_recover [-C cachesz] [-c count] + +	-C	Cache size +	-c	Transactions to recover + +b_txn +	Abort or commit a transaction containing no operations + +	usage: b_txn [-a] [-c count] + +	-a	Abort rather than commit +	-c	Transaction count + +b_txn_write +	Write/commit transaction + +	usage: b_txn_write [-arw] [-c count] + +	-a	nosync +	-c	Transaction count +	-r	Configure replication stub callback +	-w	write-nosync + +b_workload diff --git a/db-4.8.30/test_micro/source/b_curalloc.c b/db-4.8.30/test_micro/source/b_curalloc.c new file mode 100644 index 0000000..410d720 --- /dev/null +++ b/db-4.8.30/test_micro/source/b_curalloc.c @@ -0,0 +1,69 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2005-2009 Oracle.  All rights reserved. + * + * $Id$ + */ +#include "bench.h" + +static int usage(void); + +int +b_curalloc(int argc, char *argv[]) +{ +	extern char *optarg; +	extern int optind; +	DB *dbp; +	DBC *curp; +	int ch, i, count; + +	count = 100000; +	while ((ch = getopt(argc, argv, "c:")) != EOF) +		switch (ch) { +		case 'c': +			count = atoi(optarg); +			break; +		case '?': +		default: +			return (usage()); +		} +	argc -= optind; +	argv += optind; +	if (argc != 0) +		return (usage()); + +	/* Create the database. */ +	DB_BENCH_ASSERT(db_create(&dbp, NULL, 0) == 0); +	dbp->set_errfile(dbp, stderr); + +#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 +	DB_BENCH_ASSERT(dbp->open( +	    dbp, NULL, TESTFILE, NULL, DB_BTREE, DB_CREATE, 0666) == 0); +#else +	DB_BENCH_ASSERT( +	    dbp->open(dbp, TESTFILE, NULL, DB_BTREE, DB_CREATE, 0666) == 0); +#endif + +	/* Allocate a cursor count times. */ +	TIMER_START; +	for (i = 0; i < count; ++i) { +		DB_BENCH_ASSERT(dbp->cursor(dbp, NULL, &curp, 0) == 0); +		DB_BENCH_ASSERT(curp->c_close(curp) == 0); +	} +	TIMER_STOP; + +	printf("# %d cursor allocations\n", count); +	TIMER_DISPLAY(count); + +	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0); + +	return (0); +} + +static int +usage() +{ +	(void)fprintf(stderr, "usage: b_curalloc [-c count]\n"); +	return (EXIT_FAILURE); +} diff --git a/db-4.8.30/test_micro/source/b_curwalk.c b/db-4.8.30/test_micro/source/b_curwalk.c new file mode 100644 index 0000000..8e935f2 --- /dev/null +++ b/db-4.8.30/test_micro/source/b_curwalk.c @@ -0,0 +1,208 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2005-2009 Oracle.  All rights reserved. + * + * $Id$ + */ +#include "bench.h" + +static int usage(void); + +int +b_curwalk(int argc, char *argv[]) +{ +	extern char *optarg; +	extern int optind; +	DB *dbp; +	DBTYPE type; +	DBC *dbc; +	DBT key, data; +	db_recno_t recno; +	u_int32_t cachesize, pagesize, walkflags; +	int ch, i, count, dupcount, j; +	int prev, ret, skipdupwalk, sorted, walkcount; +	char *ts, dbuf[32], kbuf[32]; + +	type = DB_BTREE; +	cachesize = 10 * MEGABYTE; +	pagesize = 16 * 1024; +	count = 100000; +	dupcount = prev = skipdupwalk = sorted = 0; +	walkcount = 1000; +	ts = "Btree"; +	while ((ch = getopt(argc, argv, "C:c:d:P:pSst:w:")) != EOF) +		switch (ch) { +		case 'C': +			cachesize = (u_int32_t)atoi(optarg); +			break; +		case 'c': +			count = atoi(optarg); +			break; +		case 'd': +			dupcount = atoi(optarg); +			break; +		case 'P': +			pagesize = (u_int32_t)atoi(optarg); +			break; +		case 'p': +			prev = 1; +			break; +		case 'S': +			skipdupwalk = 1; +			break; +		case 's': +			sorted = 1; +			break; +		case 't': +			switch (optarg[0]) { +			case 'B': case 'b': +				ts = "Btree"; +				type = DB_BTREE; +				break; +			case 'H': case 'h': +				if (b_util_have_hash()) +					return (0); +				ts = "Hash"; +				type = DB_HASH; +				break; +			case 'Q': case 'q': +				if (b_util_have_queue()) +					return (0); +				ts = "Queue"; +				type = DB_QUEUE; +				break; +			case 'R': case 'r': +				ts = "Recno"; +				type = DB_RECNO; +				break; +			default: +				return (usage()); +			} +			break; +		case 'w': +			walkcount = atoi(optarg); +			break; +		case '?': +		default: +			return (usage()); +		} +	argc -= optind; +	argv += optind; +	if (argc != 0) +		return (usage()); + +	/* +	 * Queue and Recno don't support duplicates. +	 */ +	if (dupcount != 0 && (type == DB_QUEUE || type == DB_RECNO)) { +		fprintf(stderr, +		    "b_curwalk: Queue and Recno don't support duplicates\n"); +		return (usage()); +	} + +#if DB_VERSION_MAJOR < 3 || DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0 +#define	DB_PREV_NODUP	0 +	/* +	 * DB_PREV_NODUP wasn't available until after 3.0.55. +	 * +	 * For some reason, testing sorted duplicates doesn't work either. +	 * I don't really care about 3.0.55 any more, just ignore it. +	 */ +	return (0); +#endif +	/* Create the database. */ +	DB_BENCH_ASSERT(db_create(&dbp, NULL, 0) == 0); +	DB_BENCH_ASSERT(dbp->set_cachesize(dbp, 0, cachesize, 0) == 0); +	DB_BENCH_ASSERT(dbp->set_pagesize(dbp, pagesize) == 0); +	dbp->set_errfile(dbp, stderr); + +	/* Set record length for Queue. */ +	if (type == DB_QUEUE) +		DB_BENCH_ASSERT(dbp->set_re_len(dbp, 20) == 0); + +	/* Set duplicates flag. */ +	if (dupcount != 0) +		DB_BENCH_ASSERT( +		    dbp->set_flags(dbp, sorted ? DB_DUPSORT : DB_DUP) == 0); + +#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 +	DB_BENCH_ASSERT(dbp->open( +	    dbp, NULL, TESTFILE, NULL, type, DB_CREATE, 0666) == 0); +#else +	DB_BENCH_ASSERT(dbp->open( +	    dbp, TESTFILE, NULL, type, DB_CREATE, 0666) == 0); +#endif + +	/* Initialize the data. */ +	memset(&key, 0, sizeof(key)); +	memset(&data, 0, sizeof(data)); + +	/* Insert count in-order key/data pairs. */ +	data.data = dbuf; +	data.size = 20; +	if (type == DB_BTREE || type == DB_HASH) { +		key.size = 10; +		key.data = kbuf; +		for (i = 0; i < count; ++i) { +			(void)snprintf(kbuf, sizeof(kbuf), "%010d", i); +			for (j = 0; j <= dupcount; ++j) { +				(void)snprintf(dbuf, sizeof(dbuf), "%020d", j); +				DB_BENCH_ASSERT( +				    dbp->put(dbp, NULL, &key, &data, 0) == 0); +			} +		} +	} else { +		key.data = &recno; +		key.size = sizeof(recno); +		for (i = 0, recno = 1; i < count; ++i, ++recno) +			DB_BENCH_ASSERT( +			    dbp->put(dbp, NULL, &key, &data, 0) == 0); +	} + +	walkflags = prev ? +	    (skipdupwalk ? DB_PREV_NODUP : DB_PREV) : +	    (skipdupwalk ? DB_NEXT_NODUP : DB_NEXT); + +	/* Walk the cursor through the tree N times. */ +	TIMER_START; +	for (i = 0; i < walkcount; ++i) { +		DB_BENCH_ASSERT(dbp->cursor(dbp, NULL, &dbc, 0) == 0); +		while ((ret = dbc->c_get(dbc, &key, &data, walkflags)) == 0) +			; +		DB_BENCH_ASSERT(ret == DB_NOTFOUND); +		DB_BENCH_ASSERT(dbc->c_close(dbc) == 0); +	} +	TIMER_STOP; + +	printf("# %d %s %s cursor of %d 10/20 byte key/data items", +	    walkcount, ts, prev ? +	    (skipdupwalk ? "DB_PREV_NODUP" : "DB_PREV") : +	    (skipdupwalk ? "DB_NEXT_NODUP" : "DB_NEXT"), +	    count); +	if (dupcount != 0) +		printf(" with %d dups", dupcount); +	printf("\n"); + +	/* +	 * An "operation" is traversal of a single key/data pair -- not a +	 * return of the key/data pair, since some versions of this test +	 * skip duplicate key/data pairs. +	 * +	 * Use a "double" so we don't overflow. +	 */ +	TIMER_DISPLAY((double)count * walkcount); + +	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0); + +	return (EXIT_SUCCESS); +} + +static int +usage() +{ +	(void)fprintf(stderr, "%s\n\t%s\n", +	    "usage: b_curwalk [-pSs] [-C cachesz]", +	    "[-c cnt] [-d dupcnt] [-P pagesz] [-t type] [-w walkcnt]"); +	return (EXIT_FAILURE); +} diff --git a/db-4.8.30/test_micro/source/b_del.c b/db-4.8.30/test_micro/source/b_del.c new file mode 100644 index 0000000..6385267 --- /dev/null +++ b/db-4.8.30/test_micro/source/b_del.c @@ -0,0 +1,166 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2005-2009 Oracle.  All rights reserved. + * + * $Id$ + */ +#include "bench.h" + +static int usage(void); + +int +b_del(int argc, char *argv[]) +{ +	extern char *optarg; +	extern int optind; +	DB *dbp; +	DBC *dbc; +	DBT key, data; +	DBTYPE type; +	db_recno_t recno; +	u_int32_t cachesize; +	int ch, i, count, ret, use_cursor; +	char *ts, buf[32]; + +	type = DB_BTREE; +	cachesize = MEGABYTE; +	count = 100000; +	use_cursor = 0; +	ts = "Btree"; +	while ((ch = getopt(argc, argv, "C:c:t:w")) != EOF) +		switch (ch) { +		case 'C': +			cachesize = (u_int32_t)atoi(optarg); +			break; +		case 'c': +			count = atoi(optarg); +			break; +		case 't': +			switch (optarg[0]) { +			case 'B': case 'b': +				ts = "Btree"; +				type = DB_BTREE; +				break; +			case 'H': case 'h': +				if (b_util_have_hash()) +					return (0); +				ts = "Hash"; +				type = DB_HASH; +				break; +			case 'Q': case 'q': +				if (b_util_have_queue()) +					return (0); +				ts = "Queue"; +				type = DB_QUEUE; +				break; +			case 'R': case 'r': +				ts = "Recno"; +				type = DB_RECNO; +				break; +			default: +				return (usage()); +			} +			break; +		case 'w': +			use_cursor = 1; +			break; +		case '?': +		default: +			return (usage()); +		} +	argc -= optind; +	argv += optind; +	if (argc != 0) +		return (usage()); + +	/* Create the database. */ +	DB_BENCH_ASSERT(db_create(&dbp, NULL, 0) == 0); +	DB_BENCH_ASSERT(dbp->set_cachesize(dbp, 0, cachesize, 0) == 0); +	dbp->set_errfile(dbp, stderr); + +	/* Set record length for Queue. */ +	if (type == DB_QUEUE) +		DB_BENCH_ASSERT(dbp->set_re_len(dbp, 20) == 0); + +#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 +	DB_BENCH_ASSERT( +	    dbp->open(dbp, NULL, TESTFILE, NULL, type, DB_CREATE, 0666) == 0); +#else +	DB_BENCH_ASSERT( +	    dbp->open(dbp, TESTFILE, NULL, type, DB_CREATE, 0666) == 0); +#endif + +	/* Initialize the data. */ +	memset(&key, 0, sizeof(key)); +	memset(&data, 0, sizeof(data)); +	data.data = "01234567890123456789"; +	data.size = 20; + +	/* Store a key/data pair. */ +	switch (type) { +	case DB_BTREE: +	case DB_HASH: +		key.data = buf; +		key.size = 10; +		break; +	case DB_QUEUE: +	case DB_RECNO: +		key.data = &recno; +		key.size = sizeof(recno); +		break; +	case DB_UNKNOWN: +		b_util_abort(); +		break; +	} + +	/* Insert count in-order key/data pairs. */ +	if (type == DB_BTREE || type == DB_HASH) +		for (i = 0; i < count; ++i) { +			(void)snprintf(buf, sizeof(buf), "%010d", i); +			DB_BENCH_ASSERT( +			    dbp->put(dbp, NULL, &key, &data, 0) == 0); +		} +	else +		for (i = 0, recno = 1; i < count; ++i, ++recno) +			DB_BENCH_ASSERT( +			    dbp->put(dbp, NULL, &key, &data, 0) == 0); + +	/* Delete the records. */ +	TIMER_START; +	if (use_cursor) { +		DB_BENCH_ASSERT(dbp->cursor(dbp, NULL, &dbc, 0) == 0); +		while ((ret = dbc->c_get(dbc, &key, &data, DB_NEXT)) == 0) +			DB_BENCH_ASSERT(dbc->c_del(dbc, 0) == 0); +		DB_BENCH_ASSERT (ret == DB_NOTFOUND); +	} else +		if (type == DB_BTREE || type == DB_HASH) +			for (i = 0; i < count; ++i) { +				(void)snprintf(buf, sizeof(buf), "%010d", i); +				DB_BENCH_ASSERT( +				    dbp->del(dbp, NULL, &key, 0) == 0); +			} +		else +			for (i = 0, recno = 1; i < count; ++i, ++recno) +				DB_BENCH_ASSERT( +				    dbp->del(dbp, NULL, &key, 0) == 0); + +	TIMER_STOP; + +	printf( +    "# %d %s database in-order delete of 10/20 byte key/data pairs using %s\n", +	    count, ts, use_cursor ? "a cursor" : "the key"); +	TIMER_DISPLAY(count); + +	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0); + +	return (0); +} + +static int +usage() +{ +	(void)fprintf(stderr, +	    "usage: b_del [-w] [-C cachesz] [-c count] [-t type]\n"); +	return (EXIT_FAILURE); +} diff --git a/db-4.8.30/test_micro/source/b_get.c b/db-4.8.30/test_micro/source/b_get.c new file mode 100644 index 0000000..b63f02a --- /dev/null +++ b/db-4.8.30/test_micro/source/b_get.c @@ -0,0 +1,162 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2005-2009 Oracle.  All rights reserved. + * + * $Id$ + */ +#include "bench.h" + +static int usage(void); + +u_int32_t part_callback(dbp, dbt) +	DB *dbp; +	DBT *dbt; +{ +	extern u_int32_t __ham_func2(DB *, const void *, u_int32_t); +	return (__ham_func2(dbp, dbt->data, dbt->size)); +} + +int +b_get(int argc, char *argv[]) +{ +	extern char *optarg; +	extern int optind; +	DB *dbp; +	DBTYPE type; +	DBT key, data; +	db_recno_t recno; +	u_int32_t cachesize; +	int ch, i, count; +	char *ts; + +	type = DB_BTREE; +	cachesize = MEGABYTE; +	count = 100000; +	ts = "Btree"; +	while ((ch = getopt(argc, argv, "C:c:t:")) != EOF) +		switch (ch) { +		case 'C': +			cachesize = (u_int32_t)atoi(optarg); +			break; +		case 'c': +			count = atoi(optarg); +			break; +		case 't': +			switch (optarg[0]) { +			case 'B': case 'b': +				ts = "Btree"; +				type = DB_BTREE; +				break; +			case 'H': case 'h': +				if (b_util_have_hash()) +					return (0); +				ts = "Hash"; +				type = DB_HASH; +				break; +			case 'Q': case 'q': +				if (b_util_have_queue()) +					return (0); +				ts = "Queue"; +				type = DB_QUEUE; +				break; +			case 'R': case 'r': +				ts = "Recno"; +				type = DB_RECNO; +				break; +			default: +				return (usage()); +			} +			break; +		case '?': +		default: +			return (usage()); +		} +	argc -= optind; +	argv += optind; +	if (argc != 0) +		return (usage()); + +	/* Create the database. */ +	DB_BENCH_ASSERT(db_create(&dbp, NULL, 0) == 0); +	DB_BENCH_ASSERT(dbp->set_cachesize(dbp, 0, cachesize, 0) == 0); +	dbp->set_errfile(dbp, stderr); + +	/* Set record length for Queue. */ +	if (type == DB_QUEUE) +		DB_BENCH_ASSERT(dbp->set_re_len(dbp, 10) == 0); +#if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 7 && DB_VERSION_PATCH == 30 +	if (type == DB_BTREE) { +		DBT keys[3]; + +		memset(keys, 0, sizeof(keys)); +		keys[0].data = "a"; +		keys[0].size = 1; +		keys[1].data = "b"; +		keys[1].size = 1; +		keys[2].data = "c"; +		keys[2].size = 1; + +		DB_BENCH_ASSERT( +		     dbp->set_partition_keys(dbp, 4, keys, NULL) == 0); +	} + +	if (type == DB_HASH) { +		DB_BENCH_ASSERT( +		    dbp->set_partition_callback(dbp, 4, part_callback) == 0); +	} +#endif + +#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 +	DB_BENCH_ASSERT( +	    dbp->open(dbp, NULL, TESTFILE, NULL, type, DB_CREATE, 0666) == 0); +#else +	DB_BENCH_ASSERT( +	    dbp->open(dbp, TESTFILE, NULL, type, DB_CREATE, 0666) == 0); +#endif + +	/* Store a key/data pair. */ +	memset(&key, 0, sizeof(key)); +	memset(&data, 0, sizeof(data)); +	switch (type) { +	case DB_BTREE: +	case DB_HASH: +		key.data = "aaaaa"; +		key.size = 5; +		break; +	case DB_QUEUE: +	case DB_RECNO: +		recno = 1; +		key.data = &recno; +		key.size = sizeof(recno); +		break; +	case DB_UNKNOWN: +		b_util_abort(); +		break; +	} +	data.data = "bbbbb"; +	data.size = 5; + +	DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0); + +	/* Retrieve the key/data pair count times. */ +	TIMER_START; +	for (i = 0; i < count; ++i) +		DB_BENCH_ASSERT(dbp->get(dbp, NULL, &key, &data, 0) == 0); +	TIMER_STOP; + +	printf("# %d %s database get of cached key/data item\n", count, ts); +	TIMER_DISPLAY(count); + +	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0); + +	return (0); +} + +static int +usage() +{ +	(void)fprintf(stderr, +	    "usage: b_get [-C cachesz] [-c count] [-t type]\n"); +	return (EXIT_FAILURE); +} diff --git a/db-4.8.30/test_micro/source/b_inmem.c b/db-4.8.30/test_micro/source/b_inmem.c new file mode 100644 index 0000000..ee0ddda --- /dev/null +++ b/db-4.8.30/test_micro/source/b_inmem.c @@ -0,0 +1,426 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2005-2009 Oracle.  All rights reserved. + * + * $Id$ + */ + +#include "bench.h" + +#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 0 +/* + * The in-memory tests don't run on early releases of Berkeley DB. + */ +#undef	MEGABYTE +#define	MEGABYTE	(1024 * 1024) + +u_int32_t bulkbufsize = 4 * MEGABYTE; +u_int32_t cachesize = 32 * MEGABYTE; +u_int32_t datasize = 32; +u_int32_t keysize = 8; +u_int32_t logbufsize = 8 * MEGABYTE; +u_int32_t numitems; +u_int32_t pagesize = 32 * 1024; + +FILE *fp; + +static void op_ds __P((u_int, int)); +static void op_ds_bulk __P((u_int, u_int *)); +static void op_tds __P((u_int, int, u_int32_t, u_int32_t)); +static int  usage __P((void)); + +static void +op_ds(u_int ops, int update) +{ +	DB_ENV *dbenv; +	char *letters = "abcdefghijklmnopqrstuvwxuz"; +	DB *dbp; +	DBT key, data; +	char *keybuf, *databuf; +	DB_MPOOL_STAT  *gsp; + +	DB_BENCH_ASSERT((keybuf = malloc(keysize)) != NULL); +	DB_BENCH_ASSERT((databuf = malloc(datasize)) != NULL); + +	memset(&key, 0, sizeof(key)); +	memset(&data, 0, sizeof(data)); +	key.data = keybuf; +	key.size = keysize; +	memset(keybuf, 'a', keysize); + +	data.data = databuf; +	data.size = datasize; +	memset(databuf, 'b', datasize); + +	DB_BENCH_ASSERT(db_create(&dbp, NULL, 0) == 0); +	dbenv = dbp->dbenv; +	dbp->set_errfile(dbp, stderr); + +	DB_BENCH_ASSERT(dbp->set_pagesize(dbp, pagesize) == 0); +	DB_BENCH_ASSERT(dbp->open( +	    dbp, NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0666) == 0); + +	(void)dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR); + +	if (update) { +		TIMER_START; +		for (; ops > 0; --ops) { +			keybuf[(ops % keysize)] = letters[(ops % 26)]; +			DB_BENCH_ASSERT( +			    dbp->put(dbp, NULL, &key, &data, 0) == 0); +		} +		TIMER_STOP; +	} else { +		DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0); +		TIMER_START; +		for (; ops > 0; --ops) +			DB_BENCH_ASSERT( +			    dbp->get(dbp, NULL, &key, &data, 0) == 0); +		TIMER_STOP; +	} + +	if (dbenv->memp_stat(dbenv, &gsp, NULL, 0) == 0) +		DB_BENCH_ASSERT(gsp->st_cache_miss == 0); + +	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0); +} + +static void +op_ds_bulk(u_int ops, u_int *totalp) +{ +	DB_ENV *dbenv; +	DB *dbp; +	DBC *dbc; +	DBT key, data; +	u_int32_t len, klen; +	u_int i, total; +	char *keybuf, *databuf; +	void *pointer, *dp, *kp; +	DB_MPOOL_STAT  *gsp; + +	DB_BENCH_ASSERT((keybuf = malloc(keysize)) != NULL); +	DB_BENCH_ASSERT((databuf = malloc(bulkbufsize)) != NULL); + +	memset(&key, 0, sizeof(key)); +	memset(&data, 0, sizeof(data)); +	key.data = keybuf; +	key.size = keysize; + +	data.data = databuf; +	data.size = datasize; +	memset(databuf, 'b', datasize); + +	DB_BENCH_ASSERT(db_create(&dbp, NULL, 0) == 0); +	dbenv = dbp->dbenv; +	dbp->set_errfile(dbp, stderr); + +	DB_BENCH_ASSERT(dbp->set_pagesize(dbp, pagesize) == 0); +	DB_BENCH_ASSERT(dbp->set_cachesize(dbp, 0, cachesize, 1) == 0); +	DB_BENCH_ASSERT( +	    dbp->open(dbp, NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0666) == 0); + +	for (i = 1; i <= numitems; ++i) { +		(void)snprintf(keybuf, keysize, "%7d", i); +		DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0); +	} + +#if 0 +	fp = fopen("before", "w"); +	dbp->set_msgfile(dbp, fp); +	DB_BENCH_ASSERT (dbp->stat_print(dbp, DB_STAT_ALL) == 0); +#endif + +	DB_BENCH_ASSERT(dbp->cursor(dbp, NULL, &dbc, 0) == 0); + +	data.ulen = bulkbufsize; +	data.flags = DB_DBT_USERMEM; + +	(void)dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR); + +	TIMER_START; +	for (total = 0; ops > 0; --ops) { +		DB_BENCH_ASSERT(dbc->c_get( +		    dbc, &key, &data, DB_FIRST | DB_MULTIPLE_KEY) == 0); +		DB_MULTIPLE_INIT(pointer, &data); +		while (pointer != NULL) { +			DB_MULTIPLE_KEY_NEXT(pointer, &data, kp, klen, dp, len); +			if (kp != NULL) +				++total; +		} +	} +	TIMER_STOP; +	*totalp = total; + +	if (dbenv->memp_stat(dbenv, &gsp, NULL, 0) == 0) +	    DB_BENCH_ASSERT(gsp->st_cache_miss == 0); + +#if 0 +	fp = fopen("before", "w"); +	dbp->set_msgfile(dbp, fp); +	DB_BENCH_ASSERT (dbp->stat_print(dbp, DB_STAT_ALL) == 0); +#endif + +	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0); + +	COMPQUIET(dp, NULL); +	COMPQUIET(klen, 0); +	COMPQUIET(len, 0); +} + +static void +op_tds(u_int ops, int update, u_int32_t env_flags, u_int32_t log_flags) +{ +	DB *dbp; +	DBT key, data; +	DB_ENV *dbenv; +	DB_MPOOL_STAT  *gsp; +	DB_TXN *txn; +	char *keybuf, *databuf; + +	DB_BENCH_ASSERT((keybuf = malloc(keysize)) != NULL); +	DB_BENCH_ASSERT((databuf = malloc(datasize)) != NULL); + +	memset(&key, 0, sizeof(key)); +	memset(&data, 0, sizeof(data)); +	key.data = keybuf; +	key.size = keysize; +	memset(keybuf, 'a', keysize); + +	data.data = databuf; +	data.size = datasize; +	memset(databuf, 'b', datasize); + +	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0); + +	dbenv->set_errfile(dbenv, stderr); + +	/* General environment configuration. */ +#ifdef DB_AUTO_COMMIT +	DB_BENCH_ASSERT(dbenv->set_flags(dbenv, DB_AUTO_COMMIT, 1) == 0); +#endif +	if (env_flags != 0) +		DB_BENCH_ASSERT(dbenv->set_flags(dbenv, env_flags, 1) == 0); + +	/* Logging configuration. */ +	if (log_flags != 0) +#if DB_VERSION_MINOR >= 7 +		DB_BENCH_ASSERT( +		    dbenv->log_set_config(dbenv, log_flags, 1) == 0); +#else +		DB_BENCH_ASSERT(dbenv->set_flags(dbenv, log_flags, 1) == 0); +#endif +#ifdef DB_LOG_INMEMORY +	if (!(log_flags & DB_LOG_INMEMORY)) +#endif +#ifdef DB_LOG_IN_MEMORY +	if (!(log_flags & DB_LOG_IN_MEMORY)) +#endif +		DB_BENCH_ASSERT(dbenv->set_lg_max(dbenv, logbufsize * 10) == 0); +	DB_BENCH_ASSERT(dbenv->set_lg_bsize(dbenv, logbufsize) == 0); + +	DB_BENCH_ASSERT(dbenv->open(dbenv, "TESTDIR", +	    DB_CREATE | DB_PRIVATE | DB_INIT_LOCK | +	    DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN, 0666) == 0); + +	DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0); +	DB_BENCH_ASSERT(dbp->set_pagesize(dbp, pagesize) == 0); +	DB_BENCH_ASSERT(dbp->open( +	    dbp, NULL, TESTFILE, NULL, DB_BTREE, DB_CREATE, 0666) == 0); + +	if (update) { +		(void)dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR); + +		TIMER_START; +		for (; ops > 0; --ops) +			DB_BENCH_ASSERT( +			    dbp->put(dbp, NULL, &key, &data, 0) == 0); +		TIMER_STOP; + +		if (dbenv->memp_stat(dbenv, &gsp, NULL, 0) == 0) +			DB_BENCH_ASSERT(gsp->st_page_out == 0); +	} else { +		DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0); +		(void)dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR); + +		TIMER_START; +		for (; ops > 0; --ops) { +			DB_BENCH_ASSERT( +			    dbenv->txn_begin(dbenv, NULL, &txn, 0) == 0); +			DB_BENCH_ASSERT( +			    dbp->get(dbp, NULL, &key, &data, 0) == 0); +			DB_BENCH_ASSERT(txn->commit(txn, 0) == 0); +		} +		TIMER_STOP; + +		if (dbenv->memp_stat(dbenv, &gsp, NULL, 0) == 0) +			DB_BENCH_ASSERT(gsp->st_cache_miss == 0); +	} + +	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0); +	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0); +} + +#define	DEFAULT_OPS	1000000 + +int +b_inmem(int argc, char *argv[]) +{ +	extern char *optarg; +	extern int optind; +	u_int ops, total; +	int ch; + +	if ((progname = strrchr(argv[0], '/')) == NULL) +		progname = argv[0]; +	else +		++progname; + +	ops = 0; +	while ((ch = getopt(argc, argv, "b:C:d:k:l:o:P:")) != EOF) +		switch (ch) { +		case 'b': +			bulkbufsize = (u_int32_t)atoi(optarg); +			break; +		case 'C': +			cachesize = (u_int32_t)atoi(optarg); +			break; +		case 'd': +			datasize = (u_int)atoi(optarg); +			break; +		case 'k': +			keysize = (u_int)atoi(optarg); +			break; +		case 'l': +			logbufsize = (u_int32_t)atoi(optarg); +			break; +		case 'o': +			ops = (u_int)atoi(optarg); +			break; +		case 'P': +			pagesize = (u_int32_t)atoi(optarg); +			break; +		case '?': +		default: +			return (usage()); +		} +	argc -= optind; +	argv += optind; + +	if (argc != 1) +		return (usage()); + +	numitems = (cachesize / (keysize + datasize - 1)) / 2; + +	if (strcasecmp(argv[0], "read") == 0) { +		if (ops == 0) +			ops = DEFAULT_OPS; +		op_ds(ops, 0); +		printf( +	"# %u in-memory Btree database reads of %u/%u byte key/data pairs\n", +		    ops, keysize, datasize); +	} else if (strcasecmp(argv[0], "bulk") == 0) { +		if (keysize < 8) { +			fprintf(stderr, +		    "%s: bulk read requires a key size >= 10\n", progname); +			return (EXIT_FAILURE); +		} +		/* +		 * The ops value is the number of bulk operations, not key get +		 * operations.  Reduce the value so the test doesn't take so +		 * long, and use the returned number of retrievals as the ops +		 * value for timing purposes. +		 */ +		if (ops == 0) +			ops = 100000; +		op_ds_bulk(ops, &total); +		ops = total; +		printf( +    "# %u bulk in-memory Btree database reads of %u/%u byte key/data pairs\n", +		    ops, keysize, datasize); +	} else if (strcasecmp(argv[0], "write") == 0) { +		if (ops == 0) +			ops = DEFAULT_OPS; +		op_ds(ops, 1); +		printf( +	"# %u in-memory Btree database writes of %u/%u byte key/data pairs\n", +		    ops, keysize, datasize); +	} else if (strcasecmp(argv[0], "txn-read") == 0) { +		if (ops == 0) +			ops = DEFAULT_OPS; +		op_tds(ops, 0, 0, 0); +		printf( +		"# %u transactional in-memory Btree database reads of %u/%u %s", +		    ops, keysize, datasize, "byte key/data pairs\n"); +	} else if (strcasecmp(argv[0], "txn-write") == 0) { +		if (ops == 0) +			ops = DEFAULT_OPS; +#if defined(DB_LOG_INMEMORY) || defined(DB_LOG_IN_MEMORY) +#if defined(DB_LOG_INMEMORY) +		op_tds(ops, 1, 0, DB_LOG_INMEMORY); +#else +		op_tds(ops, 1, 0, DB_LOG_IN_MEMORY); +#endif +		printf( +	"# %u transactional in-memory logging Btree database writes of %u/%u%s", +		    ops, keysize, datasize, " byte key/data pairs\n"); +#else +		return (EXIT_SUCCESS); +#endif +	} else if (strcasecmp(argv[0], "txn-nosync") == 0) { +		if (ops == 0) +			ops = DEFAULT_OPS; +		op_tds(ops, 1, DB_TXN_NOSYNC, 0); +		printf( +	"# %u transactional nosync logging Btree database writes of %u/%u %s", +		    ops, keysize, datasize, "byte key/data pairs\n"); +	} else if (strcasecmp(argv[0], "txn-write-nosync") == 0) { +		if (ops == 0) +			ops = DEFAULT_OPS; +#ifdef DB_TXN_WRITE_NOSYNC +		op_tds(ops, 1, DB_TXN_WRITE_NOSYNC, 0); +		printf( +  "# %u transactional OS-write/nosync logging Btree database writes of %u/%u%s", +		    ops, keysize, datasize, " byte key/data pairs\n"); +#else +		return (EXIT_SUCCESS); +#endif +	} else if (strcasecmp(argv[0], "txn-sync") == 0) { +		/* +		 * Flushing to disk takes a long time, reduce the number of +		 * default ops. +		 */ +		if (ops == 0) +			ops = 100000; +		op_tds(ops, 1, 0, 0); +		printf( +	"# %u transactional logging Btree database writes of %u/%u %s", +		    ops, keysize, datasize, "byte key/data pairs\n"); +	} else { +		fprintf(stderr, "%s: unknown keyword %s\n", progname, argv[0]); +		return (EXIT_FAILURE); +	} + +	TIMER_DISPLAY(ops); +	return (EXIT_SUCCESS); +} + +static int +usage() +{ +	fprintf(stderr, "usage: %s %s%s%s%s", +	    progname, "[-b bulkbufsz] [-C cachesz]\n\t", +	    "[-d datasize] [-k keysize] [-l logbufsz] [-o ops] [-P pagesz]\n\t", +	    "[read | bulk | write | txn-read |\n\t", +	    "txn-write | txn-nosync | txn-write-nosync | txn-sync]\n"); +	return (EXIT_FAILURE); +} +#else +int +b_inmem(int argc, char *argv[]) +{ +	COMPQUIET(argc, 0); +	COMPQUIET(argv, NULL); +	return (0); +} +#endif diff --git a/db-4.8.30/test_micro/source/b_latch.c b/db-4.8.30/test_micro/source/b_latch.c new file mode 100644 index 0000000..83ae181 --- /dev/null +++ b/db-4.8.30/test_micro/source/b_latch.c @@ -0,0 +1,199 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2009 Oracle.  All rights reserved. + * + * $Id$ + */ + +#include "bench.h" + +#ifdef _POSIX_THREADS +typedef struct { +	pthread_t	id; +	DB_ENV		*dbenv; +	int		iterations; +	db_mutex_t	mutex; +	int		contentions; +} threadinfo_t; + +static void *latch_threadmain __P((void *)); +#endif + +static int   time_latches __P((DB_ENV *, db_mutex_t, int)); + +#define	LATCH_THREADS_MAX	100 + +/* Return the environment needed for __mutex_lock(), depending on release. + */ +#if DB_VERSION_MAJOR <4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 7 +#define	ENV_ARG(dbenv)	(dbenv) +#else +#define	ENV_ARG(dbenv)	((dbenv)->env) +#endif + +/* + * In the mulithreaded latch test each thread locks and updates this variable. + * It detects contention when the value of this counter changes during the + * mutex lock call. + */ +static int CurrentCounter = 0; +static int   latch_usage __P((void)); + +static int +latch_usage() +{ +	(void)fprintf(stderr, "usage: b_latch [-c number of %s", +	    "lock+unlock pairs] [-n number of threads]\n"); +	return (EXIT_FAILURE); +} + +/* + * time_latches -- + *	Repeat acquire and release of an exclusive latch, counting the + *	number of times that 'someone else' got it just as we tried to. + */ +static int time_latches(dbenv, mutex, iterations) +	DB_ENV *dbenv; +	db_mutex_t mutex; +	int iterations; +{ +	int contended, i, previous; + +	contended = 0; +	for (i = 0; i < iterations; ++i) { +		previous = CurrentCounter; +		DB_BENCH_ASSERT(__mutex_lock(ENV_ARG(dbenv), mutex) == 0); +		if (previous != CurrentCounter) +			contended++; +		CurrentCounter++; +		DB_BENCH_ASSERT(__mutex_unlock(ENV_ARG(dbenv), mutex) == 0); +	} +	return (contended); +} + +#ifdef _POSIX_THREADS +/* + * latch_threadmain -- + *	Entry point for multithreaded latching test. + * + *	Currently only supported for POSIX threads. + */ +static void * +latch_threadmain(arg) +	void *arg; +{ +	threadinfo_t	*info = arg; + +	info->contentions = time_latches(info->dbenv, +	    info->mutex, info->iterations); + +	return ((void *) 0); +} +#endif + +/* + * b_latch -- + *	Measure the speed of latching and mutex operations. + * + * + */ +int +b_latch(argc, argv) +	int argc; +	char *argv[]; +{ +	extern char *optarg; +	extern int optind; +	DB_ENV *dbenv; +	int ch, count, nthreads; +#ifdef _POSIX_THREADS +	threadinfo_t threads[LATCH_THREADS_MAX]; +	int i, ret; +	void *status; +#endif +	db_mutex_t mutex; +	int contended; + +	contended = 0; +	count = 1000000; +	nthreads = 0;	/* Default to running the test without extra threads */ +	while ((ch = getopt(argc, argv, "c:n:")) != EOF) +		switch (ch) { +		case 'c': +			count = atoi(optarg); +			break; +		case 'n': +			nthreads = atoi(optarg); +			break; +		case '?': +		default: +			return (latch_usage()); +		} +	argc -= optind; +	argv += optind; +	if (argc != 0 || count < 1 || nthreads < 0 || +	    nthreads > LATCH_THREADS_MAX) +		return (latch_usage()); +#ifndef _POSIX_THREADS +	if (nthreads > 1) { +		(void)fprintf(stderr, +		    "Sorry, support for -n %d: threads not yet available\n", +		    nthreads); +		exit(EXIT_FAILURE); +	} +#endif + +	/* Create the environment. */ +	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0); +	dbenv->set_errfile(dbenv, stderr); +#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 1 +	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, +	    NULL, DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | +	    DB_INIT_MPOOL | DB_INIT_TXN | DB_PRIVATE, 0666) == 0); +#else +	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, +	    DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | +	    DB_INIT_MPOOL | DB_INIT_TXN | DB_PRIVATE, 0666) == 0); +#endif +	DB_BENCH_ASSERT(dbenv->mutex_alloc(dbenv, DB_MUTEX_SELF_BLOCK, +	    &mutex) == 0); +#ifdef _POSIX_THREADS +	for (i = 0; i < nthreads; i++)  { +		threads[i].dbenv = dbenv; +		threads[i].mutex = mutex; +		threads[i].iterations = +		    nthreads <= 1 ? count : count / nthreads; +	} +#endif + +	/* Start and acquire and release a mutex count times. If there's +	 * posix support and a non-zero number of threads start them. +	 */ +	TIMER_START; +#ifdef _POSIX_THREADS +	if (nthreads > 0) { +		for (i = 0; i < nthreads; i++) +			DB_BENCH_ASSERT(pthread_create(&threads[i].id, +			    NULL, latch_threadmain, &threads[i]) == 0); +		for (i = 0; i < nthreads; i++) { +			ret = pthread_join(threads[i].id, &status); +			DB_BENCH_ASSERT(ret == 0); +			contended += threads[i].contentions; +		} + +	} else +#endif +		contended = time_latches(dbenv, mutex, count); +	TIMER_STOP; + +	printf("# %d mutex lock-unlock pairs of %d thread%s\n", count, +	    nthreads, nthreads == 1 ? "" : "s"); +	TIMER_DISPLAY(count); + +	DB_BENCH_ASSERT(dbenv->mutex_free(dbenv, mutex) == 0); +	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0); +	COMPQUIET(contended, 0); + +	return (0); +} diff --git a/db-4.8.30/test_micro/source/b_load.c b/db-4.8.30/test_micro/source/b_load.c new file mode 100644 index 0000000..9cbb968 --- /dev/null +++ b/db-4.8.30/test_micro/source/b_load.c @@ -0,0 +1,164 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2005-2009 Oracle.  All rights reserved. + * + * $Id$ + */ +#include "bench.h" + +static int usage(void); + +int +b_load(int argc, char *argv[]) +{ +	extern char *optarg; +	extern int optind; +	DB *dbp; +	DBTYPE type; +	DBT key, data; +	db_recno_t recno; +	u_int32_t cachesize; +	int ch, i, count, duplicate; +	char *ts, buf[32]; + +	type = DB_BTREE; +	cachesize = MEGABYTE; +	count = 100000; +	duplicate = 0; +	ts = "Btree"; +	while ((ch = getopt(argc, argv, "C:c:dt:")) != EOF) +		switch (ch) { +		case 'C': +			cachesize = (u_int32_t)atoi(optarg); +			break; +		case 'c': +			count = atoi(optarg); +			break; +		case 'd': +			duplicate = 1; +			break; +		case 't': +			switch (optarg[0]) { +			case 'B': case 'b': +				ts = "Btree"; +				type = DB_BTREE; +				break; +			case 'H': case 'h': +				if (b_util_have_hash()) +					return (0); +				ts = "Hash"; +				type = DB_HASH; +				break; +			case 'Q': case 'q': +				if (b_util_have_queue()) +					return (0); +				ts = "Queue"; +				type = DB_QUEUE; +				break; +			case 'R': case 'r': +				ts = "Recno"; +				type = DB_RECNO; +				break; +			default: +				return (usage()); +			} +			break; +		case '?': +		default: +			return (usage()); +		} +	argc -= optind; +	argv += optind; +	if (argc != 0) +		return (usage()); + +	/* Usage. */ +	if (duplicate && (type == DB_QUEUE || type == DB_RECNO)) { +		fprintf(stderr, +		    "b_load: Queue an Recno don't support duplicates\n"); +		return (usage()); +	} + +#if DB_VERSION_MAJOR < 3 || DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 1 +	/* +	 * DB versions prior to 3.1.17 didn't have off-page duplicates, so +	 * this test can run forever. +	 */ +	if (duplicate) +		return (0); +#endif + +	/* Create the database. */ +	DB_BENCH_ASSERT(db_create(&dbp, NULL, 0) == 0); +	DB_BENCH_ASSERT(dbp->set_cachesize(dbp, 0, cachesize, 0) == 0); +	if (duplicate) +		DB_BENCH_ASSERT(dbp->set_flags(dbp, DB_DUP) == 0); +	dbp->set_errfile(dbp, stderr); + +	/* Set record length for Queue. */ +	if (type == DB_QUEUE) +		DB_BENCH_ASSERT(dbp->set_re_len(dbp, 20) == 0); + +#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 +	DB_BENCH_ASSERT( +	    dbp->open(dbp, NULL, TESTFILE, NULL, type, DB_CREATE, 0666) == 0); +#else +	DB_BENCH_ASSERT( +	    dbp->open(dbp, TESTFILE, NULL, type, DB_CREATE, 0666) == 0); +#endif + +	/* Initialize the data. */ +	memset(&key, 0, sizeof(key)); +	memset(&data, 0, sizeof(data)); + +	/* Insert count in-order key/data pairs. */ +	TIMER_START; +	if (duplicate) { +		key.size = 10; +		key.data = "01234567890123456789"; +		data.data = buf; +		data.size = 20; +		for (i = 0; i < count; ++i) { +			(void)snprintf(buf, sizeof(buf), "%020d", i); +			DB_BENCH_ASSERT( +			    dbp->put(dbp, NULL, &key, &data, 0) == 0); +		} +	} else { +		data.data = buf; +		data.size = 20; +		if (type == DB_BTREE || type == DB_HASH) { +			key.size = 10; +			key.data = buf; +			for (i = 0; i < count; ++i) { +				(void)snprintf(buf, sizeof(buf), "%010d", i); +				DB_BENCH_ASSERT( +				    dbp->put(dbp, NULL, &key, &data, 0) == 0); +			} +		} else { +			key.data = &recno; +			key.size = sizeof(recno); +			for (i = 0, recno = 1; i < count; ++i, ++recno) +				DB_BENCH_ASSERT( +				    dbp->put(dbp, NULL, &key, &data, 0) == 0); +		} +	} + +	TIMER_STOP; + +	printf("# %d %s database in-order put of 10/20 byte key/data %sitems\n", +	    count, ts, duplicate ? "duplicate " : ""); +	TIMER_DISPLAY(count); + +	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0); + +	return (0); +} + +static int +usage() +{ +	(void)fprintf(stderr, +	    "usage: b_load [-d] [-C cachesz] [-c count] [-t type]\n"); +	return (EXIT_FAILURE); +} diff --git a/db-4.8.30/test_micro/source/b_open.c b/db-4.8.30/test_micro/source/b_open.c new file mode 100644 index 0000000..1c47e43 --- /dev/null +++ b/db-4.8.30/test_micro/source/b_open.c @@ -0,0 +1,144 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2005-2009 Oracle.  All rights reserved. + * + * $Id$ + */ +#include "bench.h" + +static int usage(void); + +int +b_open(int argc, char *argv[]) +{ +	extern char *optarg; +	extern int optind; +	DB_ENV *dbenv; +	DB *dbp; +	DBTYPE type; +	int ch, i, count; +	char *fname, *dbname, *ts; + +	type = DB_BTREE; +	count = 1000; +	fname = dbname = NULL; +	ts = "Btree"; +	while ((ch = getopt(argc, argv, "c:dft:")) != EOF) +		switch (ch) { +		case 'c': +			count = atoi(optarg); +			break; +		case 'd': +			dbname = "dbname"; +			break; +		case 'f': +			fname = "filename"; +			break; +		case 't': +			switch (optarg[0]) { +			case 'B': case 'b': +				ts = "Btree"; +				type = DB_BTREE; +				break; +			case 'H': case 'h': +				if (b_util_have_hash()) +					return (0); +				ts = "Hash"; +				type = DB_HASH; +				break; +			case 'Q': case 'q': +				if (b_util_have_queue()) +					return (0); +				ts = "Queue"; +				type = DB_QUEUE; +				break; +			case 'R': case 'r': +				ts = "Recno"; +				type = DB_RECNO; +				break; +			default: +				return (usage()); +			} +			break; +		case '?': +		default: +			return (usage()); +		} +	argc -= optind; +	argv += optind; +	if (argc != 0) +		return (usage()); + +#if DB_VERSION_MAJOR < 4 +	/* +	 * Don't run in-memory database tests on versions less than 3, it +	 * takes forever and eats memory. +	 */ +	if (fname == NULL && dbname == NULL) +		return (0); +#endif +#if DB_VERSION_MAJOR < 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 4 +	/* +	 * Named in-memory databases weren't available until 4.4. +	 */ +	if (fname == NULL && dbname != NULL) +		return (0); +#endif + +	/* Create the environment. */ +	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0); +	dbenv->set_errfile(dbenv, stderr); +#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0 +	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, +	    NULL, DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0666) == 0); +#else +	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, +	    DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0666) == 0); +#endif + +	/* Create the database. */ +	DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0); + +#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 +	DB_BENCH_ASSERT(dbp->open( +	    dbp, NULL, fname, dbname, type, DB_CREATE, 0666) == 0); +#else +	DB_BENCH_ASSERT(dbp->open( +	    dbp, fname, dbname, type, DB_CREATE, 0666) == 0); +#endif +	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0); + +	/* Open the database count times. */ +	TIMER_START; +	for (i = 0; i < count; ++i) { +		DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0); +#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 +		DB_BENCH_ASSERT(dbp->open( +		    dbp, NULL, fname, dbname, type, DB_CREATE, 0666) == 0); +#else +		DB_BENCH_ASSERT(dbp->open( +		    dbp, fname, dbname, type, DB_CREATE, 0666) == 0); +#endif +		DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0); +	} +	TIMER_STOP; + +	printf("# %d %s %sdatabase open/close pairs\n", +	    count, ts, +	    fname == NULL ? +		(dbname == NULL ? "in-memory " : "named in-memory ") : +		(dbname == NULL ? "" : "sub-")); +	TIMER_DISPLAY(count); + +	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0); + +	return (0); +} + +static int +usage() +{ +	(void)fprintf(stderr, "usage: b_open [-df] [-c count] [-t type]\n"); +	return (EXIT_FAILURE); +} diff --git a/db-4.8.30/test_micro/source/b_put.c b/db-4.8.30/test_micro/source/b_put.c new file mode 100644 index 0000000..c9b2d61 --- /dev/null +++ b/db-4.8.30/test_micro/source/b_put.c @@ -0,0 +1,225 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2005-2009 Oracle.  All rights reserved. + * + * $Id$ + */ +#include "bench.h" + +static int usage(void); +static int b_put_secondary(DB *, const DBT *, const DBT *, DBT *); + +int +b_put(int argc, char *argv[]) +{ +	extern char *optarg; +	extern int optind; +	DB_ENV *dbenv; +	DB *dbp, **second; +	DBTYPE type; +	DBT key, data; +	db_recno_t recno; +	u_int32_t cachesize, dsize; +	int ch, i, count, secondaries; +	char *ts, buf[64]; + +	second = NULL; +	type = DB_BTREE; +	cachesize = MEGABYTE; +	dsize = 20; +	count = 100000; +	secondaries = 0; +	ts = "Btree"; +	while ((ch = getopt(argc, argv, "C:c:d:s:t:")) != EOF) +		switch (ch) { +		case 'C': +			cachesize = (u_int32_t)atoi(optarg); +			break; +		case 'c': +			count = atoi(optarg); +			break; +		case 'd': +			dsize = (u_int32_t)atoi(optarg); +			break; +		case 's': +			secondaries = atoi(optarg); +			break; +		case 't': +			switch (optarg[0]) { +			case 'B': case 'b': +				ts = "Btree"; +				type = DB_BTREE; +				break; +			case 'H': case 'h': +				if (b_util_have_hash()) +					return (0); +				ts = "Hash"; +				type = DB_HASH; +				break; +			case 'Q': case 'q': +				if (b_util_have_queue()) +					return (0); +				ts = "Queue"; +				type = DB_QUEUE; +				break; +			case 'R': case 'r': +				ts = "Recno"; +				type = DB_RECNO; +				break; +			default: +				return (usage()); +			} +			break; +		case '?': +		default: +			return (usage()); +		} +	argc -= optind; +	argv += optind; +	if (argc != 0) +		return (usage()); + +#if DB_VERSION_MAJOR < 3 || DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 3 +	/* +	 * Secondaries were added after DB 3.2.9. +	 */ +	if (secondaries) +		return (0); +#endif + +	/* Create the environment. */ +	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0); +	dbenv->set_errfile(dbenv, stderr); +	DB_BENCH_ASSERT(dbenv->set_cachesize(dbenv, 0, cachesize, 0) == 0); +#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 1 +	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, +	    NULL, DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0666) == 0); +#else +	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, +	    DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0666) == 0); +#endif + +	/* +	 * Create the database. +	 * Optionally set the record length for Queue. +	 */ +	DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0); +	if (type == DB_QUEUE) +		DB_BENCH_ASSERT(dbp->set_re_len(dbp, dsize) == 0); +#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 +	DB_BENCH_ASSERT( +	    dbp->open(dbp, NULL, TESTFILE, NULL, type, DB_CREATE, 0666) == 0); +#else +	DB_BENCH_ASSERT( +	    dbp->open(dbp, TESTFILE, NULL, type, DB_CREATE, 0666) == 0); +#endif + +	/* Optionally create the secondaries. */ +	if (secondaries != 0) { +		DB_BENCH_ASSERT((second = +		    calloc(sizeof(DB *), (size_t)secondaries)) != NULL); +		for (i = 0; i < secondaries; ++i) { +			DB_BENCH_ASSERT(db_create(&second[i], dbenv, 0) == 0); +			(void)snprintf(buf, sizeof(buf), "%d.db", i); +#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 +			DB_BENCH_ASSERT(second[i]->open(second[i], NULL, +			    buf, NULL, DB_BTREE, DB_CREATE, 0600) == 0); +#else +			DB_BENCH_ASSERT(second[i]->open(second[i], +			    buf, NULL, DB_BTREE, DB_CREATE, 0600) == 0); +#endif +#if DB_VERSION_MAJOR > 3 || DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR >= 3 +#if DB_VERSION_MAJOR > 3 && DB_VERSION_MINOR > 0 +			/* +			 * The DB_TXN argument to Db.associate was added in +			 * 4.1.25. +			 */ +			DB_BENCH_ASSERT(dbp->associate( +			    dbp, NULL, second[i], b_put_secondary, 0) == 0); +#else +			DB_BENCH_ASSERT(dbp->associate( +			    dbp, second[i], b_put_secondary, 0) == 0); +#endif +#endif +		} +	} + +	/* Store a key/data pair. */ +	memset(&key, 0, sizeof(key)); +	memset(&data, 0, sizeof(data)); +	switch (type) { +	case DB_BTREE: +	case DB_HASH: +		key.data = "01234567890123456789"; +		key.size = 20; +		break; +	case DB_QUEUE: +	case DB_RECNO: +		recno = 1; +		key.data = &recno; +		key.size = sizeof(recno); +		break; +	case DB_UNKNOWN: +		b_util_abort(); +		break; +	} + +	data.size = dsize; +	DB_BENCH_ASSERT( +	    (data.data = malloc((size_t)dsize)) != NULL); + +	/* Store the key/data pair count times. */ +	TIMER_START; +	for (i = 0; i < count; ++i) { +		/* Change data value so the secondaries are updated. */ +		(void)snprintf(data.data, data.size, "%10lu", (u_long)i); +		DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0); +	} +	TIMER_STOP; + +	if (type == DB_BTREE || type == DB_HASH) +		printf( +		    "# %d %s database put of 10 byte key, %lu byte data", +		    count, ts, (u_long)dsize); +	else +		printf("# %d %s database put of key, %lu byte data", +		    count, ts, (u_long)dsize); +	if (secondaries) +		printf(" with %d secondaries", secondaries); +	printf("\n"); +	TIMER_DISPLAY(count); + +	if (second != NULL) { +		for (i = 0; i < secondaries; ++i) +			DB_BENCH_ASSERT(second[i]->close(second[i], 0) == 0); +		free(second); +	} + +	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0); +	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0); + +	return (0); +} + +static int +b_put_secondary(dbp, pkey, pdata, skey) +	DB *dbp; +	const DBT *pkey, *pdata; +	DBT *skey; +{ +	skey->data = pdata->data; +	skey->size = pdata->size; + +	COMPQUIET(dbp, NULL); +	COMPQUIET(pkey, NULL); +	return (0); +} + +static int +usage() +{ +	(void)fprintf(stderr, "usage: b_put %s\n", +	    "[-C cachesz] [-c count] [-d bytes] [-s secondaries] [-t type]"); +	return (EXIT_FAILURE); +} diff --git a/db-4.8.30/test_micro/source/b_recover.c b/db-4.8.30/test_micro/source/b_recover.c new file mode 100644 index 0000000..cbe3306 --- /dev/null +++ b/db-4.8.30/test_micro/source/b_recover.c @@ -0,0 +1,141 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2005-2009 Oracle.  All rights reserved. + * + * $Id$ + */ +#include "bench.h" + +static int usage(void); + +int +b_recover(int argc, char *argv[]) +{ +	extern char *optarg; +	extern int optind; +	DB *dbp; +	DBT key, data; +	DB_ENV *dbenv; +	DB_TXN *txn; +	u_int32_t cachesize; +	int ch, i, count; + +	/* +	 * Recover was too slow before release 4.0 that it's not worth +	 * running the test. +	 */ +#if DB_VERSION_MAJOR < 4 +	return (0); +#endif +	cachesize = MEGABYTE; +	count = 1000; +	while ((ch = getopt(argc, argv, "C:c:")) != EOF) +		switch (ch) { +		case 'C': +			cachesize = (u_int32_t)atoi(optarg); +			break; +		case 'c': +			count = atoi(optarg); +			break; +		case '?': +		default: +			return (usage()); +		} +	argc -= optind; +	argv += optind; +	if (argc != 0) +		return (usage()); + +	/* Create the environment. */ +	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0); +	dbenv->set_errfile(dbenv, stderr); +	DB_BENCH_ASSERT(dbenv->set_cachesize(dbenv, 0, cachesize, 0) == 0); + +#define	OFLAGS								\ +	(DB_CREATE | DB_INIT_LOCK |					\ +	DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_PRIVATE) +#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0 +	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, NULL, OFLAGS, 0666) == 0); +#endif +#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 1 +	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, OFLAGS, 0666) == 0); +#endif +#if DB_VERSION_MAJOR > 3 || DB_VERSION_MINOR > 1 +	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, OFLAGS, 0666) == 0); +#endif + +	/* Create the database. */ +	DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0); +#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 +	DB_BENCH_ASSERT(dbp->open(dbp, NULL, +	    TESTFILE, NULL, DB_BTREE, DB_CREATE | DB_AUTO_COMMIT, 0666) == 0); +#else +	DB_BENCH_ASSERT( +	    dbp->open(dbp, TESTFILE, NULL, DB_BTREE, DB_CREATE, 0666) == 0); +#endif + +	/* Initialize the data. */ +	memset(&key, 0, sizeof(key)); +	memset(&data, 0, sizeof(data)); +	key.size = data.size = 20; +	key.data = data.data = "01234567890123456789"; + +	/* Start/commit a transaction count times. */ +	for (i = 0; i < count; ++i) { +#if DB_VERSION_MAJOR < 4 +		DB_BENCH_ASSERT( +		    txn_begin(dbenv, NULL, &txn, DB_TXN_NOSYNC) == 0); +		DB_BENCH_ASSERT(dbp->put(dbp, txn, &key, &data, 0) == 0); +		DB_BENCH_ASSERT(txn_commit(txn, 0) == 0); +#else +		DB_BENCH_ASSERT( +		    dbenv->txn_begin(dbenv, NULL, &txn, DB_TXN_NOSYNC) == 0); +		DB_BENCH_ASSERT(dbp->put(dbp, txn, &key, &data, 0) == 0); +		DB_BENCH_ASSERT(txn->commit(txn, 0) == 0); +#endif +	} + +	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0); +	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0); + +	/* Create a new DB_ENV handle. */ +	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0); +	dbenv->set_errfile(dbenv, stderr); +	DB_BENCH_ASSERT( +	    dbenv->set_cachesize(dbenv, 0, 1048576 /* 1MB */, 0) == 0); + +	/* Now run recovery. */ +	TIMER_START; +#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0 +	DB_BENCH_ASSERT(dbenv->open( +	    dbenv, TESTDIR, NULL, OFLAGS | DB_RECOVER, 0666) == 0); +#endif +#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 1 +	DB_BENCH_ASSERT( +	    dbenv->open(dbenv, TESTDIR, OFLAGS | DB_RECOVER, 0666) == 0); +#endif +#if DB_VERSION_MAJOR > 3 || DB_VERSION_MINOR > 1 +	DB_BENCH_ASSERT( +	    dbenv->open(dbenv, TESTDIR, OFLAGS | DB_RECOVER, 0666) == 0); +#endif +	TIMER_STOP; + +	/* +	 * We divide the time by the number of transactions, so an "operation" +	 * is the recovery of a single transaction. +	 */ +	printf("# recovery after %d transactions\n", count); +	TIMER_DISPLAY(count); + +	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0); + +	return (0); +} + +static int +usage() +{ +	(void)fprintf(stderr, "usage: b_recover [-C cachesz] [-c count]\n"); +	return (EXIT_FAILURE); +} diff --git a/db-4.8.30/test_micro/source/b_txn.c b/db-4.8.30/test_micro/source/b_txn.c new file mode 100644 index 0000000..ddd7045 --- /dev/null +++ b/db-4.8.30/test_micro/source/b_txn.c @@ -0,0 +1,93 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2005-2009 Oracle.  All rights reserved. + * + * $Id$ + */ +#include "bench.h" + +static int usage(void); + +int +b_txn(int argc, char *argv[]) +{ +	extern char *optarg; +	extern int optind; +	DB_ENV *dbenv; +	DB_TXN *txn; +	int tabort, ch, i, count; + +	count = 1000; +	tabort = 0; +	while ((ch = getopt(argc, argv, "ac:")) != EOF) +		switch (ch) { +		case 'a': +			tabort = 1; +			break; +		case 'c': +			count = atoi(optarg); +			break; +		case '?': +		default: +			return (usage()); +		} +	argc -= optind; +	argv += optind; +	if (argc != 0) +		return (usage()); + +	/* Create the environment. */ +	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0); +	dbenv->set_errfile(dbenv, stderr); +#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 1 +	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, +	    NULL, DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | +	    DB_INIT_MPOOL | DB_INIT_TXN | DB_PRIVATE, 0666) == 0); +#else +	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, +	    DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | +	    DB_INIT_MPOOL | DB_INIT_TXN | DB_PRIVATE, 0666) == 0); +#endif + +	/* Start and commit/abort a transaction count times. */ +	TIMER_START; +	if (tabort) +		for (i = 0; i < count; ++i) { +#if DB_VERSION_MAJOR < 4 +			DB_BENCH_ASSERT(txn_begin(dbenv, NULL, &txn, 0) == 0); +			DB_BENCH_ASSERT(txn_abort(txn) == 0); +#else +			DB_BENCH_ASSERT( +			    dbenv->txn_begin(dbenv, NULL, &txn, 0) == 0); +			DB_BENCH_ASSERT(txn->abort(txn) == 0); +#endif +		} +	else +		for (i = 0; i < count; ++i) { +#if DB_VERSION_MAJOR < 4 +			DB_BENCH_ASSERT(txn_begin(dbenv, NULL, &txn, 0) == 0); +			DB_BENCH_ASSERT(txn_commit(txn, 0) == 0); +#else +			DB_BENCH_ASSERT( +			    dbenv->txn_begin(dbenv, NULL, &txn, 0) == 0); +			DB_BENCH_ASSERT(txn->commit(txn, 0) == 0); +#endif +		} +	TIMER_STOP; + +	printf("# %d empty transaction start/%s pairs\n", +	    count, tabort ? "abort" : "commit"); +	TIMER_DISPLAY(count); + +	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0); + +	return (0); +} + +static int +usage() +{ +	(void)fprintf(stderr, "usage: b_txn [-a] [-c count]\n"); +	return (EXIT_FAILURE); +} diff --git a/db-4.8.30/test_micro/source/b_txn_write.c b/db-4.8.30/test_micro/source/b_txn_write.c new file mode 100644 index 0000000..dcf189f --- /dev/null +++ b/db-4.8.30/test_micro/source/b_txn_write.c @@ -0,0 +1,172 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2005-2009 Oracle.  All rights reserved. + * + * $Id$ + */ +#include "bench.h" + +static int usage __P((void)); + +#ifdef DB_INIT_REP +static int b_txn_write_send __P((DB_ENV *, +    const DBT *, const DBT *, const DB_LSN *, int, u_int32_t)); + +/* + * b_txn_write_send -- + *	A stubbed-out replication message function. + */ +static int +b_txn_write_send(dbenv, control, rec, lsn, eid, flags) +	DB_ENV *dbenv; +	const DBT *control, *rec; +	const DB_LSN *lsn; +	int eid; +	u_int32_t flags; +{ +	COMPQUIET(dbenv, NULL); +	COMPQUIET(control, NULL); +	COMPQUIET(rec, NULL); +	COMPQUIET(lsn, NULL); +	COMPQUIET(eid, 0); +	COMPQUIET(flags, 0); +	return (0); +} +#endif + +int +b_txn_write(int argc, char *argv[]) +{ +	extern char *optarg; +	extern int optind; +	DB *dbp; +	DBT key, data; +	DB_ENV *dbenv; +	DB_TXN *txn; +	u_int32_t flags, oflags; +	int ch, i, count, rep_stub; +	char *config; + +	count = 1000; +	oflags = flags = 0; +	rep_stub = 0; +	config = "synchronous"; +	while ((ch = getopt(argc, argv, "ac:rw")) != EOF) +		switch (ch) { +		case 'a': +			config = "nosync"; +			flags = DB_TXN_NOSYNC; +			break; +		case 'c': +			count = atoi(optarg); +			break; +		case 'r': +#ifdef DB_INIT_REP +			rep_stub = 1; +#else +			exit(0); +#endif +			break; +		case 'w': +			config = "write-nosync"; +#ifdef DB_TXN_WRITE_NOSYNC +			flags = DB_TXN_WRITE_NOSYNC; +#else +			exit(0); +#endif +			break; +		case '?': +		default: +			return (usage()); +		} +	argc -= optind; +	argv += optind; +	if (argc != 0) +		return (usage()); + +	/* Create the environment. */ +	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0); +	dbenv->set_errfile(dbenv, stderr); + +#ifdef DB_INIT_REP +	if (rep_stub) { +#if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 5 || DB_VERSION_MAJOR > 4 +		DB_BENCH_ASSERT( +		    dbenv->rep_set_transport(dbenv, 1, b_txn_write_send) == 0); +#else +		DB_BENCH_ASSERT( +		    dbenv->set_rep_transport(dbenv, 1, b_txn_write_send) == 0); +#endif +		oflags |= DB_INIT_REP; +	} +#endif +	oflags |= DB_CREATE | DB_INIT_LOCK | +	    DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_PRIVATE; +#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0 +	DB_BENCH_ASSERT( +	    dbenv->open(dbenv, TESTDIR, NULL, flags | oflags, 0666) == 0); +#endif +#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 1 +	DB_BENCH_ASSERT( +	    dbenv->open(dbenv, TESTDIR, flags | oflags, 0666) == 0); +#endif +#if DB_VERSION_MAJOR > 3 || DB_VERSION_MINOR > 1 +	if (flags != 0) +		DB_BENCH_ASSERT(dbenv->set_flags(dbenv, flags, 1) == 0); +	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, oflags, 0666) == 0); +#endif + +#ifdef DB_INIT_REP +	if (rep_stub) +		DB_BENCH_ASSERT( +		    dbenv->rep_start(dbenv, NULL, DB_REP_MASTER) == 0); +#endif + +	/* Create the database. */ +	DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0); +#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 +	DB_BENCH_ASSERT(dbp->open(dbp, NULL, +	    TESTFILE, NULL, DB_BTREE, DB_CREATE | DB_AUTO_COMMIT, 0666) == 0); +#else +	DB_BENCH_ASSERT( +	    dbp->open(dbp, TESTFILE, NULL, DB_BTREE, DB_CREATE, 0666) == 0); +#endif + +	/* Initialize the data. */ +	memset(&key, 0, sizeof(key)); +	memset(&data, 0, sizeof(data)); +	key.size = data.size = 20; +	key.data = data.data = "01234567890123456789"; + +	/* Start/commit a transaction count times. */ +	TIMER_START; +	for (i = 0; i < count; ++i) { +#if DB_VERSION_MAJOR < 4 +		DB_BENCH_ASSERT(txn_begin(dbenv, NULL, &txn, 0) == 0); +		DB_BENCH_ASSERT(dbp->put(dbp, txn, &key, &data, 0) == 0); +		DB_BENCH_ASSERT(txn_commit(txn, 0) == 0); +#else +		DB_BENCH_ASSERT(dbenv->txn_begin(dbenv, NULL, &txn, 0) == 0); +		DB_BENCH_ASSERT(dbp->put(dbp, txn, &key, &data, 0) == 0); +		DB_BENCH_ASSERT(txn->commit(txn, 0) == 0); +#endif +	} +	TIMER_STOP; + +	printf("# %d %stransactions write %s commit pairs\n", +	    count, rep_stub ? "replicated ": "", config); +	TIMER_DISPLAY(count); + +	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0); +	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0); + +	return (0); +} + +static int +usage() +{ +	(void)fprintf(stderr, "usage: b_txn_write [-arw] [-c count]\n"); +	return (EXIT_FAILURE); +} diff --git a/db-4.8.30/test_micro/source/b_uname.c b/db-4.8.30/test_micro/source/b_uname.c new file mode 100644 index 0000000..fab0e7c --- /dev/null +++ b/db-4.8.30/test_micro/source/b_uname.c @@ -0,0 +1,147 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2005-2009 Oracle.  All rights reserved. + * + * $Id$ + */ + +#include "bench.h" + +#define	UNAMEFILE	"NODENAME" + +static int write_info __P((FILE *)); + +int +b_uname() +{ +	FILE *fp; +	int ret; + +	if ((fp = fopen(UNAMEFILE, "w")) == NULL) +		goto file_err; + +	ret = write_info(fp); + +	if (fclose(fp) != 0) { +file_err:	fprintf(stderr, +		    "%s: %s: %s\n", progname, UNAMEFILE, strerror(errno)); +		return (1); +	} + +	return (ret); +} + +#ifdef DB_WIN32 +static int +write_info(fp) +	FILE *fp; +{ +	OSVERSIONINFO osver; +	SYSTEM_INFO sysinfo; +	char *p; + +#ifdef DB_WINCE +	p = "WinCE"; +#else +	{ +	DWORD len; +	char buf[1024]; + +	len = sizeof(buf) - 1; +	GetComputerName(buf, &len); +	p = buf; +	} +#endif +	fprintf(fp, "<p>%s, ", p); + +	GetSystemInfo(&sysinfo); +	switch (sysinfo.wProcessorArchitecture) { +	case PROCESSOR_ARCHITECTURE_ALPHA: +		p = "alpha"; +		break; +	case PROCESSOR_ARCHITECTURE_INTEL: +		p = "x86"; +		break; +	case PROCESSOR_ARCHITECTURE_MIPS: +		p = "mips"; +		break; +	case PROCESSOR_ARCHITECTURE_PPC: +		p = "ppc"; +		break; +	default: +		p = "unknown"; +		break; +	} +	fprintf(fp, "%s<br>\n", p); +	memset(&osver, 0, sizeof(osver)); +	osver.dwOSVersionInfoSize = sizeof(osver); +	GetVersionEx(&osver); +	switch (osver.dwPlatformId) { +	case VER_PLATFORM_WIN32_NT:	/* NT, Windows 2000 or Windows XP */ +		if (osver.dwMajorVersion == 4) +			p = "Windows NT4x"; +		else if (osver.dwMajorVersion <= 3) +			p = "Windows NT3x"; +		else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion < 1) +			p = "Windows 2000"; +		else if (osver.dwMajorVersion >= 5) +			p = "Windows XP"; +		else +			p = "unknown"; +		break; +	case VER_PLATFORM_WIN32_WINDOWS:	/* Win95, Win98 or WinME */ +		if ((osver.dwMajorVersion > 4) || +		  ((osver.dwMajorVersion == 4) && (osver.dwMinorVersion > 0))) { +			if (osver.dwMinorVersion >= 90) +				p = "Windows ME"; +			else +				p = "Windows 98"; +		} else +			p = "Windows 95"; +		break; +	case VER_PLATFORM_WIN32s:		/* Windows 3.x */ +		p = "Windows"; +		break; +	default: +		p = "unknown"; +		break; +	} +	fprintf(fp, +	    "%s, %ld.%02ld", p, osver.dwMajorVersion, osver.dwMinorVersion); +	return (0); +} + +#elif defined(HAVE_VXWORKS) +static int +write_info(fp) +	FILE *fp; +{ +	fprintf(fp, "<p>VxWorks"); +	return (0); +} + +#else /* POSIX */ +#include <sys/utsname.h> + +static int +write_info(fp) +	FILE *fp; +{ +	struct utsname name; + +	if (uname(&name) == 0) +		fprintf(fp, "<p>%s, %s<br>\n%s, %s, %s</p>\n", name.nodename, +		    name.machine, name.sysname, name.release, name.version); +	else { +		/* +		 * We've seen random failures on some systems, complain and +		 * skip the call if it fails. +		 */ +		fprintf(stderr, "%s: uname: %s\n", progname, strerror(errno)); + +		fprintf(fp, "<p>POSIX"); +	} +	return (0); +} +#endif diff --git a/db-4.8.30/test_micro/source/b_util.c b/db-4.8.30/test_micro/source/b_util.c new file mode 100644 index 0000000..2610bc5 --- /dev/null +++ b/db-4.8.30/test_micro/source/b_util.c @@ -0,0 +1,157 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2005-2009 Oracle.  All rights reserved. + * + * $Id$ + */ + +#include "bench.h" + +static int testdir_remove __P((char *)); + +int +b_util_have_hash() +{ +#if defined(HAVE_HASH) ||\ +    DB_VERSION_MAJOR < 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 2 +	return (0); +#else +	fprintf(stderr, +    "library build did not include support for the Hash access method\n"); +	return (1); +#endif +} + +int +b_util_have_queue() +{ +#if defined(HAVE_QUEUE) ||\ +    DB_VERSION_MAJOR < 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 2 +	return (0); +#else +	fprintf(stderr, +    "library build did not include support for the Queue access method\n"); +	return (1); +#endif +} + +/* + * b_util_dir_setup -- + *	Create the test directory. + */ +int +b_util_dir_setup() +{ +	int ret; + +#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 3 +	if ((ret = __os_mkdir(NULL, TESTDIR, 0755)) != 0) { +#else +	if ((ret = mkdir(TESTDIR, 0755)) != 0) { +#endif +		fprintf(stderr, +		    "%s: %s: %s\n", progname, TESTDIR, db_strerror(ret)); +		return (1); +	} +	return (0); +} + +#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 4 +#define	OS_EXISTS(a, b, c)	__os_exists(a, b, c) +#else +#define	OS_EXISTS(a, b, c)	__os_exists(b, c) +#endif + +/* + * b_util_dir_teardown + *	Clean up the test directory. + */ +int +b_util_dir_teardown() +{ +	int ret; + +	if (OS_EXISTS(NULL, TESTFILE, NULL) == 0 && +	    (ret = b_util_unlink(TESTFILE)) != 0) { +		fprintf(stderr, +		    "%s: %s: %s\n", progname, TESTFILE, db_strerror(ret)); +		return (1); +	} +	return (testdir_remove(TESTDIR) ? 1 : 0); +} + +/* + * testdir_remove -- + *	Remove a directory and all its contents, the "dir" must contain no + *	subdirectories, because testdir_remove will not recursively delete + *	all subdirectories. + */ +static int +testdir_remove(dir) +	char *dir; +{ +	int cnt, i, isdir, ret; +	char buf[1024], **names; + +	ret = 0; + +	/* If the directory doesn't exist, we're done. */ +	if (OS_EXISTS(NULL, dir, &isdir) != 0) +		return (0); + +	/* Get a list of the directory contents. */ +#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 6 +	if ((ret = __os_dirlist(NULL, dir, 0, &names, &cnt)) != 0) +		return (ret); +#else +	if ((ret = __os_dirlist(NULL, dir, &names, &cnt)) != 0) +		return (ret); +#endif +	/* Go through the file name list, remove each file in the list */ +	for (i = 0; i < cnt; ++i) { +		(void)snprintf(buf, sizeof(buf), +		    "%s%c%s", dir, PATH_SEPARATOR[0], names[i]); +		if ((ret = OS_EXISTS(NULL, buf, &isdir)) != 0) +			goto file_err; +		if (!isdir && (ret = b_util_unlink(buf)) != 0) { +file_err:		fprintf(stderr, "%s: %s: %s\n", +			    progname, buf, db_strerror(ret)); +			break; +		} +	} + +	__os_dirfree(NULL, names, cnt); + +	/* +	 * If we removed the contents of the directory, remove the directory +	 * itself. +	 */ +	if (i == cnt && (ret = rmdir(dir)) != 0) +		fprintf(stderr, +		    "%s: %s: %s\n", progname, dir, db_strerror(errno)); +	return (ret); +} + +void +b_util_abort() +{ +#if DB_VERSION_MAJOR < 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 6 +	abort(); +#elif DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 6 +	__os_abort(); +#else +	__os_abort(NULL); +#endif +} + +int +b_util_unlink(path) +	char *path; +{ +#if DB_VERSION_MAJOR < 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 7 +	return (__os_unlink(NULL, path)); +#else +	return (__os_unlink(NULL, path, 0)); +#endif +} diff --git a/db-4.8.30/test_micro/source/b_workload.c b/db-4.8.30/test_micro/source/b_workload.c new file mode 100644 index 0000000..6851a43 --- /dev/null +++ b/db-4.8.30/test_micro/source/b_workload.c @@ -0,0 +1,631 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2005-2009 Oracle.  All rights reserved. + * + * $Id$ + */ + +#include "bench.h" +#include "b_workload.h" + +static int   dump_verbose_stats __P((DB *, CONFIG *)); +static int   is_del_workload __P((int)); +static int   is_get_workload __P((int)); +static int   is_put_workload __P((int)); +static int   run_mixed_workload __P((DB *, CONFIG *)); +static int   run_std_workload __P((DB *, CONFIG *)); +static int   usage __P((void)); +static char *workload_str __P((int)); + +/* + * General TODO list: + * * The workload type. Might work better as a bitmask than the current enum. + * * Improve the verbose stats, so they can be easily parsed. + * * Think about doing automatic btree/hash comparison in here. + */ +int +b_workload(argc, argv) +	int argc; +	char *argv[]; +{ +	extern char *optarg; +	extern int optind; +	CONFIG conf; +	DB *dbp; +	DB_ENV *dbenv; +	int ch, ffactor, ksz; + +	dbenv = NULL; +	memset(&conf, 0, sizeof(conf)); +	conf.seed = 124087; +	srand(conf.seed); + +	conf.pcount = 100000; +	conf.ts = "Btree"; +	conf.type = DB_BTREE; +	conf.dsize = 20; +	conf.presize = 0; +	conf.workload = T_PUT_GET_DELETE; + +	while ((ch = getopt(argc, argv, "b:c:d:e:g:ik:m:op:r:t:vw:")) != EOF) +		switch (ch) { +		case 'b': +			conf.cachesz = atoi(optarg); +			break; +		case 'c': +			conf.pcount = atoi(optarg); +			break; +		case 'd': +			conf.dsize = atoi(optarg); +			break; +		case 'e': +			conf.cursor_del = atoi(optarg); +			break; +		case 'g': +			conf.gcount = atoi(optarg); +			break; +		case 'i': +			conf.presize = 1; +			break; +		case 'k': +			conf.ksize = atoi(optarg); +			break; +		case 'm': +			conf.message = optarg; +			break; +		case 'o': +			conf.orderedkeys = 1; +			break; +		case 'p': +			conf.pagesz = atoi(optarg); +			break; +		case 'r': +			conf.num_dups = atoi(optarg); +			break; +		case 't': +			switch (optarg[0]) { +			case 'B': case 'b': +				conf.ts = "Btree"; +				conf.type = DB_BTREE; +				break; +			case 'H': case 'h': +				if (b_util_have_hash()) +					return (0); +				conf.ts = "Hash"; +				conf.type = DB_HASH; +				break; +			default: +				return (usage()); +			} +			break; +		case 'v': +			conf.verbose = 1; +			break; +		case 'w': +			switch (optarg[0]) { +			case 'A': +				conf.workload = T_PUT_GET_DELETE; +				break; +			case 'B': +				conf.workload = T_GET; +				break; +			case 'C': +				conf.workload = T_PUT; +				break; +			case 'D': +				conf.workload = T_DELETE; +				break; +			case 'E': +				conf.workload = T_PUT_GET; +				break; +			case 'F': +				conf.workload = T_PUT_DELETE; +				break; +			case 'G': +				conf.workload = T_GET_DELETE; +				break; +			case 'H': +				conf.workload = T_MIXED; +				break; +			default: +				return (usage()); +			} +			break; +		case '?': +		default: +			fprintf(stderr, "Invalid option: %c\n", ch); +			return (usage()); +		} +	argc -= optind; +	argv += optind; +	if (argc != 0) +		return (usage()); + +	/* +	 * Validate the input parameters if specified. +	 */ +	if (conf.pagesz != 0) +		DB_BENCH_ASSERT(conf.pagesz >= 512 && conf.pagesz <= 65536 && +		   ((conf.pagesz & (conf.pagesz - 1)) == 0)); + +	if (conf.cachesz != 0) +		DB_BENCH_ASSERT(conf.cachesz > 20480); +	DB_BENCH_ASSERT(conf.ksize == 0 || conf.orderedkeys == 0); + +	/* Create the environment. */ +	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0); +	dbenv->set_errfile(dbenv, stderr); +	if (conf.cachesz != 0) +		DB_BENCH_ASSERT( +		    dbenv->set_cachesize(dbenv, 0, conf.cachesz, 0) == 0); + +#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 1 +	DB_BENCH_ASSERT(dbenv->open(dbenv, "TESTDIR", +	    NULL, DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0666) == 0); +#else +	DB_BENCH_ASSERT(dbenv->open(dbenv, "TESTDIR", +	    DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0666) == 0); +#endif + +	DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0); +	if (conf.pagesz != 0) +		DB_BENCH_ASSERT( +		    dbp->set_pagesize(dbp, conf.pagesz) == 0); +	if (conf.presize != 0 && conf.type == DB_HASH) { +		ksz = (conf.orderedkeys != 0) ? sizeof(u_int32_t) : conf.ksize; +		if (ksz == 0) +			ksz = 10; +		ffactor = (conf.pagesz - 32)/(ksz + conf.dsize + 8); +		fprintf(stderr, "ffactor: %d\n", ffactor); +		DB_BENCH_ASSERT( +		    dbp->set_h_ffactor(dbp, ffactor) == 0); +		DB_BENCH_ASSERT( +		    dbp->set_h_nelem(dbp, conf.pcount*10) == 0); +	} +#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 +	DB_BENCH_ASSERT(dbp->open( +	    dbp, NULL, TESTFILE, NULL, conf.type, DB_CREATE, 0666) == 0); +#else +	DB_BENCH_ASSERT(dbp->open( +	    dbp, TESTFILE, NULL, conf.type, DB_CREATE, 0666) == 0); +#endif + +	if (conf.workload == T_MIXED) +		 run_mixed_workload(dbp, &conf); +	else +		run_std_workload(dbp, &conf); + +	if (is_put_workload(conf.workload) == 0) +		timespecadd(&conf.tot_time, &conf.put_time); +	if (is_get_workload(conf.workload) == 0) +		timespecadd(&conf.tot_time, &conf.get_time); +	if (is_del_workload(conf.workload) == 0) +		timespecadd(&conf.tot_time, &conf.del_time); + +	/* Ensure data is flushed for following measurements. */ +	DB_BENCH_ASSERT(dbp->sync(dbp, 0) == 0); + +	if (conf.verbose != 0) +		dump_verbose_stats(dbp, &conf); + +	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0); +	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0); + +	/* +	 * Construct a string for benchmark output. +	 * +	 * Insert HTML in-line to make the output prettier -- ugly, but easy. +	 */ +	printf("# workload test: %s: %s<br>%lu ops", +	    conf.ts, workload_str(conf.workload), (u_long)conf.pcount); +	if (conf.ksize != 0) +		printf(", key size: %lu", (u_long)conf.ksize); +	if (conf.dsize != 0) +		printf(", data size: %lu", (u_long)conf.dsize); +	if (conf.pagesz != 0) +		printf(", page size: %lu", (u_long)conf.pagesz); +	else +		printf(", page size: default"); +	if (conf.cachesz != 0) +		printf(", cache size: %lu", (u_long)conf.cachesz); +	else +		printf(", cache size: default"); +	printf(", %s keys", conf.orderedkeys == 1 ? "ordered" : "unordered"); +	printf(", num dups: %lu", (u_long)conf.num_dups); +	printf("\n"); + +	if (conf.workload != T_MIXED) { +		if (conf.message != NULL) +			printf("%s %s ", conf.message, conf.ts); +		TIME_DISPLAY(conf.pcount, conf.tot_time); +	} else +		TIMER_DISPLAY(conf.pcount); + +	return (0); +} + +/* + * The mixed workload is designed to simulate a somewhat real + * usage scenario. + * NOTES: * rand is used to decide on the current operation. This will + *        be repeatable, since the same seed is always used. + *        * All added keys are stored in a FIFO queue, this is not very + *        space efficient, but is the best way I could come up with to + *        insert random key values, and be able to retrieve/delete them. + *        * TODO: the workload will currently only work with unordered + *        fixed length keys. + */ +#define	GET_PROPORTION 90 +#define	PUT_PROPORTION 7 +#define	DEL_PROPORTION 3 + +static int +run_mixed_workload(dbp, config) +	DB *dbp; +	CONFIG *config; +{ +	DBT key, data; +	size_t next_op, i, ioff, inscount; +	char kbuf[KBUF_LEN]; +	struct bench_q operation_queue; + +	/* Having ordered insertion does not make sense here */ +	DB_BENCH_ASSERT(config->orderedkeys == 0); + +	srand(config->seed); +	memset(&operation_queue, 0, sizeof(struct bench_q)); + +	ioff = 0; +	INIT_KEY(key, config); +	memset(&data, 0, sizeof(data)); +	DB_BENCH_ASSERT( +	    (data.data = malloc(data.size = config->dsize)) != NULL); + +	/* +	 * Add an initial sample set of data to the DB. +	 * This should add some stability, and reduce the likelihood +	 * of deleting all of the entries in the DB. +	 */ +	inscount = 2 * config->pcount; +	if (inscount > 100000) +		inscount = 100000; + +	for (i = 0; i < inscount; ++i) { +		GET_KEY_NEXT(key, config, kbuf, i); +		BENCH_Q_TAIL_INSERT(operation_queue, kbuf); +		DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0); +	} + +	TIMER_START; +	for (i = 0; i < config->pcount; ++i) { +		next_op = rand()%100; + +		if (next_op < GET_PROPORTION ) { +			BENCH_Q_POP_PUSH(operation_queue, kbuf); +			key.data = kbuf; +			key.size = sizeof(kbuf); +			dbp->get(dbp, NULL, &key, &data, 0); +		} else if (next_op < GET_PROPORTION+PUT_PROPORTION) { +			GET_KEY_NEXT(key, config, kbuf, i); +			BENCH_Q_TAIL_INSERT(operation_queue, kbuf); +			dbp->put(dbp, NULL, &key, &data, 0); +		} else { +			BENCH_Q_POP(operation_queue, kbuf); +			key.data = kbuf; +			key.size = sizeof(kbuf); +			dbp->del(dbp, NULL, &key, 0); +		} +	} +	TIMER_STOP; +	TIMER_GET(config->tot_time); + +	return (0); +} + +static int +run_std_workload(dbp, config) +	DB *dbp; +	CONFIG *config; +{ +	DBT key, data; +	DBC *dbc; +	u_int32_t i; +	int ret; +	char kbuf[KBUF_LEN]; + +	/* Setup a key/data pair. */ +	INIT_KEY(key, config); +	memset(&data, 0, sizeof(data)); +	DB_BENCH_ASSERT( +	    (data.data = malloc(data.size = config->dsize)) != NULL); + +	/* Store the key/data pair count times. */ +	TIMER_START; +	for (i = 0; i < config->pcount; ++i) { +		GET_KEY_NEXT(key, config, kbuf, i); +		DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0); +	} +	TIMER_STOP; +	TIMER_GET(config->put_time); + +	if (is_get_workload(config->workload) == 0) { +		TIMER_START; +		for (i = 0; i <= config->gcount; ++i) { +			DB_BENCH_ASSERT(dbp->cursor(dbp, NULL, &dbc, 0) == 0); +			while ((dbc->c_get(dbc, &key, &data, DB_NEXT)) == 0); +			DB_BENCH_ASSERT(dbc->c_close(dbc) == 0); +		} +		TIMER_STOP; +		TIMER_GET(config->get_time); +	} + +	if (is_del_workload(config->workload) == 0) { +		/* reset rand to reproduce key sequence. */ +		srand(config->seed); + +		TIMER_START; +		if (config->cursor_del != 0) { +			DB_BENCH_ASSERT(dbp->cursor(dbp, NULL, &dbc, 0) == 0); +			while ( +			    (ret = dbc->c_get(dbc, &key, &data, DB_NEXT)) == 0) +				DB_BENCH_ASSERT(dbc->c_del(dbc, 0) == 0); +			DB_BENCH_ASSERT (ret == DB_NOTFOUND); +		} else { +			INIT_KEY(key, config); +			for (i = 0; i < config->pcount; ++i) { +				GET_KEY_NEXT(key, config, kbuf, i); + +				ret = dbp->del(dbp, NULL, &key, 0); +				/* +				 * Random key generation can cause dups, +				 * so NOTFOUND result is OK. +				 */ +				if (config->ksize == 0) +					DB_BENCH_ASSERT +					    (ret == 0 || ret == DB_NOTFOUND); +				else +					DB_BENCH_ASSERT(ret == 0); +			} +		} +		TIMER_STOP; +		TIMER_GET(config->del_time); +	} +	return (0); +} + +static int +dump_verbose_stats(dbp, config) +	DB *dbp; +	CONFIG *config; +{ +/* + * It would be nice to be able to define stat as _stat on + * Windows, but that substitutes _stat for the db call as well. + */ +#ifdef DB_WIN32 +	struct _stat fstat; +#else +	struct stat fstat; +#endif +	DB_HASH_STAT *hstat; +	DB_BTREE_STAT *bstat; +	double free_prop; +	char path[1024]; + +#ifdef DB_BENCH_INCLUDE_CONFIG_SUMMARY +	printf("Completed workload benchmark.\n"); +	printf("Configuration summary:\n"); +	printf("\tworkload type: %d\n", (int)config->workload); +	printf("\tdatabase type: %s\n", config->ts); +	if (config->cachesz != 0) +		printf("\tcache size: %lu\n", (u_long)config->cachesz); +	if (config->pagesz != 0) +		printf("\tdatabase page size: %lu\n", (u_long)config->pagesz); +	printf("\tput element count: %lu\n", (u_long)config->pcount); +	if ( is_get_workload(config->workload) == 0) +		printf("\tget element count: %lu\n", (u_long)config->gcount); +	if (config->orderedkeys) +		printf("\tInserting items in order\n"); +	else if (config->ksize == 0) +		printf("\tInserting keys with size 10\n"); +	else +		printf( +		    "\tInserting keys with size: %lu\n", (u_long)config->ksize); + +	printf("\tInserting data elements size: %lu\n", (u_long)config->dsize); + +	if (is_del_workload(config->workload) == 0) { +		if (config->cursor_del) +			printf("\tDeleting items using a cursor\n"); +		else +			printf("\tDeleting items without a cursor\n"); +	} +#endif /* DB_BENCH_INCLUDE_CONFIG_SUMMARY */ + +	if (is_put_workload(config->workload) == 0) +		printf("%s Time spent inserting (%lu) (%s) items: %lu/%lu\n", +		    config->message[0] == '\0' ? "" : config->message, +		    (u_long)config->pcount, config->ts, +		    (u_long)config->put_time.tv_sec, config->put_time.tv_nsec); + +	if (is_get_workload(config->workload) == 0) +		printf("%s Time spent getting (%lu) (%s) items: %lu/%lu\n", +		    config->message[0] == '\0' ? "" : config->message, +		    (u_long)config->pcount * ((config->gcount == 0) ? +		    1 : config->gcount), config->ts, +		    (u_long)config->get_time.tv_sec, config->get_time.tv_nsec); + +	if (is_del_workload(config->workload) == 0) +		printf("%s Time spent deleting (%lu) (%s) items: %lu/%lu\n", +		    config->message[0] == '\0' ? "" : config->message, +		    (u_long)config->pcount, config->ts, +		    (u_long)config->del_time.tv_sec, config->del_time.tv_nsec); + +	(void)snprintf(path, sizeof(path), +	    "%s%c%s", TESTDIR, PATH_SEPARATOR[0], TESTFILE); +#ifdef DB_WIN32 +	if (_stat(path, &fstat) == 0) { +#else +	if (stat(path, &fstat) == 0) { +#endif +		printf("%s Size of db file (%s): %lu K\n", +		    config->message[0] == '\0' ? "" : config->message, +		    config->ts, (u_long)fstat.st_size/1024); +	} + +	if (config->type == DB_HASH) { +#if DB_VERSION_MAJOR < 3 || DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR <= 2 +		DB_BENCH_ASSERT(dbp->stat(dbp, &hstat, NULL, 0) == 0); +#elif DB_VERSION_MAJOR < 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR <= 2 +		DB_BENCH_ASSERT(dbp->stat(dbp, &hstat, 0) == 0); +#else +		DB_BENCH_ASSERT(dbp->stat(dbp, NULL, &hstat, 0) == 0); +#endif +		/* +		 * Hash fill factor is a bit tricky. Want to include +		 * both bucket and overflow buckets (not offpage). +		 */ +		free_prop = hstat->hash_pagesize*hstat->hash_buckets; +		free_prop += hstat->hash_pagesize*hstat->hash_overflows; +		free_prop = +		    (free_prop - hstat->hash_bfree - hstat->hash_ovfl_free)/ +		    free_prop; +		printf("%s db fill factor (%s): %.2f%%\n", +		    config->message[0] == '\0' ? "" : config->message, +		    config->ts, free_prop*100); +		free(hstat); +	} else { /* Btree */ +#if DB_VERSION_MAJOR < 3 || DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR <= 2 +		DB_BENCH_ASSERT(dbp->stat(dbp, &bstat, NULL, 0) == 0); +#elif DB_VERSION_MAJOR < 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR <= 2 +		DB_BENCH_ASSERT(dbp->stat(dbp, &bstat, 0) == 0); +#else +		DB_BENCH_ASSERT(dbp->stat(dbp, NULL, &bstat, 0) == 0); +#endif +		free_prop = bstat->bt_pagesize*bstat->bt_leaf_pg; +		free_prop = (free_prop-bstat->bt_leaf_pgfree)/free_prop; +		printf("%s db fill factor (%s): %.2f%%\n", +		    config->message[0] == '\0' ? "" : config->message, +		    config->ts, free_prop*100); +		free(bstat); +	} +	return (0); +} + +static char * +workload_str(workload) +	int workload; +{ +	static char buf[128]; + +	switch (workload) { +	case T_PUT_GET_DELETE: +		return ("PUT/GET/DELETE"); +		/* NOTREACHED */ +	case T_GET: +		return ("GET"); +		/* NOTREACHED */ +	case T_PUT: +		return ("PUT"); +		/* NOTREACHED */ +	case T_DELETE: +		return ("DELETE"); +		/* NOTREACHED */ +	case T_PUT_GET: +		return ("PUT/GET"); +		/* NOTREACHED */ +	case T_PUT_DELETE: +		return ("PUT/DELETE"); +		/* NOTREACHED */ +	case T_GET_DELETE: +		return ("GET/DELETE"); +		/* NOTREACHED */ +	case T_MIXED: +		snprintf(buf, sizeof(buf), "MIXED (get: %d, put: %d, del: %d)", +		    (int)GET_PROPORTION, +		    (int)PUT_PROPORTION, (int)DEL_PROPORTION); +		return (buf); +	default: +		break; +	} + +	exit(usage()); +	/* NOTREACHED */ +} + +static int +is_get_workload(workload) +	int workload; +{ +	switch (workload) { +	case T_GET: +	case T_PUT_GET: +	case T_PUT_GET_DELETE: +	case T_GET_DELETE: +		return 0; +	} +	return 1; +} + +static int +is_put_workload(workload) +	int workload; +{ +	switch (workload) { +	case T_PUT: +	case T_PUT_GET: +	case T_PUT_GET_DELETE: +	case T_PUT_DELETE: +		return 0; +	} +	return 1; +} + +static int +is_del_workload(workload) +	int workload; +{ +	switch (workload) { +	case T_DELETE: +	case T_PUT_DELETE: +	case T_PUT_GET_DELETE: +	case T_GET_DELETE: +		return 0; +	} +	return 1; +} + +static int +usage() +{ +	(void)fprintf(stderr, +	    "usage: b_workload [-b cachesz] [-c count] [-d bytes] [-e]\n"); +	(void)fprintf(stderr, +	    "\t[-g getitrs] [-i] [-k keysize] [-m message] [-o] [-p pagesz]\n"); +	(void)fprintf(stderr, "\t[-r dup_count] [-t type] [-w type]\n"); + +	(void)fprintf(stderr, "Where:\n"); +	(void)fprintf(stderr, "\t-b the size of the DB cache.\n"); +	(void)fprintf(stderr, "\t-c the number of elements to be measured.\n"); +	(void)fprintf(stderr, "\t-d the size of each data element.\n"); +	(void)fprintf(stderr, "\t-e delete entries using a cursor.\n"); +	(void)fprintf(stderr, "\t-g number of get cursor traverses.\n"); +	(void)fprintf(stderr, "\t-i Pre-init hash DB bucket count.\n"); +	(void)fprintf(stderr, "\t-k the size of each key inserted.\n"); +	(void)fprintf(stderr, "\t-m message pre-pended to log output.\n"); +	(void)fprintf(stderr, "\t-o keys should be ordered for insert.\n"); +	(void)fprintf(stderr, "\t-p the page size for the database.\n"); +	(void)fprintf(stderr, "\t-r the number of duplicates to insert\n"); +	(void)fprintf(stderr, "\t-t type of the underlying database.\n"); +	(void)fprintf(stderr, "\t-w the workload to measure, available:\n"); +	(void)fprintf(stderr, "\t\tA - PUT_GET_DELETE\n"); +	(void)fprintf(stderr, "\t\tB - GET\n"); +	(void)fprintf(stderr, "\t\tC - PUT\n"); +	(void)fprintf(stderr, "\t\tD - DELETE\n"); +	(void)fprintf(stderr, "\t\tE - PUT_GET\n"); +	(void)fprintf(stderr, "\t\tF - PUT_DELETE\n"); +	(void)fprintf(stderr, "\t\tG - GET_DELETE\n"); +	(void)fprintf(stderr, "\t\tH - MIXED\n"); +	return (EXIT_FAILURE); +} diff --git a/db-4.8.30/test_micro/source/b_workload.h b/db-4.8.30/test_micro/source/b_workload.h new file mode 100644 index 0000000..799720d --- /dev/null +++ b/db-4.8.30/test_micro/source/b_workload.h @@ -0,0 +1,153 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2005-2009 Oracle.  All rights reserved. + * + * $Id$ + */ + +/* + * Macros to help with initializing/assigning key dbts + */ + +#define KBUF_LEN 12 +#define	INIT_KEY(key, config) do {				\ +	memset(&key, 0, sizeof(key));				\ +	if (config->orderedkeys) {				\ +		key.size = sizeof (u_int32_t);			\ +	} else if (config->ksize != 0) {			\ +		DB_BENCH_ASSERT(				\ +		    (key.data = malloc(key.size = config->ksize)) != NULL); \ +	} else {						\ +		key.data = kbuf;				\ +		key.size = 10;					\ +	}							\ +	} while (0) + +#define	GET_KEY_NEXT(key, config, kbuf, i) do {			\ +	size_t tmp_int;						\ +	if (config->orderedkeys) {				\ +		/* Will be sorted on little-endian system. */	\ +		tmp_int = i;					\ +		M_32_SWAP(tmp_int);				\ +		key.data = &tmp_int;				\ +	} else if (config->ksize == 0) {			\ +		/*						\ +		 * This will produce duplicate keys.		\ +		 * That is not such a big deal, since we are	\ +		 * using the same seed to srand each time,	\ +		 * the scenario is reproducible.		\ +		 */						\ +		(void)snprintf(kbuf, sizeof(kbuf), "%10d", rand()); \ +	} else {						\ +		/* TODO: Not sure of the best approach here. */	\ +		(void)snprintf(key.data, config->ksize, "%10lu", (u_long)i); \ +	}							\ +	} while (0) + +/* Taken from dbinc/db_swap.h */ +#undef	M_32_SWAP +#define	M_32_SWAP(a) {							\ +	u_int32_t _tmp;							\ +	_tmp = (u_int32_t)a;						\ +	((u_int8_t *)&a)[0] = ((u_int8_t *)&_tmp)[3];			\ +	((u_int8_t *)&a)[1] = ((u_int8_t *)&_tmp)[2];			\ +	((u_int8_t *)&a)[2] = ((u_int8_t *)&_tmp)[1];			\ +	((u_int8_t *)&a)[3] = ((u_int8_t *)&_tmp)[0];			\ +} + +/* + * A singly linked list, that maintains a pointer + * to the start and the end of the queue. + * Should be possible to use a STAILQ, but this seemed easier + */ +typedef struct bench_qentry { +	char data[KBUF_LEN]; +	struct bench_qentry *next; +}bench_qentry; +typedef struct bench_q { +	struct bench_qentry *head; +	struct bench_qentry *tail; +} bench_q; +#define	BENCH_Q_TAIL_INSERT(queue, buf) do {		\ +	struct bench_qentry *entry;				\ +	DB_BENCH_ASSERT(				\ +	    (entry = malloc(sizeof(struct bench_qentry))) != NULL); \ +	memcpy(entry->data, buf, sizeof(entry->data));	\ +	if (queue.head == NULL)				\ +		queue.head = queue.tail = entry;	\ +	else {						\ +		queue.tail->next = entry;		\ +		queue.tail = entry;			\ +	}						\ +} while (0) + +#define	BENCH_Q_POP(queue, buf) do {			\ +	struct bench_qentry *popped = queue.head;	\ +	if (popped == NULL)				\ +		break;					\ +	if (queue.head->next == NULL)			\ +		queue.head = queue.tail = NULL;		\ +	else						\ +		queue.head = queue.head->next;		\ +	memcpy(buf, popped->data, sizeof(buf));	\ +	free(popped);					\ +} while (0) + +/* + * Retrieve the head of the queue, save the data into user + * buffer, and push the item back onto the end of the list. + * Same functionality as pop/insert, but saves a malloc/free + */ +#define	BENCH_Q_POP_PUSH(queue, buf) do {		\ +	struct bench_qentry *popped = queue.head;	\ +	if (popped == NULL)				\ +		break;					\ +	if (queue.head->next == NULL)			\ +		queue.head = queue.tail = NULL;		\ +	else						\ +		queue.head = queue.head->next;		\ +	memcpy(buf, popped->data, sizeof(buf));	\ +	if (queue.head == NULL)				\ +		queue.head = queue.tail = popped;	\ +	else {						\ +		queue.tail->next = popped;		\ +		queue.tail = popped;			\ +	}						\ +} while (0) + +typedef enum { +	T_PUT, +	T_GET, +	T_DELETE, +	T_PUT_GET, +	T_PUT_DELETE, +	T_PUT_GET_DELETE, +	T_GET_DELETE, +	T_MIXED +} test_type; + +typedef struct +{ +	u_int32_t ksize; +	u_int32_t dsize; +	size_t orderedkeys; +	size_t num_dups; +	u_int32_t pagesz; +	u_int32_t cachesz; +	u_int32_t pcount; +	size_t gcount; +	size_t cursor_del; +	size_t verbose; +	test_type workload; +	u_int32_t seed; +	size_t presize; +	DBTYPE type; +	char   *ts; +	char   *message; +	/* Fields used to store timing information */ +	db_timespec put_time; +	db_timespec get_time; +	db_timespec del_time; +	db_timespec tot_time; +} CONFIG; diff --git a/db-4.8.30/test_micro/source/bench.h b/db-4.8.30/test_micro/source/bench.h new file mode 100644 index 0000000..08493ab --- /dev/null +++ b/db-4.8.30/test_micro/source/bench.h @@ -0,0 +1,217 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2005-2009 Oracle.  All rights reserved. + * + * $Id$ + */ +#ifndef _BENCH_H_ +#define	_BENCH_H_ +#include "db_config.h" + +#include "db_int.h" + +#if DB_VERSION_MAJOR < 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 5 +/* + * Older releases of Berkeley DB don't include standard include files in + * db_int.h. + */ +#ifdef DB_WIN32 +#define	WIN32_LEAN_AND_MEAN	1 +#include <windows.h> +#include <direct.h> +#include <sys/timeb.h> +#else +#include <sys/stat.h> +#include <sys/time.h> + +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#endif +#endif + +#define	TESTDIR		"TESTDIR" +#define	TESTFILE	"test_micro.db" + +/* + * Implement a custom assert to allow consistent behavior across builds and + * platforms. + * + * The BDB library DB_ASSERT implementation is only enabled in diagnostic + * builds -- so is not suitable here. + */ +#define	DB_BENCH_ASSERT(e) do {						\ +	(e) ? (void)0 :							\ +	    (fprintf(stderr,						\ +	    "assert failure: %s/%d: \"%s\"\n", __FILE__, __LINE__, #e),	\ +	    b_util_abort());						\ +} while (0) + +#ifndef	NS_PER_SEC +#define	NS_PER_SEC	1000000000	/* Nanoseconds in a second */ +#endif +#ifndef	NS_PER_US +#define	NS_PER_US	1000		/* Nanoseconds in a microsecond */ +#endif +#ifndef	MS_PER_NS +#define	MS_PER_NS	1000000		/* Milliseconds in a nanosecond */ +#endif + +#ifdef DB_TIMEOUT_TO_TIMESPEC +/* + * We have the timer routines in the Berkeley DB library after their conversion + * to the POSIX timespec interfaces.  We'd rather use something that gives us + * better information than elapsed wallclock time, so use getrusage instead if + * it's available. + */ +#ifdef HAVE_GETRUSAGE +#include <sys/resource.h> + +#define	SET_TIMER_FROM_GETRUSAGE(tp) do {				\ +	struct rusage __usage;						\ +	DB_BENCH_ASSERT(getrusage(RUSAGE_SELF, &__usage) == 0);		\ +	(tp)->tv_sec =							\ +	    __usage.ru_utime.tv_sec + __usage.ru_stime.tv_sec;		\ +	(tp)->tv_nsec = NS_PER_US *					\ +	    (__usage.ru_utime.tv_usec + __usage.ru_stime.tv_usec);	\ +} while (0); + +#define	TIMER_START	SET_TIMER_FROM_GETRUSAGE(&__start_time); +#define	TIMER_STOP	SET_TIMER_FROM_GETRUSAGE(&__end_time); + +#elif defined(DB_WIN32) && !defined(DB_WINCE) + +#define	SET_TIMER_FROM_GETPROCESSTIMES(tp) do {				\ +	FILETIME lpCreationTime, lpExitTime, lpKernelTime, lpUserTIme;	\ +	LARGE_INTEGER large_int;					\ +	LONGLONG __ns_since_epoch;					\ +	DB_BENCH_ASSERT(						\ +	    GetProcessTimes(GetCurrentProcess(), &lpCreationTime,	\ +	    &lpExitTime, &lpKernelTime, &lpUserTIme) != 0);		\ +	memcpy(&large_int, &lpKernelTime, sizeof(lpKernelTime));	\ +	__ns_since_epoch = (large_int.QuadPart * 100);			\ +	(tp)->tv_sec = (time_t)(__ns_since_epoch / NS_PER_SEC);		\ +	(tp)->tv_nsec = (long)(__ns_since_epoch % NS_PER_SEC);		\ +	memcpy(&large_int, &lpUserTIme, sizeof(lpUserTIme));		\ +	__ns_since_epoch = (large_int.QuadPart * 100);			\ +	(tp)->tv_sec += (time_t)(__ns_since_epoch / NS_PER_SEC);	\ +	(tp)->tv_nsec += (long)(__ns_since_epoch % NS_PER_SEC);		\ +} while (0); + +#define	TIMER_START	SET_TIMER_FROM_GETPROCESSTIMES(&__start_time); +#define	TIMER_STOP	SET_TIMER_FROM_GETPROCESSTIMES(&__end_time); + +#else /* !HAVEGETRUSAGE && !DB_WIN32 */ + +#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 6 +#define	TIMER_START	__os_gettime(NULL, &__start_time, 1) +#define	TIMER_STOP	__os_gettime(NULL, &__end_time, 1) +#else +#define	TIMER_START	__os_gettime(NULL, &__start_time) +#define	TIMER_STOP	__os_gettime(NULL, &__end_time) +#endif +#endif /* !HAVE_GETRUSAGE */ + +#else /* !DB_TIMEOUT_TO_TIMESPEC */ + +#if defined(HAVE_CLOCK_GETTIME) +typedef struct timespec db_timespec; +#else +typedef struct { +	time_t	tv_sec;				/* seconds */ +	long	tv_nsec;			/* nanoseconds */ +} db_timespec; +#endif + +#define	timespecadd(vvp, uvp)						\ +	do {								\ +		(vvp)->tv_sec += (uvp)->tv_sec;				\ +		(vvp)->tv_nsec += (uvp)->tv_nsec;			\ +		if ((vvp)->tv_nsec >= NS_PER_SEC) {			\ +			(vvp)->tv_sec++;				\ +			(vvp)->tv_nsec -= NS_PER_SEC;			\ +		}							\ +	} while (0) +#define	timespecsub(vvp, uvp)						\ +	do {								\ +		(vvp)->tv_sec -= (uvp)->tv_sec;				\ +		(vvp)->tv_nsec -= (uvp)->tv_nsec;			\ +		if ((vvp)->tv_nsec < 0) {				\ +			(vvp)->tv_sec--;				\ +			(vvp)->tv_nsec += NS_PER_SEC;			\ +		}							\ +	} while (0) + +#define	TIMER_START	CLOCK(__start_time) +#define	TIMER_STOP	CLOCK(__end_time) + +#if defined(HAVE_CLOCK_GETTIME) +#define	CLOCK(tm) do {							\ +	DB_BENCH_ASSERT(clock_gettime(					\ +	    CLOCK_REALTIME, (struct timespec *)&(tm)) == 0);		\ +} while (0) +#elif defined(DB_WIN32) +#define	CLOCK(tm) do {							\ +	struct _timeb __now;						\ +	_ftime(&__now);							\ +	(tm).tv_sec = __now.time;					\ +	(tm).tv_nsec = __now.millitm * MS_PER_NS;			\ +} while (0) +#else +#define	CLOCK(tm) do {							\ +	struct timeval __tp;						\ +	DB_BENCH_ASSERT(gettimeofday(&__tp, NULL) == 0);		\ +	(tm).tv_sec = __tp.tv_sec;					\ +	(tm).tv_nsec = __tp.tv_usec * NS_PER_US;			\ +} while (0) +#endif +#endif /* !DB_TIMEOUT_TO_TIMESPEC */ + +extern db_timespec __start_time, __end_time; + +#define	TIMER_GET(tm) do {						\ +	tm = __end_time;						\ +	timespecsub(&(tm), &__start_time);				\ +} while (0) +#define	TIMER_DISPLAY(ops) do {						\ +	db_timespec __tmp_time;						\ +	__tmp_time = __end_time;					\ +	timespecsub(&__tmp_time, &__start_time);			\ +	TIME_DISPLAY(ops, __tmp_time);					\ +} while (0) +#define	TIME_DISPLAY(ops, tm) do {					\ +	double __secs;							\ +	int __major, __minor, __patch;					\ +	__secs = (tm).tv_sec + (double)(tm).tv_nsec / NS_PER_SEC;	\ +	(void)db_version(&__major, &__minor, &__patch);			\ +	printf("%d.%d.%d\t%.2f\n", __major, __minor, __patch,		\ +	    (__secs == 0) ? 0.0 : (ops) / __secs);			\ +} while (0) + +extern char *progname;					/* program name */ + +int  b_curalloc __P((int, char *[])); +int  b_curwalk __P((int, char *[])); +int  b_del __P((int, char *[])); +int  b_get __P((int, char *[])); +int  b_inmem __P((int, char *[])); +int  b_latch __P((int, char *[])); +int  b_load __P((int, char *[])); +int  b_open __P((int, char *[])); +int  b_put __P((int, char *[])); +int  b_recover __P((int, char *[])); +int  b_txn __P((int, char *[])); +int  b_txn_write __P((int, char *[])); +int  b_uname __P((void)); +void b_util_abort __P((void)); +int  b_util_dir_setup __P((void)); +int  b_util_dir_teardown __P((void)); +int  b_util_have_hash __P((void)); +int  b_util_have_queue __P((void)); +int  b_util_unlink __P((char *)); +int  b_workload __P((int, char *[])); +u_int32_t part_callback __P((DB *, DBT *)); + +#endif /* !_BENCH_H_ */ diff --git a/db-4.8.30/test_micro/source/test_micro.c b/db-4.8.30/test_micro/source/test_micro.c new file mode 100644 index 0000000..49b43de --- /dev/null +++ b/db-4.8.30/test_micro/source/test_micro.c @@ -0,0 +1,223 @@ +/* + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2005-2009 Oracle.  All rights reserved. + * + * $Id$ + */ + +#include "bench.h" + +int main __P((int, char *[])); + +static int  run __P((char *)); +static int  usage __P((void)); + +char *progname;					/* program name */ +db_timespec __start_time, __end_time;		/* TIMER_START & TIMER_END */ + +static int test_start = 1;			/* first test to run */ +static int test_end = 0;			/* last test to run */ + +static struct { +	char *name;				/* command name */ +	int (*f)(int, char *[]);		/* function */ +} cmdlist[] = { +	{ "b_curalloc", b_curalloc }, +	{ "b_curwalk", b_curwalk }, +	{ "b_del", b_del }, +	{ "b_get", b_get }, +	{ "b_inmem", b_inmem }, +	{ "b_latch", b_latch }, +	{ "b_load", b_load }, +	{ "b_open", b_open }, +	{ "b_put", b_put }, +	{ "b_recover", b_recover }, +	{ "b_txn", b_txn }, +	{ "b_txn_write", b_txn_write }, +	{ "b_workload", b_workload }, +	{ NULL, NULL } +}; + +int +main(argc, argv) +	int argc; +	char *argv[]; +{ +	extern char *optarg; +	extern int optind; +	int ch, ret; +	char *run_directory, *ifile; + +	if ((progname = __db_rpath(argv[0])) == NULL) +		progname = argv[0]; +	else +		++progname; + +#ifdef DB_BREW +	if (bdb_brew_begin() != 0) { +		fprintf(stderr, +		    "%s: failed to initialize Berkeley DB on BREW\n"); +		return (EXIT_FAILURE); +	} +#endif + +	run_directory = NULL; +	ifile = "run.std"; +	while ((ch = getopt(argc, argv, "d:e:i:s:")) != EOF) +		switch (ch) { +		case 'd': +			run_directory = optarg; +			break; +		case 'e': +			test_end = atoi(optarg); +			break; +		case 'i': +			ifile = optarg; +			break; +		case 's': +			test_start = atoi(optarg); +			break; +		case '?': +		default: +			return (usage()); +		} +	argc -= optind; +	argv += optind; + +	/* Run in the target directory. */ +	if (run_directory != NULL && chdir(run_directory) != 0) { +		fprintf(stderr, +		    "%s: %s: %s\n", progname, run_directory, strerror(errno)); +		return (1); +	} + +	/* Clean up any left-over test directory. */ +	if (b_util_dir_teardown()) +		return (1); + +	ret = run(ifile); + +#ifdef DB_BREW +	bdb_brew_end(); +#endif + +	return (ret ? EXIT_FAILURE : EXIT_SUCCESS); +} + +/* + * run -- + *	Read a configuration file and run the tests. + */ +static int +run(ifile) +	char *ifile; +{ +#ifdef HAVE_GETOPT_OPTRESET +	extern int optreset; +#endif +	extern int optind; +	static int test_cur = 0; +	FILE *ifp; +	int argc, cmdindx, lineno, ret; +	char *p, cmd[1024], path[1024], **argv; + +	/* Identify the run. */ +	if (b_uname() != 0) +		return (1); + +	/* Open the list of tests. */ +	if ((ifp = fopen(ifile, "r")) == NULL) { +		fprintf(stderr, +		    "%s: %s: %s\n", progname, ifile, strerror(errno)); +		return (1); +	} + +	for (lineno = 1; fgets(cmd, sizeof(cmd), ifp) != NULL; ++lineno) { +		/* +		 * Nul-terminate the command line; check for a trailing \r +		 * on Windows. +		 */ +		if ((p = strchr(cmd, '\n')) == NULL) { +format_err:		fprintf(stderr, "%s: %s: line %d: illegal input\n", +			    progname, ifile, lineno); +			return (1); +		} +		if (p > cmd && p[-1] == '\r') +			--p; +		*p = '\0'; + +		/* Skip empty lines and comments. */ +		if (cmd[0] == '\0' || cmd[0] == '#') +			continue; + +		/* Optionally limit the test run to specific tests. */ +		if (++test_cur < test_start || +		    (test_end != 0 && test_cur > test_end)) +			continue; + +		fprintf(stderr, "%d: %s\n", test_cur, cmd); + +		/* Find the command. */ +		if ((p = strchr(cmd, ' ')) == NULL) +			goto format_err; +		*p++ = '\0'; +		for (cmdindx = 0; cmdlist[cmdindx].name != NULL; ++cmdindx) +			if (strcmp(cmd, cmdlist[cmdindx].name) == 0) +				break; +		if (cmdlist[cmdindx].name == NULL) +			goto format_err; + +		/* Build argc/argv. */ +		if (__db_util_arg(cmd, p, &argc, &argv) != 0) +			return (1); + +		/* Re-direct output into the test log file.  */ +		(void)snprintf(path, sizeof(path), "%d", test_cur); +		if (freopen(path, "a", stdout) == NULL) { +			fprintf(stderr, +			    "%s: %s: %s\n", progname, path, strerror(errno)); +			return (1); +		} + +		/* +		 * Each underlying "program" re-parses its arguments -- +		 * reset getopt. +		 */ +#ifdef HAVE_GETOPT_OPTRESET +		optreset = 1; +#endif +		optind = 1; + +		/* Prepare the test directory. */ +		if (b_util_dir_setup()) +			return (1); + +		ret = cmdlist[cmdindx].f(argc, argv); + +		/* Clean up the test directory. */ +		if (b_util_dir_teardown()) +			return (1); + +		(void)fflush(stdout); + +#if DB_VERSION_MAJOR < 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 1 +		__os_free(NULL, argv, 0); +#else +		__os_free(NULL, argv); +#endif +		if (ret != 0) +			return (ret); +	} + +	return (0); +} + +static int +usage() +{ +	(void)fprintf(stderr, +	    "usage: %s [-d directory] [-e end] [-i input] [-s start]\n", +	    progname); +	return (EXIT_FAILURE); +} diff --git a/db-4.8.30/test_micro/test_micro b/db-4.8.30/test_micro/test_micro new file mode 100644 index 0000000..af3e358 --- /dev/null +++ b/db-4.8.30/test_micro/test_micro @@ -0,0 +1,170 @@ +#! /bin/sh +# +# $Id$ +LIBS=${LIBS:-"-lpthread"} +WINBUILDDIR="Win32/Release" + +CYGWIN=0 +HOSTOS="`uname -o 2>/dev/null||uname -s 2>/dev/null`" +if test `echo "$HOSTOS"|grep -i cygwin|wc -l` -gt 0;then +	CYGWIN=1 +fi + +# build_test_micro_posix +#	Build test_micro on a POSIX system. +build_test_micro_posix() +{ +	# See if there's a test_micro binary already. +	test $clean -eq 0 && test -x test_micro && return 0 + +	echo 'Compiling test_micro on posix system...' +	rm -f test_micro +	CC=${CC:-gcc} +	if [ "$CC" = "gcc" ]; then +		CC="$CC -O3 -Wall" +	else +		CC="$CC -O" +	fi +	$CC -I. -I../dbinc -I../dbinc_auto -I.. -I$h/source \ +	    $SRC -o test_micro ./libdb.a $LIBS || return 1 +} + +# build_test_micro_windows +#	Build test_micro on a Windows system. +build_test_micro_windows() +{ +	# See if there's a test_micro binary already. +	test $clean -eq 0 && test -x test_micro && return 0 + +	echo 'Compiling test_micro on windows ...' +	rm -f test_micro + +	cl /nologo /o test_micro /DDB_WIN32 /G6 /Ox /MD\ +	  -I./  -I../ -I$h/source/ -I../dbinc -I../dbinc_auto $SRC $WINSRC\ +	    ./$WINBUILDDIR/libdb*.lib ./Release/libdb*.lib ws2_32.lib advapi32.lib  +} + +# run -- +#	$1: args +run() +{ +	# You can set the MAJOR and MINOR environment variables to limit +	# the BDB releases on which the tests are run. +	echo Versions db-${MAJOR:-[3-9]}.${MINOR:-*}.* +	for i in db-${MAJOR:-[3-9]}.${MINOR:-*}.*; do + +		major=`echo $i|sed "s/db-//g"|cut -d . -f 1` +		minor=`echo $i|sed "s/db-//g"|cut -d . -f 2` +		if test $major -gt "4";then +			WINBUILDDIR="Win32/Release" +		elif test $major -lt "4";then +			WINBUILDDIR="Release" +		elif test "X$minor" = "X" -o "$minor" -lt "8";then +			WINBUILDDIR="Release" +		else +			WINBUILDDIR="Win32/Release" +		fi + +		if [ -f $i/$variant/libdb.a ] ; then +			(cd $i/$variant/ && +			    build_test_micro_posix || exit 1) +		elif [ -f $i/build_windows/${WINBUILDDIR}/libdb??.lib ] ; then +			(cd $i/build_windows && +			    build_test_micro_windows || exit 1) +		 fi + +		echo "$i run begins: `date`" +		echo "test_micro $1..." +		if [ -f $i/$variant/libdb.a ] ; then +			(cd $i/$variant/ && ./test_micro $1 || exit 1) +			if [ -f $t/gmon.out ] ; then +				mv $t/gmon.out $i/$variant +				gprof $i/$variant/.libs/lt-test_micro $i/$variant/gmon.out > $i/$variant/gprof.out +			fi +		elif [ -f $i/build_windows/${WINBUILDDIR}/libdb??.lib  ] ; then +			(cd $i/build_windows/ && ./test_micro $1 || exit 1) +		fi +		echo "$i run ends: `date`" +	done +} + +# Get a path to this shellscript. +t=`dirname $0` +h=`(cd $t && pwd)` +if [ "$CYGWIN" = "1" ];then +	h="`cygpath -m -a \"$h\"`" +fi +# We may need to re-compile, create a list of our sources. +SRC="$h/source/b_curalloc.c $h/source/b_curwalk.c $h/source/b_del.c +$h/source/b_get.c $h/source/b_inmem.c $h/source/b_load.c $h/source/b_latch.c +$h/source/b_open.c $h/source/b_put.c $h/source/b_recover.c +$h/source/b_txn.c $h/source/b_txn_write.c $h/source/b_uname.c +$h/source/b_util.c $h/source/b_workload.c $h/source/test_micro.c +$h/../common/util_arg.c" + +WINSRC="$h/../clib/getopt.c" + +# Process arguments. +clean=0					# Rebuild test_micro +workload=0				# Run workload tests +start_test=0				# Start test +end_test=0				# End test +variant=build_unix +while : +	do case "$1" in +	-c)				# Rebuild test_micro. +		clean=1 +		shift;; +	-w)				# Run workload tests +		workload=1 +		shift;; +	[1-9]*-[0-9]*)			# Range: -3, 3-, 3-10 +		start_test=`echo $1|sed 's/-.*//'` +		start_test=${start_test:=1} +		end_test=`echo $1|sed 's/.*-//'` +		end_test=${end_test:=0} +		shift;; +	[1-9]*)				# Specific test +		start_test="$1" +		end_test="$1" +		shift;; +	-v)	variant=$2	# get code here, rather than from build_unix +		shift; shift;; +	*) +		break;; +	esac +done +test "$#" -ne 0 && { +	echo 'usage: test_micro [-cw] [# | #- | -# | #-#]' >& 2 +	exit 1 +} + +if test $start_test != 0; then +	cmd="$cmd -s $start_test" +fi +if test $end_test != 0; then +	cmd="$cmd -e $end_test" +fi + +# Create the run directory, and initialize test_micro's arguments. +t=RUN.`hostname | sed 's/\..*//'` +[ -d $t ] || mkdir $t +if [ "$CYGWIN" = "1" ];then +	cmd="$cmd -d `(cd $t && cygpath -m -a \"$PWD\")`" +else +	cmd="$cmd -d `(cd $t && pwd)`" +fi +# Set input file. +if test "$workload" -eq 1; then +	cmd="$cmd -i $h/configs/run.workload" +else +	cmd="$cmd -i $h/configs/run.std" +fi + +# Flush any I/O, just to get as a clean a timing as we can, ignore errors, +# sync is privleged on some systems. +(sync && sleep 1 2>&1) > /dev/null + +run "$cmd" + +exit 0 | 
