test083.tcl 4.32 KB
Newer Older
1 2
# See the file LICENSE for redistribution information.
#
jimw@mysql.com's avatar
jimw@mysql.com committed
3
# Copyright (c) 2000-2004
4 5
#	Sleepycat Software.  All rights reserved.
#
jimw@mysql.com's avatar
jimw@mysql.com committed
6
# $Id: test083.tcl,v 11.16 2004/01/28 03:36:31 bostic Exp $
7
#
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
8 9
# TEST	test083
# TEST	Test of DB->key_range.
10 11
proc test083 { method {pgsz 512} {maxitems 5000} {step 2} args} {
	source ./include.tcl
jimw@mysql.com's avatar
jimw@mysql.com committed
12 13 14 15

	global rand_init
	error_check_good set_random_seed [berkdb srand $rand_init] 0

16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
	set omethod [convert_method $method]
	set args [convert_args $method $args]

	puts "Test083 $method ($args): Test of DB->key_range"
	if { [is_btree $method] != 1 } {
		puts "\tTest083: Skipping for method $method."
		return
	}
	set pgindex [lsearch -exact $args "-pagesize"]
	if { $pgindex != -1 } {
		puts "Test083: skipping for specific pagesizes"
		return
	}

	# If we are using an env, then testfile should just be the db name.
	# Otherwise it is the test directory and the name.
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
32
	set txnenv 0
33 34 35 36 37 38 39 40
	set eindex [lsearch -exact $args "-env"]
	if { $eindex == -1 } {
		set testfile $testdir/test083.db
		set env NULL
	} else {
		set testfile test083.db
		incr eindex
		set env [lindex $args $eindex]
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
41 42 43 44 45
		set txnenv [is_txnenv $env]
		if { $txnenv == 1 } {
			append args " -auto_commit "
		}
		set testdir [get_home $env]
46 47 48 49 50 51 52 53 54 55 56 57
	}

	# We assume that numbers will be at most six digits wide
	error_check_bad maxitems_range [expr $maxitems > 999999] 1

	# We want to test key_range on a variety of sizes of btree.
	# Start at ten keys and work up to $maxitems keys, at each step
	# multiplying the number of keys by $step.
	for { set nitems 10 } { $nitems <= $maxitems }\
	    { set nitems [expr $nitems * $step] } {

		puts "\tTest083.a: Opening new database"
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
58 59 60
		if { $env != "NULL"} {
			set testdir [get_home $env]
		}
61
		cleanup $testdir $env
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
62
		set db [eval {berkdb_open -create -mode 0644} \
63 64 65
		    -pagesize $pgsz $omethod $args $testfile]
		error_check_good dbopen [is_valid_db $db] TRUE

ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
66 67
		t83_build $db $nitems $env $txnenv
		t83_test $db $nitems $env $txnenv
68 69 70 71 72

		error_check_good db_close [$db close] 0
	}
}

ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
73
proc t83_build { db nitems env txnenv } {
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
	source ./include.tcl

	puts "\tTest083.b: Populating database with $nitems keys"

	set keylist {}
	puts "\t\tTest083.b.1: Generating key list"
	for { set i 0 } { $i < $nitems } { incr i } {
		lappend keylist $i
	}

	# With randomly ordered insertions, the range of errors we
	# get from key_range can be unpredictably high [#2134].  For now,
	# just skip the randomization step.
	#puts "\t\tTest083.b.2: Randomizing key list"
	#set keylist [randomize_list $keylist]
	#puts "\t\tTest083.b.3: Populating database with randomized keys"

	puts "\t\tTest083.b.2: Populating database"
	set data [repeat . 50]
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
93
	set txn ""
94
	foreach keynum $keylist {
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
95 96 97 98 99 100 101 102 103 104
		if { $txnenv == 1 } {
			set t [$env txn]
			error_check_good txn [is_valid_txn $t $env] TRUE
			set txn "-txn $t"
		}
		set ret [eval {$db put} $txn {key[format %6d $keynum] $data}]
		error_check_good db_put $ret 0
		if { $txnenv == 1 } {
			error_check_good txn [$t commit] 0
		}
105 106 107
	}
}

ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
108
proc t83_test { db nitems env txnenv } {
109 110 111 112
	# Look at the first key, then at keys about 1/4, 1/2, 3/4, and
	# all the way through the database.  Make sure the key_ranges
	# aren't off by more than 10%.

ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
113 114 115 116 117 118 119 120
	if { $txnenv == 1 } {
		set t [$env txn]
		error_check_good txn [is_valid_txn $t $env] TRUE
		set txn "-txn $t"
	} else {
		set txn ""
	}
	set dbc [eval {$db cursor} $txn]
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
	error_check_good dbc [is_valid_cursor $dbc $db] TRUE

	puts "\tTest083.c: Verifying ranges..."

	for { set i 0 } { $i < $nitems } \
	    { incr i [expr $nitems / [berkdb random_int 3 16]] } {
		puts "\t\t...key $i"
		error_check_bad key0 [llength [set dbt [$dbc get -first]]] 0

		for { set j 0 } { $j < $i } { incr j } {
			error_check_bad key$j \
			    [llength [set dbt [$dbc get -next]]] 0
		}

		set ranges [$db keyrange [lindex [lindex $dbt 0] 0]]

		#puts $ranges
		error_check_good howmanyranges [llength $ranges] 3

		set lessthan [lindex $ranges 0]
		set morethan [lindex $ranges 2]

		set rangesum [expr $lessthan + [lindex $ranges 1] + $morethan]

		roughly_equal $rangesum 1 0.05

		# Wild guess.
		if { $nitems < 500 } {
			set tol 0.3
		} elseif { $nitems > 500 } {
			set tol 0.15
		}

		roughly_equal $lessthan [expr $i * 1.0 / $nitems] $tol

	}

	error_check_good dbc_close [$dbc close] 0
ram@mysql.r18.ru's avatar
ram@mysql.r18.ru committed
159 160 161
	if { $txnenv == 1 } {
		error_check_good txn [$t commit] 0
	}
162 163 164 165 166
}

proc roughly_equal { a b tol } {
	error_check_good "$a =~ $b" [expr $a - $b < $tol] 1
}