1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 1999-2009 Oracle. All rights reserved. 4# 5# $Id$ 6# 7# TEST test074 8# TEST Test of DB_NEXT_NODUP. 9proc test074 { method {dir -nextnodup} {nitems 100} {tnum "074"} args } { 10 source ./include.tcl 11 global alphabet 12 global is_je_test 13 global rand_init 14 15 set omethod [convert_method $method] 16 set args [convert_args $method $args] 17 18 berkdb srand $rand_init 19 20 # Data prefix--big enough that we get a mix of on-page, off-page, 21 # and multi-off-page dups with the default nitems 22 if { [is_fixed_length $method] == 1 } { 23 set globaldata "somedata" 24 } else { 25 set globaldata [repeat $alphabet 4] 26 } 27 28 puts "Test$tnum $omethod ($args): Test of $dir" 29 30 # First, test non-dup (and not-very-interesting) case with 31 # all db types. 32 33 puts "\tTest$tnum.a: No duplicates." 34 35 set txnenv 0 36 set eindex [lsearch -exact $args "-env"] 37 # 38 # If we are using an env, then testfile should just be the db name. 39 # Otherwise it is the test directory and the name. 40 if { $eindex == -1 } { 41 set testfile $testdir/test$tnum-nodup.db 42 set env NULL 43 } else { 44 set testfile test$tnum-nodup.db 45 incr eindex 46 set env [lindex $args $eindex] 47 set txnenv [is_txnenv $env] 48 if { $txnenv == 1 } { 49 append args " -auto_commit " 50 } 51 set testdir [get_home $env] 52 } 53 cleanup $testdir $env 54 set db [eval {berkdb_open -create -mode 0644} $omethod\ 55 $args {$testfile}] 56 error_check_good db_open [is_valid_db $db] TRUE 57 set txn "" 58 59 # Insert nitems items. 60 puts "\t\tTest$tnum.a.1: Put loop." 61 for {set i 1} {$i <= $nitems} {incr i} { 62 # 63 # If record based, set key to $i * 2 to leave 64 # holes/unused entries for further testing. 65 # 66 if {[is_record_based $method] == 1} { 67 set key [expr $i * 2] 68 } else { 69 set key "key$i" 70 } 71 set data "$globaldata$i" 72 if { $txnenv == 1 } { 73 set t [$env txn] 74 error_check_good txn [is_valid_txn $t $env] TRUE 75 set txn "-txn $t" 76 } 77 set ret [eval {$db put} $txn {$key \ 78 [chop_data $method $data]}] 79 error_check_good put($i) $ret 0 80 if { $txnenv == 1 } { 81 error_check_good txn [$t commit] 0 82 } 83 } 84 85 puts "\t\tTest$tnum.a.2: Get($dir)" 86 87 # foundarray($i) is set when key number i is found in the database 88 if { $txnenv == 1 } { 89 set t [$env txn] 90 error_check_good txn [is_valid_txn $t $env] TRUE 91 set txn "-txn $t" 92 } 93 set dbc [eval {$db cursor} $txn] 94 error_check_good db_cursor [is_valid_cursor $dbc $db] TRUE 95 96 # Initialize foundarray($i) to zero for all $i 97 for {set i 1} {$i < $nitems} {incr i} { 98 set foundarray($i) 0 99 } 100 101 # Walk database using $dir and record each key gotten. 102 for {set i 1} {$i <= $nitems} {incr i} { 103 set dbt [$dbc get $dir] 104 set key [lindex [lindex $dbt 0] 0] 105 if {[is_record_based $method] == 1} { 106 set num [expr $key / 2] 107 set desired_key $key 108 error_check_good $method:num $key [expr $num * 2] 109 } else { 110 set num [string range $key 3 end] 111 set desired_key key$num 112 } 113 114 error_check_good dbt_correct($i) $dbt\ 115 [list [list $desired_key\ 116 [pad_data $method $globaldata$num]]] 117 118 set foundarray($num) 1 119 } 120 121 puts "\t\tTest$tnum.a.3: Final key." 122 error_check_good last_db_get [$dbc get $dir] [list] 123 124 puts "\t\tTest$tnum.a.4: Verify loop." 125 for { set i 1 } { $i <= $nitems } { incr i } { 126 error_check_good found_key($i) $foundarray($i) 1 127 } 128 129 error_check_good dbc_close(nodup) [$dbc close] 0 130 if { $txnenv == 1 } { 131 error_check_good txn [$t commit] 0 132 } 133 134 # If we are a method that doesn't allow dups, verify that 135 # we get an empty list if we try to use DB_NEXT_DUP 136 if { [is_record_based $method] == 1 || [is_rbtree $method] == 1 } { 137 if { $txnenv == 1 } { 138 set t [$env txn] 139 error_check_good txn [is_valid_txn $t $env] TRUE 140 set txn "-txn $t" 141 } 142 puts "\t\tTest$tnum.a.5: Check DB_NEXT_DUP for $method." 143 set dbc [eval {$db cursor} $txn] 144 error_check_good db_cursor [is_valid_cursor $dbc $db] TRUE 145 146 set dbt [$dbc get $dir] 147 error_check_good $method:nextdup [$dbc get -nextdup] [list] 148 error_check_good dbc_close(nextdup) [$dbc close] 0 149 if { $txnenv == 1 } { 150 error_check_good txn [$t commit] 0 151 } 152 } 153 error_check_good db_close(nodup) [$db close] 0 154 155 # Quit here if we're a method that won't allow dups. 156 if { [is_record_based $method] == 1 || [is_rbtree $method] == 1 } { 157 puts "\tTest$tnum: Skipping remainder for method $method." 158 return 159 } 160 161 foreach opt { "-dup" "-dupsort" } { 162 if { $is_je_test || [is_compressed $args] } { 163 if { $opt == "-dup" } { 164 continue 165 } 166 } 167 168 # 169 # If we are using an env, then testfile should just be the 170 # db name. Otherwise it is the test directory and the name. 171 if { $eindex == -1 } { 172 set testfile $testdir/test$tnum$opt.db 173 } else { 174 set testfile test$tnum$opt.db 175 } 176 177 if { [string compare $opt "-dupsort"] == 0 } { 178 set opt "-dup -dupsort" 179 } 180 181 puts "\tTest$tnum.b: Duplicates ($opt)." 182 183 puts "\t\tTest$tnum.b.1 ($opt): Put loop." 184 set db [eval {berkdb_open -create -mode 0644}\ 185 $opt $omethod $args {$testfile}] 186 error_check_good db_open [is_valid_db $db] TRUE 187 188 # Insert nitems different keys such that key i has i dups. 189 for {set i 1} {$i <= $nitems} {incr i} { 190 set key key$i 191 192 for {set j 1} {$j <= $i} {incr j} { 193 if { $j < 10 } { 194 set data "${globaldata}00$j" 195 } elseif { $j < 100 } { 196 set data "${globaldata}0$j" 197 } else { 198 set data "$globaldata$j" 199 } 200 201 if { $txnenv == 1 } { 202 set t [$env txn] 203 error_check_good txn \ 204 [is_valid_txn $t $env] TRUE 205 set txn "-txn $t" 206 } 207 set ret [eval {$db put} $txn {$key $data}] 208 error_check_good put($i,$j) $ret 0 209 if { $txnenv == 1 } { 210 error_check_good txn [$t commit] 0 211 } 212 } 213 } 214 215 # Initialize foundarray($i) to 0 for all i. 216 unset foundarray 217 for { set i 1 } { $i <= $nitems } { incr i } { 218 set foundarray($i) 0 219 } 220 221 # Get loop--after each get, move forward a random increment 222 # within the duplicate set. 223 puts "\t\tTest$tnum.b.2 ($opt): Get loop." 224 set one "001" 225 if { $txnenv == 1 } { 226 set t [$env txn] 227 error_check_good txn [is_valid_txn $t $env] TRUE 228 set txn "-txn $t" 229 } 230 set dbc [eval {$db cursor} $txn] 231 error_check_good dbc($opt) [is_valid_cursor $dbc $db] TRUE 232 for { set i 1 } { $i <= $nitems } { incr i } { 233 set dbt [$dbc get $dir] 234 set key [lindex [lindex $dbt 0] 0] 235 set num [string range $key 3 end] 236 237 set desired_key key$num 238 if { [string compare $dir "-prevnodup"] == 0 } { 239 if { $num < 10 } { 240 set one "00$num" 241 } elseif { $num < 100 } { 242 set one "0$num" 243 } else { 244 set one $num 245 } 246 } 247 248 error_check_good dbt_correct($i) $dbt\ 249 [list [list $desired_key\ 250 "$globaldata$one"]] 251 252 set foundarray($num) 1 253 254 # Go forward by some number w/i dup set. 255 set inc [berkdb random_int 0 [expr $num - 1]] 256 for { set j 0 } { $j < $inc } { incr j } { 257 eval {$dbc get -nextdup} 258 } 259 } 260 261 puts "\t\tTest$tnum.b.3 ($opt): Final key." 262 error_check_good last_db_get($opt) [$dbc get $dir] [list] 263 264 # Verify 265 puts "\t\tTest$tnum.b.4 ($opt): Verify loop." 266 for { set i 1 } { $i <= $nitems } { incr i } { 267 error_check_good found_key($i) $foundarray($i) 1 268 } 269 270 error_check_good dbc_close [$dbc close] 0 271 if { $txnenv == 1 } { 272 error_check_good txn [$t commit] 0 273 } 274 error_check_good db_close [$db close] 0 275 } 276} 277