wal_common.tcl 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. # 2010 June 03
  2. #
  3. # The author disclaims copyright to this source code. In place of
  4. # a legal notice, here is a blessing:
  5. #
  6. # May you do good and not evil.
  7. # May you find forgiveness for yourself and forgive others.
  8. # May you share freely, never taking more than you give.
  9. #
  10. #***********************************************************************
  11. #
  12. # This file contains common code used by many different malloc tests
  13. # within the test suite.
  14. #
  15. proc wal_file_size {nFrame pgsz} {
  16. expr {32 + ($pgsz+24)*$nFrame}
  17. }
  18. proc wal_frame_count {zFile pgsz} {
  19. if {[file exists $zFile]==0} { return 0 }
  20. set f [file size $zFile]
  21. if {$f < 32} { return 0 }
  22. expr {($f - 32) / ($pgsz+24)}
  23. }
  24. proc wal_cksum_intlist {ckv1 ckv2 intlist} {
  25. upvar $ckv1 c1
  26. upvar $ckv2 c2
  27. foreach {v1 v2} $intlist {
  28. set c1 [expr {($c1 + $v1 + $c2)&0xFFFFFFFF}]
  29. set c2 [expr {($c2 + $v2 + $c1)&0xFFFFFFFF}]
  30. }
  31. }
  32. # This proc calculates checksums in the same way as those used by SQLite
  33. # in WAL files. If the $endian argument is "big", then checksums are
  34. # calculated by interpreting data as an array of big-endian integers. If
  35. # it is "little", data is interpreted as an array of little-endian integers.
  36. #
  37. proc wal_cksum {endian ckv1 ckv2 blob} {
  38. upvar $ckv1 c1
  39. upvar $ckv2 c2
  40. if {$endian!="big" && $endian!="little"} {
  41. return -error "Bad value \"$endian\" - must be \"big\" or \"little\""
  42. }
  43. set scanpattern I*
  44. if {$endian == "little"} { set scanpattern i* }
  45. binary scan $blob $scanpattern values
  46. wal_cksum_intlist c1 c2 $values
  47. }
  48. proc wal_set_walhdr {filename {intlist {}}} {
  49. if {[llength $intlist]==6} {
  50. set blob [binary format I6 $intlist]
  51. set endian little
  52. if {[lindex $intlist 0] & 0x00000001} { set endian big }
  53. set c1 0
  54. set c2 0
  55. wal_cksum $endian c1 c2 $blob
  56. append blob [binary format II $c1 $c2]
  57. set fd [open $filename r+]
  58. fconfigure $fd -translation binary
  59. fconfigure $fd -encoding binary
  60. seek $fd 0
  61. puts -nonewline $fd $blob
  62. close $fd
  63. }
  64. set fd [open $filename]
  65. fconfigure $fd -translation binary
  66. fconfigure $fd -encoding binary
  67. set blob [read $fd 24]
  68. close $fd
  69. binary scan $blob I6 ints
  70. set ints
  71. }
  72. proc wal_fix_walindex_cksum {hdrvar} {
  73. upvar $hdrvar hdr
  74. set c1 0
  75. set c2 0
  76. wal_cksum_intlist c1 c2 [lrange $hdr 0 9]
  77. lset hdr 10 $c1
  78. lset hdr 11 $c2
  79. }