⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btree2.test

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 TEST
字号:
# 2001 September 15## The author disclaims copyright to this source code.  In place of# a legal notice, here is a blessing:##    May you do good and not evil.#    May you find forgiveness for yourself and forgive others.#    May you share freely, never taking more than you give.##***********************************************************************# This file implements regression tests for SQLite library.  The# focus of this script is btree database backend## $Id: btree2.test,v 1.15 2006/03/19 13:00:25 drh Exp $set testdir [file dirname $argv0]source $testdir/tester.tclif {[info commands btree_open]!=""} {# Create a new database file containing no entries.  The database should# contain 5 tables:##     2   The descriptor table#     3   The foreground table#     4   The background table#     5   The long key table#     6   The long data table## An explanation for what all these tables are used for is provided below.#do_test btree2-1.1 {  expr srand(1)  file delete -force test2.bt  file delete -force test2.bt-journal  set ::b [btree_open test2.bt 2000 0]  btree_begin_transaction $::b  btree_create_table $::b 0} {2}do_test btree2-1.2 {  btree_create_table $::b 0} {3}do_test btree2-1.3 {  btree_create_table $::b 0} {4}do_test btree2-1.4 {  btree_create_table $::b 0} {5}do_test btree2-1.5 {  btree_create_table $::b 0} {6}do_test btree2-1.6 {  set ::c2 [btree_cursor $::b 2 1]  btree_insert $::c2 {one} {1}  btree_move_to $::c2 {one}  btree_delete $::c2  btree_close_cursor $::c2  btree_commit $::b  btree_integrity_check $::b 1 2 3 4 5 6} {}# This test module works by making lots of pseudo-random changes to a# database while simultaneously maintaining an invariant on that database.# Periodically, the script does a sanity check on the database and verifies# that the invariant is satisfied.## The invariant is as follows:##   1.  The descriptor table always contains 2 enters.  An entry keyed by#       "N" is the number of elements in the foreground and background tables#       combined.  The entry keyed by "L" is the number of digits in the keys#       for foreground and background tables.##   2.  The union of the foreground an background tables consists of N entries#       where each entry has an L-digit key. (Actually, some keys can be longer #       than L characters, but they always start with L digits.)  The keys#       cover all integers between 1 and N.  Whenever an entry is added to#       the foreground it is removed form the background and vice versa.##   3.  Some entries in the foreground and background tables have keys that#       begin with an L-digit number but are followed by additional characters.#       For each such entry there is a corresponding entry in the long key#       table.  The long key table entry has a key which is just the L-digit#       number and data which is the length of the key in the foreground and#       background tables.##   4.  The data for both foreground and background entries is usually a#       short string.  But some entries have long data strings.  For each#       such entries there is an entry in the long data type.  The key to#       long data table is an L-digit number.  (The extension on long keys#       is omitted.)  The data is the number of charaters in the data of the#       foreground or background entry.## The following function builds a database that satisfies all of the above# invariants.#proc build_db {N L} {  for {set i 2} {$i<=6} {incr i} {    catch {btree_close_cursor [set ::c$i]}    btree_clear_table $::b $i    set ::c$i [btree_cursor $::b $i 1]  }  btree_insert $::c2 N $N  btree_insert $::c2 L $L  set format %0${L}d  for {set i 1} {$i<=$N} {incr i} {     set key [format $format $i]    set data $key    btree_insert $::c3 $key $data  }}# Given a base key number and a length, construct the full text of the key# or data.#proc make_payload {keynum L len} {  set key [format %0${L}d $keynum]  set r $key  set i 1  while {[string length $r]<$len} {    append r " ($i) $key"    incr i  }  return [string range $r 0 [expr {$len-1}]]}# Verify the invariants on the database.  Return an empty string on # success or an error message if something is amiss.#proc check_invariants {} {  set ck [btree_integrity_check $::b 1 2 3 4 5 6]  if {$ck!=""} {    puts "\n*** SANITY:\n$ck"    exit    return $ck  }  btree_move_to $::c3 {}  btree_move_to $::c4 {}  btree_move_to $::c2 N  set N [btree_data $::c2]  btree_move_to $::c2 L  set L [btree_data $::c2]  set LM1 [expr {$L-1}]  for {set i 1} {$i<=$N} {incr i} {    set key {}    if {![btree_eof $::c3]} {      set key [btree_key $::c3]    }    if {[scan $key %d k]<1} {set k 0}    if {$k!=$i} {      set key {}      if {![btree_eof $::c4]} {        set key [btree_key $::c4]      }      if {[scan $key %d k]<1} {set k 0}      if {$k!=$i} {        return "Key $i is missing from both foreground and background"      }      set data [btree_data $::c4]      btree_next $::c4    } else {      set data [btree_data $::c3]      btree_next $::c3    }    set skey [string range $key 0 $LM1]    if {[btree_move_to $::c5 $skey]==0} {      set keylen [btree_data $::c5]    } else {      set keylen $L    }    if {[string length $key]!=$keylen} {      return "Key $i is the wrong size.\              Is \"$key\" but should be \"[make_payload $k $L $keylen]\""    }    if {[make_payload $k $L $keylen]!=$key} {      return "Key $i has an invalid extension"    }    if {[btree_move_to $::c6 $skey]==0} {      set datalen [btree_data $::c6]    } else {      set datalen $L    }    if {[string length $data]!=$datalen} {      return "Data for $i is the wrong size.\              Is [string length $data] but should be $datalen"    }    if {[make_payload $k $L $datalen]!=$data} {      return "Entry $i has an incorrect data"    }  }}# Look at all elements in both the foreground and background tables.# Make sure the key is always the same as the prefix of the data.## This routine was used for hunting bugs.  It is not a part of standard# tests.#proc check_data {n key} {  global c3 c4  incr n -1  foreach c [list $c3 $c4] {    btree_first $c  ;# move_to $c $key    set cnt 0    while {![btree_eof $c]} {      set key [btree_key $c]      set data [btree_data $c]      if {[string range $key 0 $n] ne [string range $data 0 $n]} {        puts "key=[list $key] data=[list $data] n=$n"        puts "cursor info = [btree_cursor_info $c]"        btree_page_dump $::b [lindex [btree_cursor_info $c] 0]        exit      }      btree_next $c    }  }}# Make random changes to the database such that each change preserves# the invariants.  The number of changes is $n*N where N is the parameter# from the descriptor table.  Each changes begins with a random key.# the entry with that key is put in the foreground table with probability# $I and it is put in background with probability (1.0-$I).  It gets# a long key with probability $K and long data with probability $D.  # set chngcnt 0proc random_changes {n I K D} {  global chngcnt  btree_move_to $::c2 N  set N [btree_data $::c2]  btree_move_to $::c2 L  set L [btree_data $::c2]  set LM1 [expr {$L-1}]  set total [expr {int($N*$n)}]  set format %0${L}d  for {set i 0} {$i<$total} {incr i} {    set k [expr {int(rand()*$N)+1}]    set insert [expr {rand()<=$I}]    set longkey [expr {rand()<=$K}]    set longdata [expr {rand()<=$D}]    if {$longkey} {      set x [expr {rand()}]      set keylen [expr {int($x*$x*$x*$x*3000)+10}]    } else {      set keylen $L    }    set key [make_payload $k $L $keylen]    if {$longdata} {      set x [expr {rand()}]      set datalen [expr {int($x*$x*$x*$x*3000)+10}]    } else {      set datalen $L    }    set data [make_payload $k $L $datalen]    set basekey [format $format $k]    if {[set c [btree_move_to $::c3 $basekey]]==0} {      btree_delete $::c3    } else {      if {$c<0} {btree_next $::c3}      if {![btree_eof $::c3]} {        if {[string match $basekey* [btree_key $::c3]]} {          btree_delete $::c3        }      }    }    if {[set c [btree_move_to $::c4 $basekey]]==0} {      btree_delete $::c4    } else {      if {$c<0} {btree_next $::c4}      if {![btree_eof $::c4]} {        if {[string match $basekey* [btree_key $::c4]]} {          btree_delete $::c4        }      }    }    set kx -1    if {![btree_eof $::c4]} {      if {[scan [btree_key $::c4] %d kx]<1} {set kx -1}    }    if {$kx==$k} {      btree_delete $::c4    }    # For debugging - change the "0" to "1" to integrity check after    # every change.    if 0 {      incr chngcnt      puts check----$chngcnt      set ck [btree_integrity_check $::b 1 2 3 4 5 6]      if {$ck!=""} {         puts "\nSANITY CHECK FAILED!\n$ck"         exit       }    }    if {$insert} {      btree_insert $::c3 $key $data    } else {      btree_insert $::c4 $key $data    }    if {$longkey} {      btree_insert $::c5 $basekey $keylen    } elseif {[btree_move_to $::c5 $basekey]==0} {      btree_delete $::c5    }    if {$longdata} {      btree_insert $::c6 $basekey $datalen    } elseif {[btree_move_to $::c6 $basekey]==0} {      btree_delete $::c6    }    # For debugging - change the "0" to "1" to integrity check after    # every change.    if 0 {      incr chngcnt      puts check----$chngcnt      set ck [btree_integrity_check $::b 1 2 3 4 5 6]      if {$ck!=""} {         puts "\nSANITY CHECK FAILED!\n$ck"         exit       }    }  }}set btree_trace 0# Repeat this test sequence on database of various sizes#set testno 2foreach {N L} {  10 2  50 2  200 3  2000 5} {  puts "**** N=$N L=$L ****"  set hash [md5file test2.bt]  do_test btree2-$testno.1 [subst -nocommands {    set ::c2 [btree_cursor $::b 2 1]    set ::c3 [btree_cursor $::b 3 1]    set ::c4 [btree_cursor $::b 4 1]    set ::c5 [btree_cursor $::b 5 1]    set ::c6 [btree_cursor $::b 6 1]    btree_begin_transaction $::b    build_db $N $L    check_invariants  }] {}  do_test btree2-$testno.2 {    btree_close_cursor $::c2    btree_close_cursor $::c3    btree_close_cursor $::c4    btree_close_cursor $::c5    btree_close_cursor $::c6    btree_rollback $::b    md5file test2.bt  } $hash  do_test btree2-$testno.3 [subst -nocommands {    btree_begin_transaction $::b    set ::c2 [btree_cursor $::b 2 1]    set ::c3 [btree_cursor $::b 3 1]    set ::c4 [btree_cursor $::b 4 1]    set ::c5 [btree_cursor $::b 5 1]    set ::c6 [btree_cursor $::b 6 1]    build_db $N $L    check_invariants  }] {}  do_test btree2-$testno.4 {    btree_commit $::b    check_invariants  } {}  do_test btree2-$testno.5  {    lindex [btree_pager_stats $::b] 1  } {6}  do_test btree2-$testno.6  {    btree_cursor_info $::c2    btree_cursor_info $::c3    btree_cursor_info $::c4    btree_cursor_info $::c5    btree_cursor_info $::c6    btree_close_cursor $::c2    btree_close_cursor $::c3    btree_close_cursor $::c4    btree_close_cursor $::c5    btree_close_cursor $::c6    lindex [btree_pager_stats $::b] 1  } {0}  do_test btree2-$testno.7 {    btree_close $::b  } {}  # For each database size, run various changes tests.  #  set num2 1  foreach {n I K D} {    0.5 0.5 0.1 0.1    1.0 0.2 0.1 0.1    1.0 0.8 0.1 0.1    2.0 0.0 0.1 0.1    2.0 1.0 0.1 0.1    2.0 0.0 0.0 0.0    2.0 1.0 0.0 0.0  } {    set testid btree2-$testno.8.$num2    set hash [md5file test2.bt]    do_test $testid.0 {      set ::b [btree_open test2.bt 2000 0]      set ::c2 [btree_cursor $::b 2 1]      set ::c3 [btree_cursor $::b 3 1]      set ::c4 [btree_cursor $::b 4 1]      set ::c5 [btree_cursor $::b 5 1]      set ::c6 [btree_cursor $::b 6 1]      check_invariants    } {}    set cnt 6    for {set i 2} {$i<=6} {incr i} {      if {[lindex [btree_cursor_info [set ::c$i]] 0]!=$i} {incr cnt}    }    do_test $testid.1 {      btree_begin_transaction $::b      lindex [btree_pager_stats $::b] 1    } $cnt    do_test $testid.2 [subst {      random_changes $n $I $K $D    }] {}    do_test $testid.3 {      check_invariants    } {}    do_test $testid.4 {      btree_close_cursor $::c2      btree_close_cursor $::c3      btree_close_cursor $::c4      btree_close_cursor $::c5      btree_close_cursor $::c6      btree_rollback $::b      md5file test2.bt    } $hash    btree_begin_transaction $::b    set ::c2 [btree_cursor $::b 2 1]    set ::c3 [btree_cursor $::b 3 1]    set ::c4 [btree_cursor $::b 4 1]    set ::c5 [btree_cursor $::b 5 1]    set ::c6 [btree_cursor $::b 6 1]    do_test $testid.5 [subst {      random_changes $n $I $K $D    }] {}    do_test $testid.6 {      check_invariants    } {}    do_test $testid.7 {      btree_commit $::b      check_invariants    } {}    set hash [md5file test2.bt]    do_test $testid.8 {      btree_close_cursor $::c2      btree_close_cursor $::c3      btree_close_cursor $::c4      btree_close_cursor $::c5      btree_close_cursor $::c6      lindex [btree_pager_stats $::b] 1    } {0}    do_test $testid.9 {      btree_close $::b      set ::b [btree_open test2.bt 2000 0]      set ::c2 [btree_cursor $::b 2 1]      set ::c3 [btree_cursor $::b 3 1]      set ::c4 [btree_cursor $::b 4 1]      set ::c5 [btree_cursor $::b 5 1]      set ::c6 [btree_cursor $::b 6 1]      check_invariants    } {}    do_test $testid.10 {      btree_close_cursor $::c2      btree_close_cursor $::c3      btree_close_cursor $::c4      btree_close_cursor $::c5      btree_close_cursor $::c6      lindex [btree_pager_stats $::b] 1    } {0}    do_test $testid.11 {      btree_close $::b    } {}    incr num2  }  incr testno  set ::b [btree_open test2.bt 2000 0]}  # Testing is complete.  Shut everything down.#do_test btree-999.1 {  lindex [btree_pager_stats $::b] 1} {0}do_test btree-999.2 {  btree_close $::b} {}do_test btree-999.3 {  file delete -force test2.bt  file exists test2.bt-journal} {0}} ;# end if( not mem: and has pager_open command );finish_test

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -