Import BSDDB 4.7.25 (as of svn r89086)
This commit is contained in:
84
test_micro/README
Normal file
84
test_micro/README
Normal file
@@ -0,0 +1,84 @@
|
||||
# $Id: README,v 1.6 2007/12/21 19:22:01 bostic Exp $
|
||||
|
||||
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.
|
||||
115
test_micro/configs/run.small
Normal file
115
test_micro/configs/run.small
Normal file
@@ -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
|
||||
116
test_micro/configs/run.std
Normal file
116
test_micro/configs/run.std
Normal file
@@ -0,0 +1,116 @@
|
||||
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
|
||||
38
test_micro/configs/run.workload
Normal file
38
test_micro/configs/run.workload
Normal file
@@ -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
|
||||
117
test_micro/report
Normal file
117
test_micro/report
Normal file
@@ -0,0 +1,117 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# $Id: report,v 1.7 2008/02/07 18:11:34 bostic Exp $
|
||||
|
||||
# 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>"
|
||||
t=`echo "400 * ($avg/($max + $max/10))" | bc -l`
|
||||
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
|
||||
40
test_micro/report.awk
Normal file
40
test_micro/report.awk
Normal file
@@ -0,0 +1,40 @@
|
||||
# $Id: report.awk,v 1.3 2008/01/02 15:54:03 bostic Exp $
|
||||
|
||||
/^[^#]/ {
|
||||
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");
|
||||
}
|
||||
}
|
||||
101
test_micro/source/LIST
Normal file
101
test_micro/source/LIST
Normal file
@@ -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
|
||||
65
test_micro/source/b_curalloc.c
Normal file
65
test_micro/source/b_curalloc.c
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* $Id: b_curalloc.c 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
#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);
|
||||
}
|
||||
204
test_micro/source/b_curwalk.c
Normal file
204
test_micro/source/b_curwalk.c
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* $Id: b_curwalk.c 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
#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);
|
||||
}
|
||||
162
test_micro/source/b_del.c
Normal file
162
test_micro/source/b_del.c
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* $Id: b_del.c 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
#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);
|
||||
}
|
||||
129
test_micro/source/b_get.c
Normal file
129
test_micro/source/b_get.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* $Id: b_get.c 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
#include "bench.h"
|
||||
|
||||
static int usage(void);
|
||||
|
||||
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 >= 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);
|
||||
}
|
||||
423
test_micro/source/b_inmem.c
Normal file
423
test_micro/source/b_inmem.c
Normal file
@@ -0,0 +1,423 @@
|
||||
/*
|
||||
* $Id: b_inmem.c 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
|
||||
#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;
|
||||
char *progname;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
(void)dbenv->memp_stat(dbenv, &gsp, NULL, 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;
|
||||
|
||||
(void)dbenv->memp_stat(dbenv, &gsp, NULL, 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;
|
||||
|
||||
(void)dbenv->memp_stat(dbenv, &gsp, NULL, 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;
|
||||
|
||||
(void)dbenv->memp_stat(dbenv, &gsp, NULL, 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 byte key/data pairs\n",
|
||||
ops, keysize, datasize);
|
||||
} 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 byte key/data pairs\n",
|
||||
ops, keysize, datasize);
|
||||
#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 byte key/data pairs\n",
|
||||
ops, keysize, datasize);
|
||||
} 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 byte key/data pairs\n",
|
||||
ops, keysize, datasize);
|
||||
#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 byte key/data pairs\n",
|
||||
ops, keysize, datasize);
|
||||
} 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
|
||||
160
test_micro/source/b_load.c
Normal file
160
test_micro/source/b_load.c
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* $Id: b_load.c 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
#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);
|
||||
}
|
||||
140
test_micro/source/b_open.c
Normal file
140
test_micro/source/b_open.c
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* $Id: b_open.c 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
#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);
|
||||
}
|
||||
217
test_micro/source/b_put.c
Normal file
217
test_micro/source/b_put.c
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* $Id: b_put.c 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
#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;
|
||||
int ch, dsize, 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 = 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, (u_int32_t)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);
|
||||
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;
|
||||
}
|
||||
|
||||
DB_BENCH_ASSERT(
|
||||
(data.data = malloc(data.size = (size_t)dsize)) != NULL);
|
||||
|
||||
/* Store the key/data pair count times. */
|
||||
TIMER_START;
|
||||
for (i = 0; i < count; ++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 = pkey->data;
|
||||
skey->size = pkey->size;
|
||||
|
||||
COMPQUIET(dbp, NULL);
|
||||
COMPQUIET(pdata, 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);
|
||||
}
|
||||
137
test_micro/source/b_recover.c
Normal file
137
test_micro/source/b_recover.c
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* $Id: b_recover.c 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
#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);
|
||||
}
|
||||
89
test_micro/source/b_txn.c
Normal file
89
test_micro/source/b_txn.c
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* $Id: b_txn.c 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
#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);
|
||||
}
|
||||
168
test_micro/source/b_txn_write.c
Normal file
168
test_micro/source/b_txn_write.c
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* $Id: b_txn_write.c 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
#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);
|
||||
}
|
||||
143
test_micro/source/b_uname.c
Normal file
143
test_micro/source/b_uname.c
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* $Id: b_uname.c 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
|
||||
#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
|
||||
154
test_micro/source/b_util.c
Normal file
154
test_micro/source/b_util.c
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* $Id: b_util.c 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
|
||||
#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
|
||||
}
|
||||
623
test_micro/source/b_workload.c
Normal file
623
test_micro/source/b_workload.c
Normal file
@@ -0,0 +1,623 @@
|
||||
/*
|
||||
* $Id: b_workload.c 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
|
||||
#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;
|
||||
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.
|
||||
*/
|
||||
for (i = 0; i < 2 * config->pcount; ++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);
|
||||
}
|
||||
149
test_micro/source/b_workload.h
Normal file
149
test_micro/source/b_workload.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* $Id: b_workload.h 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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
|
||||
{
|
||||
size_t ksize;
|
||||
size_t dsize;
|
||||
size_t orderedkeys;
|
||||
size_t num_dups;
|
||||
size_t pagesz;
|
||||
size_t cachesz;
|
||||
size_t pcount;
|
||||
size_t gcount;
|
||||
size_t cursor_del;
|
||||
size_t verbose;
|
||||
test_type workload;
|
||||
size_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;
|
||||
211
test_micro/source/bench.h
Normal file
211
test_micro/source/bench.h
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* $Id: bench.h 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
#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 */
|
||||
|
||||
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_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 *[]));
|
||||
|
||||
#endif /* !_BENCH_H_ */
|
||||
217
test_micro/source/test_micro.c
Normal file
217
test_micro/source/test_micro.c
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* $Id: test_micro.c 63573 2008-05-23 21:43:21Z trent.nelson $
|
||||
*/
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
int main __P((int, char *[]));
|
||||
|
||||
static int run __P((char *));
|
||||
static int usage __P((void));
|
||||
|
||||
char *progname; /* program name */
|
||||
|
||||
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_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);
|
||||
}
|
||||
135
test_micro/test_micro
Normal file
135
test_micro/test_micro
Normal file
@@ -0,0 +1,135 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# $Id: test_micro,v 1.51 2008/04/14 02:21:47 david Exp $
|
||||
|
||||
# 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...'
|
||||
rm -f test_micro
|
||||
CC=${CC:-gcc}
|
||||
if [ "$CC" = "gcc" ]; then
|
||||
CC="$CC -O3 -Wall"
|
||||
else
|
||||
CC="$CC -O"
|
||||
fi
|
||||
$CC -I. -I.. -I../include -I../include_auto -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...'
|
||||
rm -f test_micro
|
||||
cl /nologo /o test_micro /DDB_WIN32 /G6 /Ox /MD\
|
||||
-I.. -I../.. -I../include -I../include_auto $SRC $WINSRC\
|
||||
libdb*.lib ws2_32.lib advapi32.lib || return 1
|
||||
}
|
||||
|
||||
# run --
|
||||
# $1: args
|
||||
run()
|
||||
{
|
||||
# You can set the MAJOR and MINOR environment variables to limit
|
||||
# the BDB releases on which the tests are run.
|
||||
for i in db-${MAJOR:-[3-9]}.${MINOR:-*}.*; do
|
||||
if [ -f $i/build_unix/libdb.a ] ; then
|
||||
(cd $i/build_unix/ &&
|
||||
build_test_micro_posix || exit 1)
|
||||
elif [ -f $i/build_win*/Release/libdb??.lib ] ; then
|
||||
(cd $i/build_win*/Release &&
|
||||
build_test_micro_windows || exit 1)
|
||||
fi
|
||||
|
||||
echo "$i run begins: `date`"
|
||||
echo "test_micro $1..."
|
||||
if [ -f $i/build_unix/libdb.a ] ; then
|
||||
(cd $i/build_unix/ && ./test_micro $1 || exit 1)
|
||||
elif [ -f $i/build_win*/Release/libdb??.lib ] ; then
|
||||
(cd $i/build_win*/Release && ./test_micro $1 || exit 1)
|
||||
fi
|
||||
echo "$i run ends: `date`"
|
||||
done
|
||||
}
|
||||
|
||||
# Get a path to this shellscript.
|
||||
t=`dirname $0`
|
||||
h=`(cd $t && echo $PWD)`
|
||||
|
||||
# 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_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
|
||||
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;;
|
||||
*)
|
||||
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
|
||||
cmd="$cmd -d `(cd $t && pwd)`"
|
||||
|
||||
# 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
|
||||
Reference in New Issue
Block a user