# 2007 May 17
#
# 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 testing that the overflow-page related
# enhancements added after version 3.3.17 speed things up.
#
# $Id: speed3.test,v 1.6 2009/07/09 02:48:24 shane Exp $
#

#---------------------------------------------------------------------
# Test plan:
#
# If auto-vacuum is enabled for the database, the following cases
# should show performance improvement with respect to 3.3.17.
#
#   + When deleting rows that span overflow pages. This is faster
#     because the overflow pages no longer need to be read before
#     they can be moved to the free list (test cases speed3-1.X). 
#
#   + When reading a column value stored on an overflow page that
#     is not the first overflow page for the row. The improvement
#     in this case is because the overflow pages between the tree
#     page and the overflow page containing the value do not have
#     to be read (test cases speed3-2.X).
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !tclvar||!attach {
  finish_test
  return
}

speed_trial_init speed1

# Set a uniform random seed
expr srand(0)

set ::NROW 1000

# The number_name procedure below converts its argment (an integer)
# into a string which is the English-language name for that number.
#
# Example:
#
#     puts [number_name 123]   ->  "one hundred twenty three"
#
set ones {zero one two three four five six seven eight nine
          ten eleven twelve thirteen fourteen fifteen sixteen seventeen
          eighteen nineteen}
set tens {{} ten twenty thirty forty fifty sixty seventy eighty ninety}
proc number_name {n} {
  if {$n>=1000} {
    set txt "[number_name [expr {$n/1000}]] thousand"
    set n [expr {$n%1000}]
  } else {
    set txt {}
  }
  if {$n>=100} {
    append txt " [lindex $::ones [expr {$n/100}]] hundred"
    set n [expr {$n%100}]
  }
  if {$n>=20} {
    append txt " [lindex $::tens [expr {$n/10}]]"
    set n [expr {$n%10}]
  }
  if {$n>0} {
    append txt " [lindex $::ones $n]"
  }
  set txt [string trim $txt]
  if {$txt==""} {set txt zero}
  return $txt
}

proc populate_t1 {db} {
  $db transaction {
    for {set ii 0} {$ii < $::NROW} {incr ii} {
      set N [number_name $ii]
      set repeats [expr {(10000/[string length $N])+1}]
      set text [string range [string repeat $N $repeats] 0 10000]
      $db eval {INSERT INTO main.t1 VALUES($ii, $text, $ii)}
    }
    $db eval {INSERT INTO aux.t1 SELECT * FROM main.t1}
  }
}


proc io_log {db} {
  db_enter db
  array set stats1 [btree_pager_stats [btree_from_db db]]
  array set stats2 [btree_pager_stats [btree_from_db db 2]]
  db_leave db
# puts "1: [array get stats1]"
# puts "2: [array get stats2]"
  puts "Incrvacuum: Read $stats1(read), wrote $stats1(write)"
  puts "Normal    : Read $stats2(read), wrote $stats2(write)"
}

proc reset_db {} {
  db close
  sqlite3 db test.db
  db eval { 
    PRAGMA main.cache_size = 200000;
    PRAGMA main.auto_vacuum = 'incremental';
    ATTACH 'test2.db' AS 'aux'; 
    PRAGMA aux.auto_vacuum = 'none';
  }
}

forcedelete test2.db test2.db-journal
reset_db

# Set up a database in auto-vacuum mode and create a database schema.
#
do_test speed3-0.1 {
  execsql {
    CREATE TABLE main.t1(a INTEGER, b TEXT, c INTEGER);
  }
  execsql {
    SELECT name FROM sqlite_master ORDER BY 1;
  }
} {t1}
do_test speed3-0.2 {
  execsql {
    CREATE TABLE aux.t1(a INTEGER, b TEXT, c INTEGER);
  }
  execsql {
    SELECT name FROM aux.sqlite_master ORDER BY 1;
  }
} {t1}
do_test speed3-0.3 {
  populate_t1 db
  execsql {
    SELECT count(*) FROM main.t1;
    SELECT count(*) FROM aux.t1;
  }
} "$::NROW $::NROW"
do_test speed3-0.4 {
  execsql {
    PRAGMA main.auto_vacuum;
    PRAGMA aux.auto_vacuum;
  }
} {2 0}

# Delete all content in a table, one row at a time.
#
#io_log db
reset_db
speed_trial speed3-1.incrvacuum $::NROW row {DELETE FROM main.t1 WHERE 1}
speed_trial speed3-1.normal     $::NROW row {DELETE FROM aux.t1 WHERE 1}
io_log db

# Select the "C" column (located at the far end of the overflow 
# chain) from each table row.
#
#db eval {PRAGMA incremental_vacuum(500000)}
populate_t1 db
reset_db
speed_trial speed3-2.incrvacuum $::NROW row {SELECT c FROM main.t1}
speed_trial speed3-2.normal     $::NROW row {SELECT c FROM aux.t1}
io_log db

finish_test
