1*1da57d55SToomas Soome#
27c478bd9Sstevel@tonic-gate# 2001 September 15
37c478bd9Sstevel@tonic-gate#
47c478bd9Sstevel@tonic-gate# The author disclaims copyright to this source code.  In place of
57c478bd9Sstevel@tonic-gate# a legal notice, here is a blessing:
67c478bd9Sstevel@tonic-gate#
77c478bd9Sstevel@tonic-gate#    May you do good and not evil.
87c478bd9Sstevel@tonic-gate#    May you find forgiveness for yourself and forgive others.
97c478bd9Sstevel@tonic-gate#    May you share freely, never taking more than you give.
107c478bd9Sstevel@tonic-gate#
117c478bd9Sstevel@tonic-gate#***********************************************************************
127c478bd9Sstevel@tonic-gate# This file implements regression tests for SQLite library.  The
137c478bd9Sstevel@tonic-gate# focus of this script is btree database backend
147c478bd9Sstevel@tonic-gate#
157c478bd9Sstevel@tonic-gate# $Id: btree2.test,v 1.10 2002/02/19 13:39:23 drh Exp $
167c478bd9Sstevel@tonic-gate
177c478bd9Sstevel@tonic-gate
187c478bd9Sstevel@tonic-gateset testdir [file dirname $argv0]
197c478bd9Sstevel@tonic-gatesource $testdir/tester.tcl
207c478bd9Sstevel@tonic-gate
217c478bd9Sstevel@tonic-gateif {[info commands btree_open]!=""} {
227c478bd9Sstevel@tonic-gate
237c478bd9Sstevel@tonic-gate# Create a new database file containing no entries.  The database should
247c478bd9Sstevel@tonic-gate# contain 5 tables:
257c478bd9Sstevel@tonic-gate#
267c478bd9Sstevel@tonic-gate#     2   The descriptor table
277c478bd9Sstevel@tonic-gate#     3   The foreground table
287c478bd9Sstevel@tonic-gate#     4   The background table
297c478bd9Sstevel@tonic-gate#     5   The long key table
307c478bd9Sstevel@tonic-gate#     6   The long data table
317c478bd9Sstevel@tonic-gate#
327c478bd9Sstevel@tonic-gate# An explanation for what all these tables are used for is provided below.
337c478bd9Sstevel@tonic-gate#
347c478bd9Sstevel@tonic-gatedo_test btree2-1.1 {
357c478bd9Sstevel@tonic-gate  expr srand(1)
367c478bd9Sstevel@tonic-gate  file delete -force test2.bt
377c478bd9Sstevel@tonic-gate  file delete -force test2.bt-journal
387c478bd9Sstevel@tonic-gate  set ::b [btree_open test2.bt]
397c478bd9Sstevel@tonic-gate  btree_begin_transaction $::b
407c478bd9Sstevel@tonic-gate  btree_create_table $::b
417c478bd9Sstevel@tonic-gate} {3}
427c478bd9Sstevel@tonic-gatedo_test btree2-1.2 {
437c478bd9Sstevel@tonic-gate  btree_create_table $::b
447c478bd9Sstevel@tonic-gate} {4}
457c478bd9Sstevel@tonic-gatedo_test btree2-1.3 {
467c478bd9Sstevel@tonic-gate  btree_create_table $::b
477c478bd9Sstevel@tonic-gate} {5}
487c478bd9Sstevel@tonic-gatedo_test btree2-1.4 {
497c478bd9Sstevel@tonic-gate  btree_create_table $::b
507c478bd9Sstevel@tonic-gate} {6}
517c478bd9Sstevel@tonic-gatedo_test btree2-1.5 {
527c478bd9Sstevel@tonic-gate  set ::c2 [btree_cursor $::b 2 1]
537c478bd9Sstevel@tonic-gate  btree_insert $::c2 {one} {1}
547c478bd9Sstevel@tonic-gate  btree_delete $::c2
557c478bd9Sstevel@tonic-gate  btree_close_cursor $::c2
567c478bd9Sstevel@tonic-gate  btree_commit $::b
577c478bd9Sstevel@tonic-gate  btree_integrity_check $::b 2 3 4 5 6
587c478bd9Sstevel@tonic-gate} {}
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate# This test module works by making lots of pseudo-random changes to a
617c478bd9Sstevel@tonic-gate# database while simultaneously maintaining an invariant on that database.
627c478bd9Sstevel@tonic-gate# Periodically, the script does a sanity check on the database and verifies
637c478bd9Sstevel@tonic-gate# that the invariant is satisfied.
647c478bd9Sstevel@tonic-gate#
657c478bd9Sstevel@tonic-gate# The invariant is as follows:
667c478bd9Sstevel@tonic-gate#
677c478bd9Sstevel@tonic-gate#   1.  The descriptor table always contains 2 enters.  An entry keyed by
687c478bd9Sstevel@tonic-gate#       "N" is the number of elements in the foreground and background tables
697c478bd9Sstevel@tonic-gate#       combined.  The entry keyed by "L" is the number of digits in the keys
707c478bd9Sstevel@tonic-gate#       for foreground and background tables.
717c478bd9Sstevel@tonic-gate#
727c478bd9Sstevel@tonic-gate#   2.  The union of the foreground an background tables consists of N entries
73*1da57d55SToomas Soome#       where each entry an L-digit key.  (Actually, some keys can be longer
747c478bd9Sstevel@tonic-gate#       than L characters, but they always start with L digits.)  The keys
757c478bd9Sstevel@tonic-gate#       cover all integers between 1 and N.  Whenever an entry is added to
767c478bd9Sstevel@tonic-gate#       the foreground it is removed form the background and vice versa.
777c478bd9Sstevel@tonic-gate#
787c478bd9Sstevel@tonic-gate#   3.  Some entries in the foreground and background tables have keys that
797c478bd9Sstevel@tonic-gate#       begin with an L-digit number but are followed by additional characters.
807c478bd9Sstevel@tonic-gate#       For each such entry there is a corresponding entry in the long key
817c478bd9Sstevel@tonic-gate#       table.  The long key table entry has a key which is just the L-digit
827c478bd9Sstevel@tonic-gate#       number and data which is the length of the key in the foreground and
837c478bd9Sstevel@tonic-gate#       background tables.
847c478bd9Sstevel@tonic-gate#
857c478bd9Sstevel@tonic-gate#   4.  The data for both foreground and background entries is usually a
867c478bd9Sstevel@tonic-gate#       short string.  But some entries have long data strings.  For each
877c478bd9Sstevel@tonic-gate#       such entries there is an entry in the long data type.  The key to
887c478bd9Sstevel@tonic-gate#       long data table is an L-digit number.  (The extension on long keys
897c478bd9Sstevel@tonic-gate#       is omitted.)  The data is the number of charaters in the data of the
907c478bd9Sstevel@tonic-gate#       foreground or background entry.
917c478bd9Sstevel@tonic-gate#
927c478bd9Sstevel@tonic-gate# The following function builds a database that satisfies all of the above
937c478bd9Sstevel@tonic-gate# invariants.
947c478bd9Sstevel@tonic-gate#
957c478bd9Sstevel@tonic-gateproc build_db {N L} {
967c478bd9Sstevel@tonic-gate  for {set i 2} {$i<=6} {incr i} {
977c478bd9Sstevel@tonic-gate    catch {btree_close_cursor [set ::c$i]}
987c478bd9Sstevel@tonic-gate    btree_clear_table $::b $i
997c478bd9Sstevel@tonic-gate    set ::c$i [btree_cursor $::b $i 1]
1007c478bd9Sstevel@tonic-gate  }
1017c478bd9Sstevel@tonic-gate  btree_insert $::c2 N $N
1027c478bd9Sstevel@tonic-gate  btree_insert $::c2 L $L
1037c478bd9Sstevel@tonic-gate  set format %0${L}d
104*1da57d55SToomas Soome  for {set i 1} {$i<=$N} {incr i} {
1057c478bd9Sstevel@tonic-gate    set key [format $format $i]
1067c478bd9Sstevel@tonic-gate    set data $key
1077c478bd9Sstevel@tonic-gate    btree_insert $::c3 $key $data
1087c478bd9Sstevel@tonic-gate  }
1097c478bd9Sstevel@tonic-gate}
1107c478bd9Sstevel@tonic-gate
1117c478bd9Sstevel@tonic-gate# Given a base key number and a length, construct the full text of the key
1127c478bd9Sstevel@tonic-gate# or data.
1137c478bd9Sstevel@tonic-gate#
1147c478bd9Sstevel@tonic-gateproc make_payload {keynum L len} {
1157c478bd9Sstevel@tonic-gate  set key [format %0${L}d $keynum]
1167c478bd9Sstevel@tonic-gate  set r $key
1177c478bd9Sstevel@tonic-gate  set i 1
1187c478bd9Sstevel@tonic-gate  while {[string length $r]<$len} {
1197c478bd9Sstevel@tonic-gate    append r " ($i) $key"
1207c478bd9Sstevel@tonic-gate    incr i
1217c478bd9Sstevel@tonic-gate  }
1227c478bd9Sstevel@tonic-gate  return [string range $r 0 [expr {$len-1}]]
1237c478bd9Sstevel@tonic-gate}
1247c478bd9Sstevel@tonic-gate
125*1da57d55SToomas Soome# Verify the invariants on the database.  Return an empty string on
1267c478bd9Sstevel@tonic-gate# success or an error message if something is amiss.
1277c478bd9Sstevel@tonic-gate#
1287c478bd9Sstevel@tonic-gateproc check_invariants {} {
1297c478bd9Sstevel@tonic-gate  set ck [btree_integrity_check $::b 2 3 4 5 6]
1307c478bd9Sstevel@tonic-gate  if {$ck!=""} {
1317c478bd9Sstevel@tonic-gate    puts "\n*** SANITY:\n$ck"
1327c478bd9Sstevel@tonic-gate    exit
1337c478bd9Sstevel@tonic-gate    return $ck
1347c478bd9Sstevel@tonic-gate  }
1357c478bd9Sstevel@tonic-gate  btree_move_to $::c3 {}
1367c478bd9Sstevel@tonic-gate  btree_move_to $::c4 {}
1377c478bd9Sstevel@tonic-gate  btree_move_to $::c2 N
1387c478bd9Sstevel@tonic-gate  set N [btree_data $::c2]
1397c478bd9Sstevel@tonic-gate  btree_move_to $::c2 L
1407c478bd9Sstevel@tonic-gate  set L [btree_data $::c2]
1417c478bd9Sstevel@tonic-gate  set LM1 [expr {$L-1}]
1427c478bd9Sstevel@tonic-gate  for {set i 1} {$i<=$N} {incr i} {
1437c478bd9Sstevel@tonic-gate    set key [btree_key $::c3]
1447c478bd9Sstevel@tonic-gate    if {[scan $key %d k]<1} {set k 0}
1457c478bd9Sstevel@tonic-gate    if {$k!=$i} {
1467c478bd9Sstevel@tonic-gate      set key [btree_key $::c4]
1477c478bd9Sstevel@tonic-gate      if {[scan $key %d k]<1} {set k 0}
1487c478bd9Sstevel@tonic-gate      if {$k!=$i} {
1497c478bd9Sstevel@tonic-gate        # puts "MISSING $i"
1507c478bd9Sstevel@tonic-gate        # puts {Page 3:}; btree_page_dump $::b 3
1517c478bd9Sstevel@tonic-gate        # puts {Page 4:}; btree_page_dump $::b 4
1527c478bd9Sstevel@tonic-gate        # exit
1537c478bd9Sstevel@tonic-gate        return "Key $i is missing from both foreground and background"
1547c478bd9Sstevel@tonic-gate      }
1557c478bd9Sstevel@tonic-gate      set data [btree_data $::c4]
1567c478bd9Sstevel@tonic-gate      btree_next $::c4
1577c478bd9Sstevel@tonic-gate    } else {
1587c478bd9Sstevel@tonic-gate      set data [btree_data $::c3]
1597c478bd9Sstevel@tonic-gate      btree_next $::c3
1607c478bd9Sstevel@tonic-gate    }
1617c478bd9Sstevel@tonic-gate    set skey [string range $key 0 $LM1]
1627c478bd9Sstevel@tonic-gate    if {[btree_move_to $::c5 $skey]==0} {
1637c478bd9Sstevel@tonic-gate      set keylen [btree_data $::c5]
1647c478bd9Sstevel@tonic-gate    } else {
1657c478bd9Sstevel@tonic-gate      set keylen $L
1667c478bd9Sstevel@tonic-gate    }
1677c478bd9Sstevel@tonic-gate    if {[string length $key]!=$keylen} {
1687c478bd9Sstevel@tonic-gate      return "Key $i is the wrong size.\
1697c478bd9Sstevel@tonic-gate              Is \"$key\" but should be \"[make_payload $k $L $keylen]\""
1707c478bd9Sstevel@tonic-gate    }
1717c478bd9Sstevel@tonic-gate    if {[make_payload $k $L $keylen]!=$key} {
1727c478bd9Sstevel@tonic-gate      return "Key $i has an invalid extension"
1737c478bd9Sstevel@tonic-gate    }
1747c478bd9Sstevel@tonic-gate    if {[btree_move_to $::c6 $skey]==0} {
1757c478bd9Sstevel@tonic-gate      set datalen [btree_data $::c6]
1767c478bd9Sstevel@tonic-gate    } else {
1777c478bd9Sstevel@tonic-gate      set datalen $L
1787c478bd9Sstevel@tonic-gate    }
1797c478bd9Sstevel@tonic-gate    if {[string length $data]!=$datalen} {
1807c478bd9Sstevel@tonic-gate      return "Data for $i is the wrong size.\
1817c478bd9Sstevel@tonic-gate              Is [string length $data] but should be $datalen"
1827c478bd9Sstevel@tonic-gate    }
1837c478bd9Sstevel@tonic-gate    if {[make_payload $k $L $datalen]!=$data} {
1847c478bd9Sstevel@tonic-gate      return "Entry $i has an incorrect data"
1857c478bd9Sstevel@tonic-gate    }
1867c478bd9Sstevel@tonic-gate  }
1877c478bd9Sstevel@tonic-gate}
1887c478bd9Sstevel@tonic-gate
1897c478bd9Sstevel@tonic-gate# Make random changes to the database such that each change preserves
1907c478bd9Sstevel@tonic-gate# the invariants.  The number of changes is $n*N where N is the parameter
1917c478bd9Sstevel@tonic-gate# from the descriptor table.  Each changes begins with a random key.
1927c478bd9Sstevel@tonic-gate# the entry with that key is put in the foreground table with probability
1937c478bd9Sstevel@tonic-gate# $I and it is put in background with probability (1.0-$I).  It gets
194*1da57d55SToomas Soome# a long key with probability $K and long data with probability $D.
195*1da57d55SToomas Soome#
1967c478bd9Sstevel@tonic-gateset chngcnt 0
1977c478bd9Sstevel@tonic-gateproc random_changes {n I K D} {
1987c478bd9Sstevel@tonic-gate  btree_move_to $::c2 N
1997c478bd9Sstevel@tonic-gate  set N [btree_data $::c2]
2007c478bd9Sstevel@tonic-gate  btree_move_to $::c2 L
2017c478bd9Sstevel@tonic-gate  set L [btree_data $::c2]
2027c478bd9Sstevel@tonic-gate  set LM1 [expr {$L-1}]
2037c478bd9Sstevel@tonic-gate  set total [expr {int($N*$n)}]
2047c478bd9Sstevel@tonic-gate  set format %0${L}d
2057c478bd9Sstevel@tonic-gate  for {set i 0} {$i<$total} {incr i} {
2067c478bd9Sstevel@tonic-gate    set k [expr {int(rand()*$N)+1}]
2077c478bd9Sstevel@tonic-gate    set insert [expr {rand()<=$I}]
2087c478bd9Sstevel@tonic-gate    set longkey [expr {rand()<=$K}]
2097c478bd9Sstevel@tonic-gate    set longdata [expr {rand()<=$D}]
2107c478bd9Sstevel@tonic-gate    # incr ::chngcnt
211*1da57d55SToomas Soome    # if {$::chngcnt==251} {btree_tree_dump $::b 3}
2127c478bd9Sstevel@tonic-gate    # puts "CHANGE $::chngcnt: $k $insert $longkey $longdata"
2137c478bd9Sstevel@tonic-gate    if {$longkey} {
2147c478bd9Sstevel@tonic-gate      set x [expr {rand()}]
2157c478bd9Sstevel@tonic-gate      set keylen [expr {int($x*$x*$x*$x*3000)+10}]
2167c478bd9Sstevel@tonic-gate    } else {
2177c478bd9Sstevel@tonic-gate      set keylen $L
2187c478bd9Sstevel@tonic-gate    }
2197c478bd9Sstevel@tonic-gate    set key [make_payload $k $L $keylen]
2207c478bd9Sstevel@tonic-gate    if {$longdata} {
2217c478bd9Sstevel@tonic-gate      set x [expr {rand()}]
2227c478bd9Sstevel@tonic-gate      set datalen [expr {int($x*$x*$x*$x*3000)+10}]
2237c478bd9Sstevel@tonic-gate    } else {
2247c478bd9Sstevel@tonic-gate      set datalen $L
2257c478bd9Sstevel@tonic-gate    }
2267c478bd9Sstevel@tonic-gate    set data [make_payload $k $L $datalen]
2277c478bd9Sstevel@tonic-gate    set basekey [format $format $k]
2287c478bd9Sstevel@tonic-gate    if {[set c [btree_move_to $::c3 $basekey]]==0} {
2297c478bd9Sstevel@tonic-gate      btree_delete $::c3
2307c478bd9Sstevel@tonic-gate    } else {
2317c478bd9Sstevel@tonic-gate      if {$c<0} {btree_next $::c3}
2327c478bd9Sstevel@tonic-gate      if {[string match $basekey* [btree_key $::c3]]} {
2337c478bd9Sstevel@tonic-gate        btree_delete $::c3
2347c478bd9Sstevel@tonic-gate      }
2357c478bd9Sstevel@tonic-gate    }
2367c478bd9Sstevel@tonic-gate    if {[set c [btree_move_to $::c4 $basekey]]==0} {
2377c478bd9Sstevel@tonic-gate      btree_delete $::c4
2387c478bd9Sstevel@tonic-gate    } else {
2397c478bd9Sstevel@tonic-gate      if {$c<0} {btree_next $::c4}
2407c478bd9Sstevel@tonic-gate      if {[string match $basekey* [btree_key $::c4]]} {
2417c478bd9Sstevel@tonic-gate        btree_delete $::c4
2427c478bd9Sstevel@tonic-gate      }
2437c478bd9Sstevel@tonic-gate    }
2447c478bd9Sstevel@tonic-gate    if {[scan [btree_key $::c4] %d kx]<1} {set kx -1}
2457c478bd9Sstevel@tonic-gate    if {$kx==$k} {
2467c478bd9Sstevel@tonic-gate      btree_delete $::c4
2477c478bd9Sstevel@tonic-gate    }
2487c478bd9Sstevel@tonic-gate    if {$insert} {
2497c478bd9Sstevel@tonic-gate      btree_insert $::c3 $key $data
2507c478bd9Sstevel@tonic-gate    } else {
2517c478bd9Sstevel@tonic-gate      btree_insert $::c4 $key $data
2527c478bd9Sstevel@tonic-gate    }
2537c478bd9Sstevel@tonic-gate    if {$longkey} {
2547c478bd9Sstevel@tonic-gate      btree_insert $::c5 $basekey $keylen
2557c478bd9Sstevel@tonic-gate    } elseif {[btree_move_to $::c5 $basekey]==0} {
2567c478bd9Sstevel@tonic-gate      btree_delete $::c5
2577c478bd9Sstevel@tonic-gate    }
2587c478bd9Sstevel@tonic-gate    if {$longdata} {
2597c478bd9Sstevel@tonic-gate      btree_insert $::c6 $basekey $datalen
2607c478bd9Sstevel@tonic-gate    } elseif {[btree_move_to $::c6 $basekey]==0} {
2617c478bd9Sstevel@tonic-gate      btree_delete $::c6
2627c478bd9Sstevel@tonic-gate    }
2637c478bd9Sstevel@tonic-gate    # set ck [btree_integrity_check $::b 2 3 4 5 6]
2647c478bd9Sstevel@tonic-gate    # if {$ck!=""} {
2657c478bd9Sstevel@tonic-gate    #   puts "\nSANITY CHECK FAILED!\n$ck"
2667c478bd9Sstevel@tonic-gate    #   exit
2677c478bd9Sstevel@tonic-gate    # }
2687c478bd9Sstevel@tonic-gate    # puts "PAGE 3:"; btree_page_dump $::b 3
2697c478bd9Sstevel@tonic-gate    # puts "PAGE 4:"; btree_page_dump $::b 4
2707c478bd9Sstevel@tonic-gate  }
2717c478bd9Sstevel@tonic-gate}
2727c478bd9Sstevel@tonic-gate
2737c478bd9Sstevel@tonic-gate# Repeat this test sequence on database of various sizes
2747c478bd9Sstevel@tonic-gate#
2757c478bd9Sstevel@tonic-gateset testno 2
2767c478bd9Sstevel@tonic-gateforeach {N L} {
2777c478bd9Sstevel@tonic-gate  10 2
2787c478bd9Sstevel@tonic-gate  50 2
2797c478bd9Sstevel@tonic-gate  200 3
2807c478bd9Sstevel@tonic-gate  2000 5
2817c478bd9Sstevel@tonic-gate} {
2827c478bd9Sstevel@tonic-gate  puts "**** N=$N L=$L ****"
2837c478bd9Sstevel@tonic-gate  set hash [md5file test2.bt]
2847c478bd9Sstevel@tonic-gate  do_test btree2-$testno.1 [subst -nocommands {
2857c478bd9Sstevel@tonic-gate    set ::c2 [btree_cursor $::b 2 1]
2867c478bd9Sstevel@tonic-gate    set ::c3 [btree_cursor $::b 3 1]
2877c478bd9Sstevel@tonic-gate    set ::c4 [btree_cursor $::b 4 1]
2887c478bd9Sstevel@tonic-gate    set ::c5 [btree_cursor $::b 5 1]
2897c478bd9Sstevel@tonic-gate    set ::c6 [btree_cursor $::b 6 1]
2907c478bd9Sstevel@tonic-gate    btree_begin_transaction $::b
2917c478bd9Sstevel@tonic-gate    build_db $N $L
2927c478bd9Sstevel@tonic-gate    check_invariants
2937c478bd9Sstevel@tonic-gate  }] {}
2947c478bd9Sstevel@tonic-gate  do_test btree2-$testno.2 {
2957c478bd9Sstevel@tonic-gate    btree_close_cursor $::c2
2967c478bd9Sstevel@tonic-gate    btree_close_cursor $::c3
2977c478bd9Sstevel@tonic-gate    btree_close_cursor $::c4
2987c478bd9Sstevel@tonic-gate    btree_close_cursor $::c5
2997c478bd9Sstevel@tonic-gate    btree_close_cursor $::c6
3007c478bd9Sstevel@tonic-gate    btree_rollback $::b
3017c478bd9Sstevel@tonic-gate    md5file test2.bt
3027c478bd9Sstevel@tonic-gate  } $hash
3037c478bd9Sstevel@tonic-gate  do_test btree2-$testno.3 [subst -nocommands {
3047c478bd9Sstevel@tonic-gate    btree_begin_transaction $::b
3057c478bd9Sstevel@tonic-gate    set ::c2 [btree_cursor $::b 2 1]
3067c478bd9Sstevel@tonic-gate    set ::c3 [btree_cursor $::b 3 1]
3077c478bd9Sstevel@tonic-gate    set ::c4 [btree_cursor $::b 4 1]
3087c478bd9Sstevel@tonic-gate    set ::c5 [btree_cursor $::b 5 1]
3097c478bd9Sstevel@tonic-gate    set ::c6 [btree_cursor $::b 6 1]
3107c478bd9Sstevel@tonic-gate    build_db $N $L
3117c478bd9Sstevel@tonic-gate    check_invariants
3127c478bd9Sstevel@tonic-gate  }] {}
3137c478bd9Sstevel@tonic-gate  do_test btree2-$testno.4 {
3147c478bd9Sstevel@tonic-gate    btree_commit $::b
3157c478bd9Sstevel@tonic-gate    check_invariants
3167c478bd9Sstevel@tonic-gate  } {}
3177c478bd9Sstevel@tonic-gate  do_test btree2-$testno.5  {
3187c478bd9Sstevel@tonic-gate    lindex [btree_pager_stats $::b] 1
3197c478bd9Sstevel@tonic-gate  } {6}
3207c478bd9Sstevel@tonic-gate  do_test btree2-$testno.6  {
3217c478bd9Sstevel@tonic-gate    btree_close_cursor $::c2
3227c478bd9Sstevel@tonic-gate    btree_close_cursor $::c3
3237c478bd9Sstevel@tonic-gate    btree_close_cursor $::c4
3247c478bd9Sstevel@tonic-gate    btree_close_cursor $::c5
3257c478bd9Sstevel@tonic-gate    btree_close_cursor $::c6
3267c478bd9Sstevel@tonic-gate    lindex [btree_pager_stats $::b] 1
3277c478bd9Sstevel@tonic-gate  } {0}
3287c478bd9Sstevel@tonic-gate  do_test btree2-$testno.7 {
3297c478bd9Sstevel@tonic-gate    btree_close $::b
3307c478bd9Sstevel@tonic-gate  } {}
3317c478bd9Sstevel@tonic-gateafter 100
3327c478bd9Sstevel@tonic-gate  # For each database size, run various changes tests.
3337c478bd9Sstevel@tonic-gate  #
3347c478bd9Sstevel@tonic-gate  set num2 1
3357c478bd9Sstevel@tonic-gate  foreach {n I K D} {
3367c478bd9Sstevel@tonic-gate    0.5 0.5 0.1 0.1
3377c478bd9Sstevel@tonic-gate    1.0 0.2 0.1 0.1
3387c478bd9Sstevel@tonic-gate    1.0 0.8 0.1 0.1
3397c478bd9Sstevel@tonic-gate    2.0 0.0 0.1 0.1
3407c478bd9Sstevel@tonic-gate    2.0 1.0 0.1 0.1
3417c478bd9Sstevel@tonic-gate    2.0 0.0 0.0 0.0
3427c478bd9Sstevel@tonic-gate    2.0 1.0 0.0 0.0
3437c478bd9Sstevel@tonic-gate  } {
3447c478bd9Sstevel@tonic-gate    set testid btree2-$testno.8.$num2
3457c478bd9Sstevel@tonic-gate    set hash [md5file test2.bt]
3467c478bd9Sstevel@tonic-gate    do_test $testid.0 {
3477c478bd9Sstevel@tonic-gate      set ::b [btree_open test2.bt]
3487c478bd9Sstevel@tonic-gate      set ::c2 [btree_cursor $::b 2 1]
3497c478bd9Sstevel@tonic-gate      set ::c3 [btree_cursor $::b 3 1]
3507c478bd9Sstevel@tonic-gate      set ::c4 [btree_cursor $::b 4 1]
3517c478bd9Sstevel@tonic-gate      set ::c5 [btree_cursor $::b 5 1]
3527c478bd9Sstevel@tonic-gate      set ::c6 [btree_cursor $::b 6 1]
3537c478bd9Sstevel@tonic-gate      check_invariants
3547c478bd9Sstevel@tonic-gate    } {}
3557c478bd9Sstevel@tonic-gate    set cnt 6
3567c478bd9Sstevel@tonic-gate    for {set i 2} {$i<=6} {incr i} {
3577c478bd9Sstevel@tonic-gate      if {[lindex [btree_cursor_dump [set ::c$i]] 0]!=$i} {incr cnt}
3587c478bd9Sstevel@tonic-gate    }
3597c478bd9Sstevel@tonic-gate    do_test $testid.1 {
3607c478bd9Sstevel@tonic-gate      btree_begin_transaction $::b
3617c478bd9Sstevel@tonic-gate      lindex [btree_pager_stats $::b] 1
3627c478bd9Sstevel@tonic-gate    } $cnt
3637c478bd9Sstevel@tonic-gate    # exec cp test2.bt test2.bt.bu1
3647c478bd9Sstevel@tonic-gate    do_test $testid.2 [subst {
3657c478bd9Sstevel@tonic-gate      random_changes $n $I $K $D
3667c478bd9Sstevel@tonic-gate    }] {}
3677c478bd9Sstevel@tonic-gate    do_test $testid.3 {
3687c478bd9Sstevel@tonic-gate      check_invariants
3697c478bd9Sstevel@tonic-gate    } {}
3707c478bd9Sstevel@tonic-gate    do_test $testid.4 {
3717c478bd9Sstevel@tonic-gate      btree_close_cursor $::c2
3727c478bd9Sstevel@tonic-gate      btree_close_cursor $::c3
3737c478bd9Sstevel@tonic-gate      btree_close_cursor $::c4
3747c478bd9Sstevel@tonic-gate      btree_close_cursor $::c5
3757c478bd9Sstevel@tonic-gate      btree_close_cursor $::c6
3767c478bd9Sstevel@tonic-gate      btree_rollback $::b
3777c478bd9Sstevel@tonic-gate      md5file test2.bt
3787c478bd9Sstevel@tonic-gate    } $hash
3797c478bd9Sstevel@tonic-gate    # exec cp test2.bt test2.bt.bu2
3807c478bd9Sstevel@tonic-gate    btree_begin_transaction $::b
3817c478bd9Sstevel@tonic-gate    set ::c2 [btree_cursor $::b 2 1]
3827c478bd9Sstevel@tonic-gate    set ::c3 [btree_cursor $::b 3 1]
3837c478bd9Sstevel@tonic-gate    set ::c4 [btree_cursor $::b 4 1]
3847c478bd9Sstevel@tonic-gate    set ::c5 [btree_cursor $::b 5 1]
3857c478bd9Sstevel@tonic-gate    set ::c6 [btree_cursor $::b 6 1]
3867c478bd9Sstevel@tonic-gate    do_test $testid.5 [subst {
3877c478bd9Sstevel@tonic-gate      random_changes $n $I $K $D
3887c478bd9Sstevel@tonic-gate    }] {}
3897c478bd9Sstevel@tonic-gate    do_test $testid.6 {
3907c478bd9Sstevel@tonic-gate      check_invariants
3917c478bd9Sstevel@tonic-gate    } {}
3927c478bd9Sstevel@tonic-gate    do_test $testid.7 {
3937c478bd9Sstevel@tonic-gate      btree_commit $::b
3947c478bd9Sstevel@tonic-gate      check_invariants
3957c478bd9Sstevel@tonic-gate    } {}
3967c478bd9Sstevel@tonic-gate    set hash [md5file test2.bt]
3977c478bd9Sstevel@tonic-gate    do_test $testid.8 {
3987c478bd9Sstevel@tonic-gate      btree_close_cursor $::c2
3997c478bd9Sstevel@tonic-gate      btree_close_cursor $::c3
4007c478bd9Sstevel@tonic-gate      btree_close_cursor $::c4
4017c478bd9Sstevel@tonic-gate      btree_close_cursor $::c5
4027c478bd9Sstevel@tonic-gate      btree_close_cursor $::c6
4037c478bd9Sstevel@tonic-gate      lindex [btree_pager_stats $::b] 1
4047c478bd9Sstevel@tonic-gate    } {0}
4057c478bd9Sstevel@tonic-gate    do_test $testid.9 {
4067c478bd9Sstevel@tonic-gate      btree_close $::b
4077c478bd9Sstevel@tonic-gate      set ::b [btree_open test2.bt]
4087c478bd9Sstevel@tonic-gate      set ::c2 [btree_cursor $::b 2 1]
4097c478bd9Sstevel@tonic-gate      set ::c3 [btree_cursor $::b 3 1]
4107c478bd9Sstevel@tonic-gate      set ::c4 [btree_cursor $::b 4 1]
4117c478bd9Sstevel@tonic-gate      set ::c5 [btree_cursor $::b 5 1]
4127c478bd9Sstevel@tonic-gate      set ::c6 [btree_cursor $::b 6 1]
4137c478bd9Sstevel@tonic-gate      check_invariants
4147c478bd9Sstevel@tonic-gate    } {}
4157c478bd9Sstevel@tonic-gate    do_test $testid.10 {
4167c478bd9Sstevel@tonic-gate      btree_close_cursor $::c2
4177c478bd9Sstevel@tonic-gate      btree_close_cursor $::c3
4187c478bd9Sstevel@tonic-gate      btree_close_cursor $::c4
4197c478bd9Sstevel@tonic-gate      btree_close_cursor $::c5
4207c478bd9Sstevel@tonic-gate      btree_close_cursor $::c6
4217c478bd9Sstevel@tonic-gate      lindex [btree_pager_stats $::b] 1
4227c478bd9Sstevel@tonic-gate    } {0}
4237c478bd9Sstevel@tonic-gate    do_test $testid.11 {
4247c478bd9Sstevel@tonic-gate      btree_close $::b
4257c478bd9Sstevel@tonic-gate    } {}
4267c478bd9Sstevel@tonic-gate    incr num2
4277c478bd9Sstevel@tonic-gate  }
4287c478bd9Sstevel@tonic-gate  incr testno
4297c478bd9Sstevel@tonic-gate  set ::b [btree_open test2.bt]
430*1da57d55SToomas Soome}
4317c478bd9Sstevel@tonic-gate
4327c478bd9Sstevel@tonic-gate# Testing is complete.  Shut everything down.
4337c478bd9Sstevel@tonic-gate#
4347c478bd9Sstevel@tonic-gatedo_test btree-999.1 {
4357c478bd9Sstevel@tonic-gate  lindex [btree_pager_stats $::b] 1
4367c478bd9Sstevel@tonic-gate} {0}
4377c478bd9Sstevel@tonic-gatedo_test btree-999.2 {
4387c478bd9Sstevel@tonic-gate  btree_close $::b
4397c478bd9Sstevel@tonic-gate} {}
4407c478bd9Sstevel@tonic-gatedo_test btree-999.3 {
4417c478bd9Sstevel@tonic-gate  file delete -force test2.bt
4427c478bd9Sstevel@tonic-gate  file exists test2.bt-journal
4437c478bd9Sstevel@tonic-gate} {0}
4447c478bd9Sstevel@tonic-gate
4457c478bd9Sstevel@tonic-gate} ;# end if( not mem: and has pager_open command );
4467c478bd9Sstevel@tonic-gate
4477c478bd9Sstevel@tonic-gatefinish_test
448