10190d1daSdanielk1977# 2005 November 30 20190d1daSdanielk1977# 30190d1daSdanielk1977# The author disclaims copyright to this source code. In place of 40190d1daSdanielk1977# a legal notice, here is a blessing: 50190d1daSdanielk1977# 60190d1daSdanielk1977# May you do good and not evil. 70190d1daSdanielk1977# May you find forgiveness for yourself and forgive others. 80190d1daSdanielk1977# May you share freely, never taking more than you give. 90190d1daSdanielk1977# 100190d1daSdanielk1977#*********************************************************************** 110190d1daSdanielk1977# 12aef0bf64Sdanielk1977# This file contains test cases focused on the two memory-management APIs, 13aef0bf64Sdanielk1977# sqlite3_soft_heap_limit() and sqlite3_release_memory(). 14aef0bf64Sdanielk1977# 15468c82bcSdanielk1977# Prior to version 3.6.2, calling sqlite3_release_memory() or exceeding 16468c82bcSdanielk1977# the configured soft heap limit could cause sqlite to upgrade database 17468c82bcSdanielk1977# locks and flush dirty pages to the file system. As of 3.6.2, this is 18468c82bcSdanielk1977# no longer the case. In version 3.6.2, sqlite3_release_memory() only 19468c82bcSdanielk1977# reclaims clean pages. This test file has been updated accordingly. 200190d1daSdanielk1977# 2111809366Sdrh# $Id: malloc5.test,v 1.22 2009/04/11 19:09:54 drh Exp $ 2252622828Sdanielk1977 230190d1daSdanielk1977set testdir [file dirname $argv0] 240190d1daSdanielk1977source $testdir/tester.tcl 25eee4c8caSdrhsource $testdir/malloc_common.tcl 2652622828Sdanielk1977db close 270190d1daSdanielk1977 28aef0bf64Sdanielk1977# Only run these tests if memory debugging is turned on. 29ed138fb3Sdrh# 30eee4c8caSdrhif {!$MEMDEBUG} { 315a3032b3Sdrh puts "Skipping malloc5 tests: not compiled with -DSQLITE_MEMDEBUG..." 32aef0bf64Sdanielk1977 finish_test 33aef0bf64Sdanielk1977 return 34aef0bf64Sdanielk1977} 35aef0bf64Sdanielk1977 3652622828Sdanielk1977# Skip these tests if OMIT_MEMORY_MANAGEMENT was defined at compile time. 3752622828Sdanielk1977ifcapable !memorymanage { 3852622828Sdanielk1977 finish_test 3952622828Sdanielk1977 return 4052622828Sdanielk1977} 4152622828Sdanielk1977 429f549d54Sdan# The sizes of memory allocations from system malloc() might vary, 439f549d54Sdan# depending on the memory allocator algorithms used. The following 449f549d54Sdan# routine is designed to support answers that fall within a range 459f549d54Sdan# of values while also supplying easy-to-understand "expected" values 469f549d54Sdan# when errors occur. 479f549d54Sdan# 489f549d54Sdanproc value_in_range {target x args} { 499f549d54Sdan set v [lindex $args 0] 509f549d54Sdan if {$v!=""} { 519f549d54Sdan if {$v<$target*$x} {return $v} 529f549d54Sdan if {$v>$target/$x} {return $v} 539f549d54Sdan } 549f549d54Sdan return "number between [expr {int($target*$x)}] and [expr {int($target/$x)}]" 559f549d54Sdan} 569f549d54Sdanset mrange 0.98 ;# plus or minus 2% 579f549d54Sdan 5803bc525aSdantest_set_config_pagecache 0 100 5903bc525aSdan 603aefabafSdrhsqlite3_soft_heap_limit 0 6152622828Sdanielk1977sqlite3 db test.db 629f549d54Sdan# db eval {PRAGMA cache_size=1} 6352622828Sdanielk1977 640190d1daSdanielk1977do_test malloc5-1.1 { 656aafc29bSdrh # Simplest possible test. Call sqlite3_release_memory when there is exactly 66468c82bcSdanielk1977 # one unused page in a single pager cache. The page cannot be freed, as 67468c82bcSdanielk1977 # it is dirty. So sqlite3_release_memory() returns 0. 680190d1daSdanielk1977 # 690190d1daSdanielk1977 execsql { 70271d8cb0Sdrh PRAGMA auto_vacuum=OFF; 710190d1daSdanielk1977 BEGIN; 720190d1daSdanielk1977 CREATE TABLE abc(a, b, c); 730190d1daSdanielk1977 } 74468c82bcSdanielk1977 sqlite3_release_memory 75468c82bcSdanielk1977} {0} 76468c82bcSdanielk1977 77468c82bcSdanielk1977do_test malloc5-1.2 { 78468c82bcSdanielk1977 # Test that the transaction started in the above test is still active. 79468c82bcSdanielk1977 # The lock on the database file should not have been upgraded (this was 80468c82bcSdanielk1977 # not the case before version 3.6.2). 81468c82bcSdanielk1977 # 82468c82bcSdanielk1977 sqlite3 db2 test.db 83957026acSdrh execsql {PRAGMA cache_size=2; SELECT * FROM sqlite_master } db2 84468c82bcSdanielk1977} {} 85468c82bcSdanielk1977do_test malloc5-1.3 { 86468c82bcSdanielk1977 # Call [sqlite3_release_memory] when there is exactly one unused page 87468c82bcSdanielk1977 # in the cache belonging to db2. 88468c82bcSdanielk1977 # 896aafc29bSdrh set ::pgalloc [sqlite3_release_memory] 909f549d54Sdan value_in_range 1288 0.75 919f549d54Sdan} [value_in_range 1288 0.75] 929b5d76bfSdrh 93468c82bcSdanielk1977do_test malloc5-1.4 { 94468c82bcSdanielk1977 # Commit the transaction and open a new one. Read 1 page into the cache. 95468c82bcSdanielk1977 # Because the page is not dirty, it is eligible for collection even 96468c82bcSdanielk1977 # before the transaction is concluded. 97468c82bcSdanielk1977 # 980190d1daSdanielk1977 execsql { 990190d1daSdanielk1977 COMMIT; 1000190d1daSdanielk1977 BEGIN; 1010190d1daSdanielk1977 SELECT * FROM abc; 1020190d1daSdanielk1977 } 1039b5d76bfSdrh value_in_range $::pgalloc $::mrange [sqlite3_release_memory] 1049b5d76bfSdrh} [value_in_range $::pgalloc $::mrange] 105468c82bcSdanielk1977 1060190d1daSdanielk1977do_test malloc5-1.5 { 107468c82bcSdanielk1977 # Conclude the transaction opened in the previous [do_test] block. This 108468c82bcSdanielk1977 # causes another page (page 1) to become eligible for recycling. 109468c82bcSdanielk1977 # 110468c82bcSdanielk1977 execsql { COMMIT } 1119b5d76bfSdrh value_in_range $::pgalloc $::mrange [sqlite3_release_memory] 1129b5d76bfSdrh} [value_in_range $::pgalloc $::mrange] 113468c82bcSdanielk1977 114468c82bcSdanielk1977do_test malloc5-1.6 { 1150190d1daSdanielk1977 # Manipulate the cache so that it contains two unused pages. One requires 1160190d1daSdanielk1977 # a journal-sync to free, the other does not. 11724168728Sdanielk1977 db2 close 1180190d1daSdanielk1977 execsql { 119468c82bcSdanielk1977 BEGIN; 1200190d1daSdanielk1977 CREATE TABLE def(d, e, f); 1219f549d54Sdan SELECT * FROM abc; 1220190d1daSdanielk1977 } 1239b5d76bfSdrh value_in_range $::pgalloc $::mrange [sqlite3_release_memory 500] 1249b5d76bfSdrh} [value_in_range $::pgalloc $::mrange] 1250190d1daSdanielk1977do_test malloc5-1.7 { 126468c82bcSdanielk1977 # Database should not be locked this time. 127468c82bcSdanielk1977 sqlite3 db2 test.db 128468c82bcSdanielk1977 catchsql { SELECT * FROM abc } db2 129468c82bcSdanielk1977} {0 {}} 130468c82bcSdanielk1977do_test malloc5-1.8 { 131468c82bcSdanielk1977 # Try to release another block of memory. This will fail as the only 132468c82bcSdanielk1977 # pages currently in the cache are dirty (page 3) or pinned (page 1). 13324168728Sdanielk1977 db2 close 1346aafc29bSdrh sqlite3_release_memory 500 135468c82bcSdanielk1977} 0 1360190d1daSdanielk1977do_test malloc5-1.8 { 137468c82bcSdanielk1977 # Database is still not locked. 138468c82bcSdanielk1977 # 13924168728Sdanielk1977 sqlite3 db2 test.db 140468c82bcSdanielk1977 catchsql { SELECT * FROM abc } db2 141468c82bcSdanielk1977} {0 {}} 1420190d1daSdanielk1977do_test malloc5-1.9 { 1430190d1daSdanielk1977 execsql { 1440190d1daSdanielk1977 COMMIT; 1450190d1daSdanielk1977 } 1460190d1daSdanielk1977} {} 1470190d1daSdanielk1977 1480190d1daSdanielk1977do_test malloc5-2.1 { 1490190d1daSdanielk1977 # Put some data in tables abc and def. Both tables are still wholly 1500190d1daSdanielk1977 # contained within their root pages. 1510190d1daSdanielk1977 execsql { 1520190d1daSdanielk1977 INSERT INTO abc VALUES(1, 2, 3); 1530190d1daSdanielk1977 INSERT INTO abc VALUES(4, 5, 6); 1540190d1daSdanielk1977 INSERT INTO def VALUES(7, 8, 9); 1550190d1daSdanielk1977 INSERT INTO def VALUES(10,11,12); 1560190d1daSdanielk1977 } 1570190d1daSdanielk1977} {} 1580190d1daSdanielk1977do_test malloc5-2.2 { 1590190d1daSdanielk1977 # Load the root-page for table def into the cache. Then query table abc. 1600190d1daSdanielk1977 # Halfway through the query call sqlite3_release_memory(). The goal of this 1610190d1daSdanielk1977 # test is to make sure we don't free pages that are in use (specifically, 1620190d1daSdanielk1977 # the root of table abc). 163468c82bcSdanielk1977 sqlite3_release_memory 1640190d1daSdanielk1977 set nRelease 0 1650190d1daSdanielk1977 execsql { 1660190d1daSdanielk1977 BEGIN; 1670190d1daSdanielk1977 SELECT * FROM def; 1680190d1daSdanielk1977 } 1695591df55Sdanielk1977 set data [list] 1700190d1daSdanielk1977 db eval {SELECT * FROM abc} { 1716aafc29bSdrh incr nRelease [sqlite3_release_memory] 1720190d1daSdanielk1977 lappend data $a $b $c 1730190d1daSdanielk1977 } 1745591df55Sdanielk1977 execsql { 1755591df55Sdanielk1977 COMMIT; 1765591df55Sdanielk1977 } 177*69a4b383Sdan value_in_range $::pgalloc $::mrange $nRelease 178*69a4b383Sdan} [value_in_range $::pgalloc $::mrange] 179*69a4b383Sdando_test malloc5-2.2.1 { 180*69a4b383Sdan set data 181*69a4b383Sdan} {1 2 3 4 5 6} 1820190d1daSdanielk1977 1835591df55Sdanielk1977do_test malloc5-3.1 { 1845591df55Sdanielk1977 # Simple test to show that if two pagers are opened from within this 1855591df55Sdanielk1977 # thread, memory is freed from both when sqlite3_release_memory() is 1865591df55Sdanielk1977 # called. 1875591df55Sdanielk1977 execsql { 1885591df55Sdanielk1977 BEGIN; 1895591df55Sdanielk1977 SELECT * FROM abc; 1905591df55Sdanielk1977 } 1915591df55Sdanielk1977 execsql { 1925591df55Sdanielk1977 SELECT * FROM sqlite_master; 1935591df55Sdanielk1977 BEGIN; 1945591df55Sdanielk1977 SELECT * FROM def; 1955591df55Sdanielk1977 } db2 19640a3cabeSdrh value_in_range [expr $::pgalloc*2] 0.99 [sqlite3_release_memory] 19740a3cabeSdrh} [value_in_range [expr $::pgalloc * 2] 0.99] 1985591df55Sdanielk1977do_test malloc5-3.2 { 1995591df55Sdanielk1977 concat \ 2005591df55Sdanielk1977 [execsql {SELECT * FROM abc; COMMIT}] \ 2015591df55Sdanielk1977 [execsql {SELECT * FROM def; COMMIT} db2] 2025591df55Sdanielk1977} {1 2 3 4 5 6 7 8 9 10 11 12} 2035591df55Sdanielk1977 2045591df55Sdanielk1977db2 close 205ed138fb3Sdrhputs "Highwater mark: [sqlite3_memory_highwater]" 2065591df55Sdanielk1977 2075591df55Sdanielk1977# The following two test cases each execute a transaction in which 2085591df55Sdanielk1977# 10000 rows are inserted into table abc. The first test case is used 2095591df55Sdanielk1977# to ensure that more than 1MB of dynamic memory is used to perform 2105591df55Sdanielk1977# the transaction. 2115591df55Sdanielk1977# 2125591df55Sdanielk1977# The second test case sets the "soft-heap-limit" to 100,000 bytes (0.1 MB) 2135591df55Sdanielk1977# and tests to see that this limit is not exceeded at any point during 2145591df55Sdanielk1977# transaction execution. 2155591df55Sdanielk1977# 216aef0bf64Sdanielk1977# Before executing malloc5-4.* we save the value of the current soft heap 217aef0bf64Sdanielk1977# limit in variable ::soft_limit. The original value is restored after 218aef0bf64Sdanielk1977# running the tests. 219aef0bf64Sdanielk1977# 2206aafc29bSdrhset ::soft_limit [sqlite3_soft_heap_limit -1] 2213a7fb7c4Sdrhexecsql {PRAGMA cache_size=2000} 2225591df55Sdanielk1977do_test malloc5-4.1 { 2235591df55Sdanielk1977 execsql {BEGIN;} 2245591df55Sdanielk1977 execsql {DELETE FROM abc;} 2255591df55Sdanielk1977 for {set i 0} {$i < 10000} {incr i} { 2265591df55Sdanielk1977 execsql "INSERT INTO abc VALUES($i, $i, '[string repeat X 100]');" 2275591df55Sdanielk1977 } 2285591df55Sdanielk1977 execsql {COMMIT;} 229c63e880bSdan db cache flush 230468c82bcSdanielk1977 sqlite3_release_memory 231468c82bcSdanielk1977 sqlite3_memory_highwater 1 232468c82bcSdanielk1977 execsql {SELECT * FROM abc} 233ed138fb3Sdrh set nMaxBytes [sqlite3_memory_highwater 1] 234ed138fb3Sdrh puts -nonewline " (Highwater mark: $nMaxBytes) " 235ed138fb3Sdrh expr $nMaxBytes > 1000000 2365591df55Sdanielk1977} {1} 2375591df55Sdanielk1977do_test malloc5-4.2 { 238957026acSdrh db eval {PRAGMA cache_size=1} 239c63e880bSdan db cache flush 2406aafc29bSdrh sqlite3_release_memory 241a7fc253dSdan sqlite3_soft_heap_limit 200000 242ed138fb3Sdrh sqlite3_memory_highwater 1 243468c82bcSdanielk1977 execsql {SELECT * FROM abc} 244ed138fb3Sdrh set nMaxBytes [sqlite3_memory_highwater 1] 245ed138fb3Sdrh puts -nonewline " (Highwater mark: $nMaxBytes) " 246a7fc253dSdan expr $nMaxBytes <= 210000 2475591df55Sdanielk1977} {1} 2485591df55Sdanielk1977do_test malloc5-4.3 { 2495591df55Sdanielk1977 # Check that the content of table abc is at least roughly as expected. 2505591df55Sdanielk1977 execsql { 2515591df55Sdanielk1977 SELECT count(*), sum(a), sum(b) FROM abc; 2525591df55Sdanielk1977 } 253468c82bcSdanielk1977} [list 10000 [expr int(10000.0 * 4999.5)] [expr int(10000.0 * 4999.5)]] 2545591df55Sdanielk1977 255aef0bf64Sdanielk1977# Restore the soft heap limit. 2566aafc29bSdrhsqlite3_soft_heap_limit $::soft_limit 25752622828Sdanielk1977 258c551edc2Sdanielk1977# Test that there are no problems calling sqlite3_release_memory when 259c551edc2Sdanielk1977# there are open in-memory databases. 260c551edc2Sdanielk1977# 261c551edc2Sdanielk1977# At one point these tests would cause a seg-fault. 262c551edc2Sdanielk1977# 263c551edc2Sdanielk1977do_test malloc5-5.1 { 264c551edc2Sdanielk1977 db close 265c551edc2Sdanielk1977 sqlite3 db :memory: 266c551edc2Sdanielk1977 execsql { 267c551edc2Sdanielk1977 BEGIN; 268c551edc2Sdanielk1977 CREATE TABLE abc(a, b, c); 269c551edc2Sdanielk1977 INSERT INTO abc VALUES('abcdefghi', 1234567890, NULL); 270c551edc2Sdanielk1977 INSERT INTO abc SELECT * FROM abc; 271c551edc2Sdanielk1977 INSERT INTO abc SELECT * FROM abc; 272c551edc2Sdanielk1977 INSERT INTO abc SELECT * FROM abc; 273c551edc2Sdanielk1977 INSERT INTO abc SELECT * FROM abc; 274c551edc2Sdanielk1977 INSERT INTO abc SELECT * FROM abc; 275c551edc2Sdanielk1977 INSERT INTO abc SELECT * FROM abc; 276c551edc2Sdanielk1977 INSERT INTO abc SELECT * FROM abc; 277c551edc2Sdanielk1977 } 278c551edc2Sdanielk1977 sqlite3_release_memory 279c551edc2Sdanielk1977} 0 28084f786fcSdanielk1977do_test malloc5-5.2 { 281c551edc2Sdanielk1977 sqlite3_soft_heap_limit 5000 282c551edc2Sdanielk1977 execsql { 283c551edc2Sdanielk1977 COMMIT; 284c551edc2Sdanielk1977 PRAGMA temp_store = memory; 285c551edc2Sdanielk1977 SELECT * FROM abc ORDER BY a; 286c551edc2Sdanielk1977 } 287c551edc2Sdanielk1977 expr 1 288c551edc2Sdanielk1977} {1} 28984f786fcSdanielk1977sqlite3_soft_heap_limit $::soft_limit 29084f786fcSdanielk1977 29184f786fcSdanielk1977#------------------------------------------------------------------------- 29284f786fcSdanielk1977# The following test cases (malloc5-6.*) test the new global LRU list 29384f786fcSdanielk1977# used to determine the pages to recycle when sqlite3_release_memory is 29484f786fcSdanielk1977# called and there is more than one pager open. 29584f786fcSdanielk1977# 29684f786fcSdanielk1977proc nPage {db} { 29784f786fcSdanielk1977 set bt [btree_from_db $db] 29884f786fcSdanielk1977 array set stats [btree_pager_stats $bt] 29984f786fcSdanielk1977 set stats(page) 30084f786fcSdanielk1977} 30184f786fcSdanielk1977db close 302fda06befSmistachkinforcedelete test.db test.db-journal test2.db test2.db-journal 30384f786fcSdanielk1977 30484f786fcSdanielk1977# This block of test-cases (malloc5-6.1.*) prepares two database files 30584f786fcSdanielk1977# for the subsequent tests. 30684f786fcSdanielk1977do_test malloc5-6.1.1 { 30784f786fcSdanielk1977 sqlite3 db test.db 30884f786fcSdanielk1977 execsql { 30984f786fcSdanielk1977 PRAGMA page_size=1024; 310957026acSdrh PRAGMA default_cache_size=2; 311801880f6Sdanielk1977 } 312801880f6Sdanielk1977 execsql { 313801880f6Sdanielk1977 PRAGMA temp_store = memory; 31484f786fcSdanielk1977 BEGIN; 31584f786fcSdanielk1977 CREATE TABLE abc(a PRIMARY KEY, b, c); 31684f786fcSdanielk1977 INSERT INTO abc VALUES(randstr(50,50), randstr(75,75), randstr(100,100)); 31784f786fcSdanielk1977 INSERT INTO abc 31884f786fcSdanielk1977 SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc; 31984f786fcSdanielk1977 INSERT INTO abc 32084f786fcSdanielk1977 SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc; 32184f786fcSdanielk1977 INSERT INTO abc 32284f786fcSdanielk1977 SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc; 32384f786fcSdanielk1977 INSERT INTO abc 32484f786fcSdanielk1977 SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc; 32584f786fcSdanielk1977 INSERT INTO abc 32684f786fcSdanielk1977 SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc; 32784f786fcSdanielk1977 INSERT INTO abc 32884f786fcSdanielk1977 SELECT randstr(50,50), randstr(75,75), randstr(100,100) FROM abc; 32984f786fcSdanielk1977 COMMIT; 33084f786fcSdanielk1977 } 331fda06befSmistachkin forcecopy test.db test2.db 33284f786fcSdanielk1977 sqlite3 db2 test2.db 333957026acSdrh db2 eval {PRAGMA cache_size=2} 334fa18beceSdanielk1977 list \ 335fa18beceSdanielk1977 [expr ([file size test.db]/1024)>20] [expr ([file size test2.db]/1024)>20] 336fa18beceSdanielk1977} {1 1} 33784f786fcSdanielk1977do_test malloc5-6.1.2 { 33884f786fcSdanielk1977 list [execsql {PRAGMA cache_size}] [execsql {PRAGMA cache_size} db2] 339957026acSdrh} {2 2} 34084f786fcSdanielk1977 34184f786fcSdanielk1977do_test malloc5-6.2.1 { 34284f786fcSdanielk1977 execsql {SELECT * FROM abc} db2 34384f786fcSdanielk1977 execsql {SELECT * FROM abc} db 344801880f6Sdanielk1977 expr [nPage db] + [nPage db2] 345957026acSdrh} {4} 346801880f6Sdanielk1977 34784f786fcSdanielk1977do_test malloc5-6.2.2 { 34884f786fcSdanielk1977 # If we now try to reclaim some memory, it should come from the db2 cache. 34984f786fcSdanielk1977 sqlite3_release_memory 3000 350801880f6Sdanielk1977 expr [nPage db] + [nPage db2] 3519f549d54Sdan} {1} 35284f786fcSdanielk1977do_test malloc5-6.2.3 { 35384f786fcSdanielk1977 # Access the db2 cache again, so that all the db2 pages have been used 35484f786fcSdanielk1977 # more recently than all the db pages. Then try to reclaim 3000 bytes. 35584f786fcSdanielk1977 # This time, 3 pages should be pulled from the db cache. 35684f786fcSdanielk1977 execsql { SELECT * FROM abc } db2 35784f786fcSdanielk1977 sqlite3_release_memory 3000 358801880f6Sdanielk1977 expr [nPage db] + [nPage db2] 3599f549d54Sdan} {0} 36084f786fcSdanielk1977 36184f786fcSdanielk1977do_test malloc5-6.3.1 { 36284f786fcSdanielk1977 # Now open a transaction and update 2 pages in the db2 cache. Then 36384f786fcSdanielk1977 # do a SELECT on the db cache so that all the db pages are more recently 36484f786fcSdanielk1977 # used than the db2 pages. When we try to free memory, SQLite should 36584f786fcSdanielk1977 # free the non-dirty db2 pages, then the db pages, then finally use 36684f786fcSdanielk1977 # sync() to free up the dirty db2 pages. The only page that cannot be 36784f786fcSdanielk1977 # freed is page1 of db2. Because there is an open transaction, the 36884f786fcSdanielk1977 # btree layer holds a reference to page 1 in the db2 cache. 3699f549d54Sdan # 3709f549d54Sdan # UPDATE: No longer. As release_memory() does not cause a sync() 37184f786fcSdanielk1977 execsql { 37284f786fcSdanielk1977 BEGIN; 37384f786fcSdanielk1977 UPDATE abc SET c = randstr(100,100) 37484f786fcSdanielk1977 WHERE rowid = 1 OR rowid = (SELECT max(rowid) FROM abc); 37584f786fcSdanielk1977 } db2 37684f786fcSdanielk1977 execsql { SELECT * FROM abc } db 377801880f6Sdanielk1977 expr [nPage db] + [nPage db2] 378957026acSdrh} {4} 37984f786fcSdanielk1977do_test malloc5-6.3.2 { 38084f786fcSdanielk1977 # Try to release 7700 bytes. This should release all the 38184f786fcSdanielk1977 # non-dirty pages held by db2. 3829d69c5d1Sdan sqlite3_release_memory [expr 7*1132] 38384f786fcSdanielk1977 list [nPage db] [nPage db2] 3849f549d54Sdan} {0 3} 38584f786fcSdanielk1977do_test malloc5-6.3.3 { 38684f786fcSdanielk1977 # Try to release another 1000 bytes. This should come fromt the db 38784f786fcSdanielk1977 # cache, since all three pages held by db2 are either in-use or diry. 38884f786fcSdanielk1977 sqlite3_release_memory 1000 38984f786fcSdanielk1977 list [nPage db] [nPage db2] 3909f549d54Sdan} {0 3} 39184f786fcSdanielk1977do_test malloc5-6.3.4 { 39284f786fcSdanielk1977 # Now release 9900 more (about 9 pages worth). This should expunge 39384f786fcSdanielk1977 # the rest of the db cache. But the db2 cache remains intact, because 39484f786fcSdanielk1977 # SQLite tries to avoid calling sync(). 39511809366Sdrh if {$::tcl_platform(wordSize)==8} { 3969d69c5d1Sdan sqlite3_release_memory 10500 39711809366Sdrh } else { 39884f786fcSdanielk1977 sqlite3_release_memory 9900 39911809366Sdrh } 40084f786fcSdanielk1977 list [nPage db] [nPage db2] 4019f549d54Sdan} {0 3} 40284f786fcSdanielk1977do_test malloc5-6.3.5 { 40384f786fcSdanielk1977 # But if we are really insistent, SQLite will consent to call sync() 404468c82bcSdanielk1977 # if there is no other option. UPDATE: As of 3.6.2, SQLite will not 405468c82bcSdanielk1977 # call sync() in this scenario. So no further memory can be reclaimed. 40684f786fcSdanielk1977 sqlite3_release_memory 1000 40784f786fcSdanielk1977 list [nPage db] [nPage db2] 4089f549d54Sdan} {0 3} 40984f786fcSdanielk1977do_test malloc5-6.3.6 { 41084f786fcSdanielk1977 # The referenced page (page 1 of the db2 cache) will not be freed no 41184f786fcSdanielk1977 # matter how much memory we ask for: 41284f786fcSdanielk1977 sqlite3_release_memory 31459 41384f786fcSdanielk1977 list [nPage db] [nPage db2] 4149f549d54Sdan} {0 3} 41584f786fcSdanielk1977 41684f786fcSdanielk1977db2 close 417c551edc2Sdanielk1977 418c551edc2Sdanielk1977sqlite3_soft_heap_limit $::soft_limit 41903bc525aSdantest_restore_config_pagecache 420c551edc2Sdanielk1977finish_test 42152622828Sdanielk1977catch {db close} 422