1# See the file LICENSE for redistribution information. 2# 3# Copyright (c) 2005-2009 Oracle. All rights reserved. 4# 5# $Id$ 6# 7# TEST test117 8# TEST Test database compaction with requested fill percent. 9# TEST 10# TEST Populate a database. Remove a high proportion of entries. 11# TEST Dump and save contents. Compact the database, requesting 12# TEST fill percentages starting at 10% and working our way up to 13# TEST 100. On each cycle, make sure we still have the same contents. 14# TEST 15# TEST Unlike the other compaction tests, this one does not 16# TEST use -freespace. 17 18proc test117 { method {nentries 10000} {tnum "117"} args } { 19 source ./include.tcl 20 21 # Compaction is an option for btree and recno databases only. 22 if { [is_hash $method] == 1 || [is_queue $method] == 1 } { 23 puts "Skipping test$tnum for method $method." 24 return 25 } 26 27 set args [convert_args $method $args] 28 set omethod [convert_method $method] 29 if { [is_partition_callback $args] == 1 } { 30 set nodump 1 31 } else { 32 set nodump 0 33 } 34 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 set txnenv 0 38 set eindex [lsearch -exact $args "-env"] 39 if { $eindex == -1 } { 40 set basename $testdir/test$tnum 41 set env NULL 42 } else { 43 set basename test$tnum 44 incr eindex 45 set env [lindex $args $eindex] 46 set rpcenv [is_rpcenv $env] 47 if { $rpcenv == 1 } { 48 puts "Test$tnum: skipping for RPC" 49 return 50 } 51 set txnenv [is_txnenv $env] 52 if { $txnenv == 1 } { 53 append args " -auto_commit " 54 } 55 set testdir [get_home $env] 56 } 57 puts "Test$tnum: ($method $args) Database compaction and fillpercent." 58 set t1 $testdir/t1 59 set t2 $testdir/t2 60 set splitopts { "" "-revsplitoff" } 61 set txn "" 62 63 if { [is_record_based $method] == 1 } { 64 set checkfunc test001_recno.check 65 } else { 66 set checkfunc test001.check 67 } 68 69 foreach splitopt $splitopts { 70 set testfile $basename.db 71 if { $splitopt == "-revsplitoff" } { 72 set testfile $basename.rev.db 73 if { [is_record_based $method] == 1 } { 74 puts "Skipping\ 75 -revsplitoff option for method $method." 76 continue 77 } 78 } 79 set did [open $dict] 80 if { $env != "NULL" } { 81 set testdir [get_home $env] 82 } 83 cleanup $testdir $env 84 85 puts "\tTest$tnum.a: Create and populate database ($splitopt)." 86 set db [eval {berkdb_open -create \ 87 -mode 0644} $splitopt $args $omethod $testfile] 88 error_check_good dbopen [is_valid_db $db] TRUE 89 90 set count 0 91 if { $txnenv == 1 } { 92 set t [$env txn] 93 error_check_good txn [is_valid_txn $t $env] TRUE 94 set txn "-txn $t" 95 } 96 while { [gets $did str] != -1 && $count < $nentries } { 97 global kvals 98 99 if { [is_record_based $method] == 1 } { 100 set key [expr $count + 1] 101 set kvals($key) [pad_data $method $str] 102 } else { 103 set key $str 104 set str [reverse $str] 105 } 106 107 set ret [eval \ 108 {$db put} $txn {$key [chop_data $method $str]}] 109 error_check_good put $ret 0 110 incr count 111 112 } 113 if { $txnenv == 1 } { 114 error_check_good txn_commit [$t commit] 0 115 } 116 close $did 117 error_check_good db_sync [$db sync] 0 118 119 if { $env != "NULL" } { 120 set testdir [get_home $env] 121 set filename $testdir/$testfile 122 } else { 123 set filename $testfile 124 } 125 set size1 [file size $filename] 126 set free1 [stat_field $db stat "Pages on freelist"] 127 128 puts "\tTest$tnum.b: Delete most entries from database." 129 set did [open $dict] 130 set count [expr $nentries - 1] 131 set n 17 132 133 # Leave every nth item. Since rrecno renumbers, we 134 # delete starting at nentries and working down to 0. 135 if { $txnenv == 1 } { 136 set t [$env txn] 137 error_check_good txn [is_valid_txn $t $env] TRUE 138 set txn "-txn $t" 139 } 140 while { [gets $did str] != -1 && $count > 0 } { 141 if { [is_record_based $method] == 1 } { 142 set key [expr $count + 1] 143 } else { 144 set key $str 145 } 146 147 if { [expr $count % $n] != 0 } { 148 set ret [eval {$db del} $txn {$key}] 149 error_check_good del $ret 0 150 } 151 incr count -1 152 } 153 if { $txnenv == 1 } { 154 error_check_good t_commit [$t commit] 0 155 } 156 error_check_good db_sync [$db sync] 0 157 158 puts "\tTest$tnum.c: Do a dump_file on contents." 159 if { $txnenv == 1 } { 160 set t [$env txn] 161 error_check_good txn [is_valid_txn $t $env] TRUE 162 set txn "-txn $t" 163 } 164 dump_file $db $txn $t1 165 if { $txnenv == 1 } { 166 error_check_good txn_commit [$t commit] 0 167 } 168 169 # Start by compacting pages filled less than 10% and 170 # work up to 100%. 171 for { set fillpercent 10 } { $fillpercent <= 100 }\ 172 { incr fillpercent 10 } { 173 174 puts "\tTest$tnum.d: Compact and verify database\ 175 with fillpercent $fillpercent." 176 set ret [$db compact -fillpercent $fillpercent] 177 error_check_good db_sync [$db sync] 0 178 set size2 [file size $filename] 179 error_check_good verify_dir \ 180 [verify_dir $testdir "" 0 0 $nodump] 0 181 set free2 [stat_field $db stat "Pages on freelist"] 182 183 # The number of free pages should never decline. 184 error_check_good pages_freed [expr $free2 >= $free1] 1 185 error_check_good file_size [expr $size2 <= $size1] 1 186 187 puts "\tTest$tnum.e:\ 188 Contents are the same after compaction." 189 if { $txnenv == 1 } { 190 set t [$env txn] 191 error_check_good txn [is_valid_txn $t $env] TRUE 192 set txn "-txn $t" 193 } 194 dump_file $db $txn $t2 195 if { $txnenv == 1 } { 196 error_check_good txn_commit [$t commit] 0 197 } 198 error_check_good filecmp [filecmp $t1 $t2] 0 199 set free1 $free2 200 set size1 $size2 201 } 202 error_check_good db_close [$db close] 0 203 close $did 204 } 205} 206