# 2012 August 29
#
# 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.
#
#***********************************************************************
# The tests in this file focus on testing that very large checkpoints
# (those that occur when the database contains an unusually large number 
# of levels or free blocks) are handled correctly.
#

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

# Check that lsm_config(AUTOWORK) seems to be connected to something.
#
do_test 1.1 { sqlite4_lsm_config db main autowork  0  } 0
do_test 1.2 { sqlite4_lsm_config db main autowork  1  } 1
do_test 1.3 { sqlite4_lsm_config db main autowork -1  } 1
do_test 1.4 { sqlite4_lsm_config db main autowork  0  } 0
do_test 1.5 { sqlite4_lsm_config db main autowork -1  } 0


set nLevel 200
do_execsql_test 2.0 { CREATE TABLE t1(a INTEGER PRIMARY KEY, b INTEGER UNIQUE) }
do_test 2.1 {
  for {set i 1} {$i <= $nLevel} {incr i} {
    db close
    sqlite4 db test.db
    sqlite4_lsm_config db main autowork 0
    db eval { INSERT INTO t1 VALUES($i, $i || $i) }
  }
  db eval { 
    SELECT count(*) FROM t1;
    PRAGMA integrity_check;
  }
} [list $nLevel ok]


#-------------------------------------------------------------------------
# The point of this test is to add a large number of blocks to the 
# free-block list and check that this doesn't seem to cause any
# obvious problems.
#
do_test 3.0 {
  db close
  forcedelete test.db
  sqlite4 db file:test.db?lsm_block_size=65536
  execsql { 
    CREATE TABLE t1(a PRIMARY KEY, b);
    CREATE INDEX i1 ON t1(b);
  }
} {}
do_execsql_test 3.1 {
  INSERT INTO t1 VALUES(randstr(100,100), randstr(100,100));
  INSERT INTO t1 SELECT randstr(100,100), randstr(100,100) FROM t1;   --   2
  INSERT INTO t1 SELECT randstr(100,100), randstr(100,100) FROM t1;   --   4
  INSERT INTO t1 SELECT randstr(100,100), randstr(100,100) FROM t1;   --   8
  INSERT INTO t1 SELECT randstr(100,100), randstr(100,100) FROM t1;   --  16
  INSERT INTO t1 SELECT randstr(100,100), randstr(100,100) FROM t1;   --  32
  INSERT INTO t1 SELECT randstr(100,100), randstr(100,100) FROM t1;   --  64
  INSERT INTO t1 SELECT randstr(100,100), randstr(100,100) FROM t1;   -- 128
  INSERT INTO t1 SELECT randstr(100,100), randstr(100,100) FROM t1;   -- 256
  INSERT INTO t1 SELECT randstr(100,100), randstr(100,100) FROM t1;   -- 512
  INSERT INTO t1 SELECT randstr(100,100), randstr(100,100) FROM t1;   --  1K
  INSERT INTO t1 SELECT randstr(100,100), randstr(100,100) FROM t1;   --  2K
  INSERT INTO t1 SELECT randstr(100,100), randstr(100,100) FROM t1;   --  4K
  INSERT INTO t1 SELECT randstr(100,100), randstr(100,100) FROM t1;   --  8K
  INSERT INTO t1 SELECT randstr(100,100), randstr(100,100) FROM t1;   -- 16K
  INSERT INTO t1 SELECT randstr(100,100), randstr(100,100) FROM t1;   -- 32K
  INSERT INTO t1 SELECT randstr(100,100), randstr(100,100) FROM t1;   -- 64K
}
do_test 3.2 {
  sqlite4_lsm_flush db main
  sqlite4_lsm_work db main -nmerge 1 -npage 1000000
  execsql { SELECT count(*) FROM t1 }
} {65536}
do_test 3.3 {
  db close
  sqlite4 db test.db
  execsql { SELECT count(*) FROM t1 }
} {65536}
do_test 3.4 {
  execsql { INSERT INTO t1 VALUES(randstr(100,100), randstr(100,100)) }
  sqlite4_lsm_flush db main
  sqlite4_lsm_work db main -nmerge 1 -npage 1000000
  execsql { SELECT count(*) FROM t1 }
} {65537}

finish_test

