summaryrefslogtreecommitdiff
path: root/bdb/test/mpool.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'bdb/test/mpool.tcl')
-rw-r--r--bdb/test/mpool.tcl420
1 files changed, 420 insertions, 0 deletions
diff --git a/bdb/test/mpool.tcl b/bdb/test/mpool.tcl
new file mode 100644
index 00000000000..b2eb2252037
--- /dev/null
+++ b/bdb/test/mpool.tcl
@@ -0,0 +1,420 @@
+# See the file LICENSE for redistribution information.
+#
+# Copyright (c) 1996, 1997, 1998, 1999, 2000
+# Sleepycat Software. All rights reserved.
+#
+# $Id: mpool.tcl,v 11.34 2001/01/18 04:58:07 krinsky Exp $
+#
+# Options are:
+# -cachesize {gbytes bytes ncache}
+# -nfiles <files>
+# -iterations <iterations>
+# -pagesize <page size in bytes>
+# -dir <directory in which to store memp>
+# -stat
+proc memp_usage {} {
+ puts "memp -cachesize {gbytes bytes ncache}"
+ puts "\t-nfiles <files>"
+ puts "\t-iterations <iterations>"
+ puts "\t-pagesize <page size in bytes>"
+ puts "\t-dir <memp directory>"
+ puts "\t-mem {private system}"
+ return
+}
+
+proc mpool { args } {
+ source ./include.tcl
+ global errorCode
+
+ puts "mpool {$args} running"
+ # Set defaults
+ set cachearg " -cachesize {0 200000 3}"
+ set nfiles 5
+ set iterations 500
+ set pagesize "512 1024 2048 4096 8192"
+ set npages 100
+ set procs 4
+ set seeds ""
+ set shm_key 1
+ set dostat 0
+ set flags ""
+ for { set i 0 } { $i < [llength $args] } {incr i} {
+ switch -regexp -- [lindex $args $i] {
+ -c.* {
+ incr i
+ set cachesize [lindex $args $i]
+ set cachearg " -cachesize $cachesize"
+ }
+ -d.* { incr i; set testdir [lindex $args $i] }
+ -i.* { incr i; set iterations [lindex $args $i] }
+ -me.* {
+ incr i
+ if { [string \
+ compare [lindex $args $i] private] == 0 } {
+ set flags -private
+ } elseif { [string \
+ compare [lindex $args $i] system] == 0 } {
+ #
+ # We need to use a shm id. Use one
+ # that is the same each time so that
+ # we do not grow segments infinitely.
+ set flags "-system_mem -shm_key $shm_key"
+ } else {
+ puts -nonewline \
+ "FAIL:[timestamp] Usage: "
+ memp_usage
+ return
+ }
+ }
+ -nf.* { incr i; set nfiles [lindex $args $i] }
+ -np.* { incr i; set npages [lindex $args $i] }
+ -pa.* { incr i; set pagesize [lindex $args $i] }
+ -pr.* { incr i; set procs [lindex $args $i] }
+ -se.* { incr i; set seeds [lindex $args $i] }
+ -st.* { set dostat 1 }
+ default {
+ puts -nonewline "FAIL:[timestamp] Usage: "
+ memp_usage
+ return
+ }
+ }
+ }
+
+ # Clean out old directory
+ env_cleanup $testdir
+
+ # Open the memp with region init specified
+ set ret [catch {eval {berkdb env -create -mode 0644}\
+ $cachearg {-region_init -home $testdir} $flags} res]
+ if { $ret == 0 } {
+ set env $res
+ } else {
+ # If the env open failed, it may be because we're on a platform
+ # such as HP-UX 10 that won't support mutexes in shmget memory.
+ # Or QNX, which doesn't support system memory at all.
+ # Verify that the return value was EINVAL or EOPNOTSUPP
+ # and bail gracefully.
+ error_check_good is_shm_test [is_substr $flags -system_mem] 1
+ error_check_good returned_error [expr \
+ [is_substr $errorCode EINVAL] || \
+ [is_substr $errorCode EOPNOTSUPP]] 1
+ puts "Warning:\
+ platform does not support mutexes in shmget memory."
+ puts "Skipping shared memory mpool test."
+ return
+ }
+ error_check_good env_open [is_substr $env env] 1
+
+ reset_env $env
+ env_cleanup $testdir
+
+ # Now open without region init
+ set env [eval {berkdb env -create -mode 0644}\
+ $cachearg {-home $testdir} $flags]
+ error_check_good evn_open [is_substr $env env] 1
+
+ memp001 $env \
+ $testdir $nfiles $iterations [lindex $pagesize 0] $dostat $flags
+ reset_env $env
+ set ret [berkdb envremove -home $testdir]
+ error_check_good env_remove $ret 0
+ env_cleanup $testdir
+
+ memp002 $testdir \
+ $procs $pagesize $iterations $npages $seeds $dostat $flags
+ set ret [berkdb envremove -home $testdir]
+ error_check_good env_remove $ret 0
+ env_cleanup $testdir
+
+ memp003 $testdir $iterations $flags
+ set ret [berkdb envremove -home $testdir]
+ error_check_good env_remove $ret 0
+
+ env_cleanup $testdir
+}
+
+proc memp001 {env dir n iter psize dostat flags} {
+ source ./include.tcl
+ global rand_init
+
+ puts "Memp001: {$flags} random update $iter iterations on $n files."
+
+ # Open N memp files
+ for {set i 1} {$i <= $n} {incr i} {
+ set fname "data_file.$i"
+ file_create $dir/$fname 50 $psize
+
+ set mpools($i) \
+ [$env mpool -create -pagesize $psize -mode 0644 $fname]
+ error_check_good mp_open [is_substr $mpools($i) $env.mp] 1
+ }
+
+ # Now, loop, picking files at random
+ berkdb srand $rand_init
+ for {set i 0} {$i < $iter} {incr i} {
+ set mpool $mpools([berkdb random_int 1 $n])
+ set p1 [get_range $mpool 10]
+ set p2 [get_range $mpool 10]
+ set p3 [get_range $mpool 10]
+ set p1 [replace $mpool $p1]
+ set p3 [replace $mpool $p3]
+ set p4 [get_range $mpool 20]
+ set p4 [replace $mpool $p4]
+ set p5 [get_range $mpool 10]
+ set p6 [get_range $mpool 20]
+ set p7 [get_range $mpool 10]
+ set p8 [get_range $mpool 20]
+ set p5 [replace $mpool $p5]
+ set p6 [replace $mpool $p6]
+ set p9 [get_range $mpool 40]
+ set p9 [replace $mpool $p9]
+ set p10 [get_range $mpool 40]
+ set p7 [replace $mpool $p7]
+ set p8 [replace $mpool $p8]
+ set p9 [replace $mpool $p9]
+ set p10 [replace $mpool $p10]
+ }
+
+ if { $dostat == 1 } {
+ puts [$env mpool_stat]
+ for {set i 1} {$i <= $n} {incr i} {
+ error_check_good mp_sync [$mpools($i) fsync] 0
+ }
+ }
+
+ # Close N memp files
+ for {set i 1} {$i <= $n} {incr i} {
+ error_check_good memp_close:$mpools($i) [$mpools($i) close] 0
+ fileremove -f $dir/data_file.$i
+ }
+}
+
+proc file_create { fname nblocks blocksize } {
+ set fid [open $fname w]
+ for {set i 0} {$i < $nblocks} {incr i} {
+ seek $fid [expr $i * $blocksize] start
+ puts -nonewline $fid $i
+ }
+ seek $fid [expr $nblocks * $blocksize - 1]
+
+ # We don't end the file with a newline, because some platforms (like
+ # Windows) emit CR/NL. There does not appear to be a BINARY open flag
+ # that prevents this.
+ puts -nonewline $fid "Z"
+ close $fid
+
+ # Make sure it worked
+ if { [file size $fname] != $nblocks * $blocksize } {
+ error "FAIL: file_create could not create correct file size"
+ }
+}
+
+proc get_range { mpool max } {
+ set pno [berkdb random_int 0 $max]
+ set p [$mpool get $pno]
+ error_check_good page [is_valid_page $p $mpool] TRUE
+ set got [$p pgnum]
+ if { $got != $pno } {
+ puts "Get_range: Page mismatch page |$pno| val |$got|"
+ }
+ set ret [$p init "Page is pinned by [pid]"]
+ error_check_good page_init $ret 0
+
+ return $p
+}
+
+proc replace { mpool p } {
+ set pgno [$p pgnum]
+
+ set ret [$p init "Page is unpinned by [pid]"]
+ error_check_good page_init $ret 0
+
+ set ret [$p put -dirty]
+ error_check_good page_put $ret 0
+
+ set p2 [$mpool get $pgno]
+ error_check_good page [is_valid_page $p2 $mpool] TRUE
+
+ return $p2
+}
+
+proc memp002 { dir procs psizes iterations npages seeds dostat flags } {
+ source ./include.tcl
+
+ puts "Memp002: {$flags} Multiprocess mpool tester"
+
+ if { [is_substr $flags -private] != 0 } {
+ puts "Memp002 skipping\
+ multiple processes not supported by private memory"
+ return
+ }
+ set iter [expr $iterations / $procs]
+
+ # Clean up old stuff and create new.
+ env_cleanup $dir
+
+ for { set i 0 } { $i < [llength $psizes] } { incr i } {
+ fileremove -f $dir/file$i
+ }
+ set e [eval {berkdb env -create -lock -home $dir} $flags]
+ error_check_good dbenv [is_valid_widget $e env] TRUE
+
+ set pidlist {}
+ for { set i 0 } { $i < $procs } {incr i} {
+ if { [llength $seeds] == $procs } {
+ set seed [lindex $seeds $i]
+ } else {
+ set seed -1
+ }
+
+ puts "$tclsh_path\
+ $test_path/mpoolscript.tcl $dir $i $procs \
+ $iter $psizes $npages 3 $flags > \
+ $dir/memp002.$i.out &"
+ set p [exec $tclsh_path $test_path/wrap.tcl \
+ mpoolscript.tcl $dir/memp002.$i.out $dir $i $procs \
+ $iter $psizes $npages 3 $flags &]
+ lappend pidlist $p
+ }
+ puts "Memp002: $procs independent processes now running"
+ watch_procs
+
+ reset_env $e
+}
+
+# Test reader-only/writer process combinations; we use the access methods
+# for testing.
+proc memp003 { dir {nentries 10000} flags } {
+ global alphabet
+ source ./include.tcl
+
+ puts "Memp003: {$flags} Reader/Writer tests"
+
+ if { [is_substr $flags -private] != 0 } {
+ puts "Memp003 skipping\
+ multiple processes not supported by private memory"
+ return
+ }
+
+ env_cleanup $dir
+ set psize 1024
+ set testfile mpool.db
+ set t1 $dir/t1
+
+ # Create an environment that the two processes can share
+ set c [list 0 [expr $psize * 10] 3]
+ set dbenv [eval {berkdb env \
+ -create -lock -home $dir -cachesize $c} $flags]
+ error_check_good dbenv [is_valid_env $dbenv] TRUE
+
+ # First open and create the file.
+
+ set db [berkdb_open -env $dbenv -create -truncate \
+ -mode 0644 -pagesize $psize -btree $testfile]
+ error_check_good dbopen/RW [is_valid_db $db] TRUE
+
+ set did [open $dict]
+ set txn ""
+ set count 0
+
+ puts "\tMemp003.a: create database"
+ set keys ""
+ # Here is the loop where we put and get each key/data pair
+ while { [gets $did str] != -1 && $count < $nentries } {
+ lappend keys $str
+
+ set ret [eval {$db put} $txn {$str $str}]
+ error_check_good put $ret 0
+
+ set ret [eval {$db get} $txn {$str}]
+ error_check_good get $ret [list [list $str $str]]
+
+ incr count
+ }
+ close $did
+ error_check_good close [$db close] 0
+
+ # Now open the file for read-only
+ set db [berkdb_open -env $dbenv -rdonly $testfile]
+ error_check_good dbopen/RO [is_substr $db db] 1
+
+ puts "\tMemp003.b: verify a few keys"
+ # Read and verify a couple of keys; saving them to check later
+ set testset ""
+ for { set i 0 } { $i < 10 } { incr i } {
+ set ndx [berkdb random_int 0 [expr $nentries - 1]]
+ set key [lindex $keys $ndx]
+ if { [lsearch $testset $key] != -1 } {
+ incr i -1
+ continue;
+ }
+
+ # The remote process stuff is unhappy with
+ # zero-length keys; make sure we don't pick one.
+ if { [llength $key] == 0 } {
+ incr i -1
+ continue
+ }
+
+ lappend testset $key
+
+ set ret [eval {$db get} $txn {$key}]
+ error_check_good get/RO $ret [list [list $key $key]]
+ }
+
+ puts "\tMemp003.c: retrieve and modify keys in remote process"
+ # Now open remote process where we will open the file RW
+ set f1 [open |$tclsh_path r+]
+ puts $f1 "source $test_path/test.tcl"
+ puts $f1 "flush stdout"
+ flush $f1
+
+ set c [concat "{" [list 0 [expr $psize * 10] 3] "}" ]
+ set remote_env [send_cmd $f1 \
+ "berkdb env -create -lock -home $dir -cachesize $c $flags"]
+ error_check_good remote_dbenv [is_valid_env $remote_env] TRUE
+
+ set remote_db [send_cmd $f1 "berkdb_open -env $remote_env $testfile"]
+ error_check_good remote_dbopen [is_valid_db $remote_db] TRUE
+
+ foreach k $testset {
+ # Get the key
+ set ret [send_cmd $f1 "$remote_db get $k"]
+ error_check_good remote_get $ret [list [list $k $k]]
+
+ # Now replace the key
+ set ret [send_cmd $f1 "$remote_db put $k $k$k"]
+ error_check_good remote_put $ret 0
+ }
+
+ puts "\tMemp003.d: verify changes in local process"
+ foreach k $testset {
+ set ret [eval {$db get} $txn {$key}]
+ error_check_good get_verify/RO $ret [list [list $key $key$key]]
+ }
+
+ puts "\tMemp003.e: Fill up the cache with dirty buffers"
+ foreach k $testset {
+ # Now rewrite the keys with BIG data
+ set data [replicate $alphabet 32]
+ set ret [send_cmd $f1 "$remote_db put $k $data"]
+ error_check_good remote_put $ret 0
+ }
+
+ puts "\tMemp003.f: Get more pages for the read-only file"
+ dump_file $db $txn $t1 nop
+
+ puts "\tMemp003.g: Sync from the read-only file"
+ error_check_good db_sync [$db sync] 0
+ error_check_good db_close [$db close] 0
+
+ set ret [send_cmd $f1 "$remote_db close"]
+ error_check_good remote_get $ret 0
+
+ # Close the environment both remotely and locally.
+ set ret [send_cmd $f1 "$remote_env close"]
+ error_check_good remote:env_close $ret 0
+ close $f1
+
+ reset_env $dbenv
+}