1
# See the file LICENSE for redistribution information.
3
# Copyright (c) 1999-2002
4
# Sleepycat Software. All rights reserved.
9
# TEST Test of cursor stability on duplicate pages.
11
# TEST Does the following:
12
# TEST a. Initialize things by DB->putting ndups dups and
13
# TEST setting a reference cursor to point to each.
14
# TEST b. c_put ndups dups (and correspondingly expanding
15
# TEST the set of reference cursors) after the last one, making sure
16
# TEST after each step that all the reference cursors still point to
17
# TEST the right item.
18
# TEST c. Ditto, but before the first one.
19
# TEST d. Ditto, but after each one in sequence first to last.
20
# TEST e. Ditto, but after each one in sequence from last to first.
21
# TEST occur relative to the new datum)
22
# TEST f. Ditto for the two sequence tests, only doing a
23
# TEST DBC->c_put(DB_CURRENT) of a larger datum instead of adding a
25
proc test073 { method {pagesize 512} {ndups 50} {tnum 73} args } {
29
set omethod [convert_method $method]
30
set args [convert_args $method $args]
33
set eindex [lsearch -exact $args "-env"]
35
# If we are using an env, then testfile should just be the db name.
36
# Otherwise it is the test directory and the name.
37
if { $eindex == -1 } {
38
set testfile $testdir/test0$tnum.db
41
set testfile test0$tnum.db
43
set env [lindex $args $eindex]
44
set txnenv [is_txnenv $env]
46
append args " -auto_commit "
48
set testdir [get_home $env]
55
puts -nonewline "Test0$tnum $omethod ($args): "
56
if { [is_record_based $method] || [is_rbtree $method] } {
57
puts "Skipping for method $method."
60
puts "cursor stability on duplicate pages."
62
set pgindex [lsearch -exact $args "-pagesize"]
63
if { $pgindex != -1 } {
64
puts "Test073: skipping for specific pagesizes"
68
append args " -pagesize $pagesize -dup"
70
set db [eval {berkdb_open \
71
-create -mode 0644} $omethod $args $testfile]
72
error_check_good "db open" [is_valid_db $db] TRUE
74
# Number of outstanding keys.
77
puts "\tTest0$tnum.a.1: Initializing put loop; $ndups dups, short data."
79
for { set i 0 } { $i < $ndups } { incr i } {
80
set datum [makedatum_t73 $i 0]
84
error_check_good txn [is_valid_txn $t $env] TRUE
87
set ret [eval {$db put} $txn {$key $datum}]
88
error_check_good "db put ($i)" $ret 0
90
error_check_good txn [$t commit] 0
97
puts "\tTest0$tnum.a.2: Initializing cursor get loop; $keys dups."
100
error_check_good txn [is_valid_txn $t $env] TRUE
103
for { set i 0 } { $i < $keys } { incr i } {
104
set datum [makedatum_t73 $i 0]
106
set dbc($i) [eval {$db cursor} $txn]
107
error_check_good "db cursor ($i)"\
108
[is_valid_cursor $dbc($i) $db] TRUE
109
error_check_good "dbc get -get_both ($i)"\
110
[$dbc($i) get -get_both $key $datum]\
111
[list [list $key $datum]]
114
puts "\tTest0$tnum.b: Cursor put (DB_KEYLAST); $ndups new dups,\
117
for { set i 0 } { $i < $ndups } { incr i } {
118
# !!! keys contains the number of the next dup
119
# to be added (since they start from zero)
121
set datum [makedatum_t73 $keys 0]
122
set curs [eval {$db cursor} $txn]
123
error_check_good "db cursor create" [is_valid_cursor $curs $db]\
125
error_check_good "c_put(DB_KEYLAST, $keys)"\
126
[$curs put -keylast $key $datum] 0
132
verify_t73 is_long dbc $keys $key
135
puts "\tTest0$tnum.c: Cursor put (DB_KEYFIRST); $ndups new dups,\
138
for { set i 0 } { $i < $ndups } { incr i } {
139
# !!! keys contains the number of the next dup
140
# to be added (since they start from zero)
142
set datum [makedatum_t73 $keys 0]
143
set curs [eval {$db cursor} $txn]
144
error_check_good "db cursor create" [is_valid_cursor $curs $db]\
146
error_check_good "c_put(DB_KEYFIRST, $keys)"\
147
[$curs put -keyfirst $key $datum] 0
153
verify_t73 is_long dbc $keys $key
156
puts "\tTest0$tnum.d: Cursor put (DB_AFTER) first to last;\
157
$keys new dups, short data"
158
# We want to add a datum after each key from 0 to the current
159
# value of $keys, which we thus need to save.
161
for { set i 0 } { $i < $keysnow } { incr i } {
162
set datum [makedatum_t73 $keys 0]
163
set curs [eval {$db cursor} $txn]
164
error_check_good "db cursor create" [is_valid_cursor $curs $db]\
167
# Which datum to insert this guy after.
168
set curdatum [makedatum_t73 $i 0]
169
error_check_good "c_get(DB_GET_BOTH, $i)"\
170
[$curs get -get_both $key $curdatum]\
171
[list [list $key $curdatum]]
172
error_check_good "c_put(DB_AFTER, $i)"\
173
[$curs put -after $datum] 0
179
verify_t73 is_long dbc $keys $key
182
puts "\tTest0$tnum.e: Cursor put (DB_BEFORE) last to first;\
183
$keys new dups, short data"
185
for { set i [expr $keys - 1] } { $i >= 0 } { incr i -1 } {
186
set datum [makedatum_t73 $keys 0]
187
set curs [eval {$db cursor} $txn]
188
error_check_good "db cursor create" [is_valid_cursor $curs $db]\
191
# Which datum to insert this guy before.
192
set curdatum [makedatum_t73 $i 0]
193
error_check_good "c_get(DB_GET_BOTH, $i)"\
194
[$curs get -get_both $key $curdatum]\
195
[list [list $key $curdatum]]
196
error_check_good "c_put(DB_BEFORE, $i)"\
197
[$curs put -before $datum] 0
203
if { $i % 10 == 1 } {
204
verify_t73 is_long dbc $keys $key
207
verify_t73 is_long dbc $keys $key
209
puts "\tTest0$tnum.f: Cursor put (DB_CURRENT), first to last,\
212
for { set i 0 } { $i < $keysnow } { incr i } {
213
set olddatum [makedatum_t73 $i 0]
214
set newdatum [makedatum_t73 $i 1]
215
set curs [eval {$db cursor} $txn]
216
error_check_good "db cursor create" [is_valid_cursor $curs $db]\
219
error_check_good "c_get(DB_GET_BOTH, $i)"\
220
[$curs get -get_both $key $olddatum]\
221
[list [list $key $olddatum]]
222
error_check_good "c_put(DB_CURRENT, $i)"\
223
[$curs put -current $newdatum] 0
225
error_check_good "cursor close" [$curs close] 0
229
if { $i % 10 == 1 } {
230
verify_t73 is_long dbc $keys $key
233
verify_t73 is_long dbc $keys $key
236
puts "\tTest0$tnum.g: Closing cursors."
237
for { set i 0 } { $i < $keys } { incr i } {
238
error_check_good "dbc close ($i)" [$dbc($i) close] 0
240
if { $txnenv == 1 } {
241
error_check_good txn [$t commit] 0
243
error_check_good "db close" [$db close] 0
246
# !!!: This procedure is also used by test087.
247
proc makedatum_t73 { num is_long } {
249
if { $is_long == 1 } {
250
set a $alphabet$alphabet$alphabet
255
# format won't do leading zeros, alas.
256
if { $num / 1000 > 0 } {
258
} elseif { $num / 100 > 0 } {
260
} elseif { $num / 10 > 0 } {
269
# !!!: This procedure is also used by test087.
270
proc verify_t73 { is_long_array curs_array numkeys key } {
271
upvar $is_long_array is_long
272
upvar $curs_array dbc
275
#useful for debugging, perhaps.
278
for { set j 0 } { $j < $numkeys } { incr j } {
279
set dbt [$dbc($j) get -current]
280
set k [lindex [lindex $dbt 0] 0]
281
set d [lindex [lindex $dbt 0] 1]
284
"cursor $j key correctness (with $numkeys total items)"\
287
"cursor $j data correctness (with $numkeys total items)"\
288
$d [makedatum_t73 $j $is_long($j)]