1: # 2008 June 18
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 tests of the memory allocation subsystem
13: #
14:
15: set testdir [file dirname $argv0]
16: source $testdir/tester.tcl
17: sqlite3_reset_auto_extension
18:
19: # This test assumes that no page-cache or scratch buffers are installed
20: # by default when a new database connection is opened. As a result, it
21: # will not work with the "memsubsys1" permutation.
22: #
23: if {[permutation] == "memsubsys1"} {
24: finish_test
25: return
26: }
27:
28: # This procedure constructs a new database in test.db. It fills
29: # this database with many small records (enough to force multiple
30: # rebalance operations in the btree-layer and to require a large
31: # page cache), verifies correct results, then returns.
32: #
33: proc build_test_db {testname pragmas} {
34: catch {db close}
35: forcedelete test.db test.db-journal
36: sqlite3 db test.db
37: sqlite3_db_config_lookaside db 0 0 0
38: db eval $pragmas
39: db eval {
40: CREATE TABLE t1(x, y);
41: CREATE TABLE t2(a, b);
42: CREATE INDEX i1 ON t1(x,y);
43: INSERT INTO t1 VALUES(1, 100);
44: INSERT INTO t1 VALUES(2, 200);
45: }
46: for {set i 2} {$i<5000} {incr i $i} {
47: db eval {INSERT INTO t2 SELECT * FROM t1}
48: db eval {INSERT INTO t1 SELECT a+$i, a+b*100 FROM t2}
49: db eval {DELETE FROM t2}
50: }
51: do_test $testname.1 {
52: db eval {SELECT count(*) FROM t1}
53: } 8192
54: integrity_check $testname.2
55: }
56:
57: # Reset all of the highwater marks.
58: #
59: proc reset_highwater_marks {} {
60: sqlite3_status SQLITE_STATUS_MEMORY_USED 1
61: sqlite3_status SQLITE_STATUS_MALLOC_SIZE 1
62: sqlite3_status SQLITE_STATUS_PAGECACHE_USED 1
63: sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 1
64: sqlite3_status SQLITE_STATUS_PAGECACHE_SIZE 1
65: sqlite3_status SQLITE_STATUS_SCRATCH_USED 1
66: sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 1
67: sqlite3_status SQLITE_STATUS_SCRATCH_SIZE 1
68: sqlite3_status SQLITE_STATUS_PARSER_STACK 1
69: }
70:
71: set xtra_size 290
72:
73: # Test 1: Both PAGECACHE and SCRATCH are shut down.
74: #
75: db close
76: sqlite3_shutdown
77: sqlite3_config_lookaside 0 0
78: sqlite3_initialize
79: reset_highwater_marks
80: build_test_db memsubsys1-1 {PRAGMA page_size=1024}
81: do_test memsubsys1-1.3 {
82: set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
83: } 0
84: do_test memsubsys1-1.4 {
85: set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
86: } 0
87: set max_pagecache [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
88: #show_memstats
89:
90: # Test 2: Activate PAGECACHE with 20 pages
91: #
92: db close
93: sqlite3_shutdown
94: sqlite3_config_pagecache [expr 1024+$xtra_size] 20
95: sqlite3_initialize
96: reset_highwater_marks
97: build_test_db memsubsys1-2 {PRAGMA page_size=1024}
98: #show_memstats
99: set MEMORY_MANAGEMENT $sqlite_options(memorymanage)
100: ifcapable !malloc_usable_size {
101: do_test memsubsys1-2.3 {
102: set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
103: } [expr ($TEMP_STORE>1 || $MEMORY_MANAGEMENT==0)*1024]
104: }
105: do_test memsubsys1-2.4 {
106: set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
107: } 20
108: do_test memsubsys1-2.5 {
109: set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
110: } 0
111:
112: # Test 3: Activate PAGECACHE with 20 pages but use the wrong page size
113: # so that PAGECACHE is not used.
114: #
115: db close
116: sqlite3_shutdown
117: sqlite3_config_pagecache [expr 512+$xtra_size] 20
118: sqlite3_initialize
119: reset_highwater_marks
120: build_test_db memsubsys1-3.1 {PRAGMA page_size=1024}
121: #show_memstats
122: do_test memsubsys1-3.1.3 {
123: set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
124: } 0
125: do_test memsubsys1-3.1.4 {
126: set overflow [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
127: } $max_pagecache
128: do_test memsubsys1-3.1.5 {
129: set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
130: } 0
131: db close
132: sqlite3_shutdown
133: sqlite3_config_pagecache [expr 2048+$xtra_size] 20
134: sqlite3_initialize
135: reset_highwater_marks
136: build_test_db memsubsys1-3.2 {PRAGMA page_size=2048}
137: #show_memstats
138: do_test memsubsys1-3.2.3 {
139: db eval {PRAGMA page_size}
140: } 2048
141: do_test memsubsys1-3.2.4 {
142: set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
143: } 20
144: do_test memsubsys1-3.2.5 {
145: set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
146: } 0
147:
148: # Test 4: Activate both PAGECACHE and SCRATCH.
149: #
150: db close
151: sqlite3_shutdown
152: sqlite3_config_pagecache [expr 1024+$xtra_size] 50
153: sqlite3_config_scratch 6000 2
154: sqlite3_initialize
155: reset_highwater_marks
156: build_test_db memsubsys1-4 {PRAGMA page_size=1024}
157: #show_memstats
158: do_test memsubsys1-4.3 {
159: set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
160: expr {$pg_used>=45 && $pg_used<=50}
161: } 1
162: do_test memsubsys1-4.4 {
163: set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
164: } 0
165: do_test memsubsys1-4.5 {
166: set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
167: expr {$maxreq<7000}
168: } 1
169: do_test memsubsys1-4.6 {
170: set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
171: } 1
172:
173: # Test 5: Activate both PAGECACHE and SCRATCH. But make the page size
174: # such that the SCRATCH allocations are too small.
175: #
176: db close
177: sqlite3_shutdown
178: sqlite3_config_pagecache [expr 4096+$xtra_size] 24
179: sqlite3_config_scratch 6000 2
180: sqlite3_initialize
181: reset_highwater_marks
182: build_test_db memsubsys1-5 {PRAGMA page_size=4096}
183: #show_memstats
184: do_test memsubsys1-5.3 {
185: set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
186: } 24
187: do_test memsubsys1-5.4 {
188: set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
189: expr {$maxreq>4096}
190: } 1
191: do_test memsubsys1-5.5 {
192: set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
193: } 0
194: do_test memsubsys1-5.6 {
195: set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]
196: expr {$s_ovfl>6000}
197: } 1
198:
199: # Test 6: Activate both PAGECACHE and SCRATCH with a 4k page size.
200: # Make it so that SCRATCH is large enough
201: #
202: db close
203: sqlite3_shutdown
204: sqlite3_config_pagecache [expr 4096+$xtra_size] 24
205: sqlite3_config_scratch 25300 1
206: sqlite3_initialize
207: reset_highwater_marks
208: build_test_db memsubsys1-6 {PRAGMA page_size=4096}
209: #show_memstats
210: do_test memsubsys1-6.3 {
211: set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
212: } 24
213: #do_test memsubsys1-6.4 {
214: # set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
215: # expr {$maxreq>4096 && $maxreq<=(4096+$xtra_size)}
216: #} 1
217: do_test memsubsys1-6.5 {
218: set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
219: } 1
220: do_test memsubsys1-6.6 {
221: set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]
222: } 0
223:
224: # Test 7: Activate both PAGECACHE and SCRATCH with a 4k page size.
225: # Set cache_size small so that no PAGECACHE overflow occurs. Verify
226: # that maximum allocation size is small.
227: #
228: db close
229: sqlite3_shutdown
230: sqlite3_config_pagecache [expr 4096+$xtra_size] 24
231: sqlite3_config_scratch 25300 1
232: sqlite3_initialize
233: reset_highwater_marks
234: build_test_db memsubsys1-7 {
235: PRAGMA page_size=4096;
236: PRAGMA cache_size=10;
237: PRAGMA temp_store=memory;
238: }
239: #show_memstats
240: do_test memsubsys1-7.3 {
241: set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
242: expr {$pg_used<24}
243: } 1
244: do_test memsubsys1-7.4 {
245: set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
246: } 0
247: do_test memsubsys1-7.5 {
248: set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
249: expr {$maxreq<4100}
250: } 1
251: do_test memsubsys1-7.6 {
252: set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
253: } 1
254: do_test memsubsys1-7.7 {
255: set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]
256: } 0
257:
258: # Test 8: Disable PAGECACHE. Make available SCRATCH zero. Verify that
259: # the SCRATCH overflow logic works.
260: #
261: db close
262: sqlite3_shutdown
263: sqlite3_config_pagecache 0 0
264: sqlite3_config_scratch 25000 0
265: sqlite3_initialize
266: reset_highwater_marks
267: do_test memsubsys1-8.1 {
268: set pg_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
269: } 0
270: do_test memsubsys1-8.2 {
271: set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]
272: } 0
273: do_test memsubsys1-8.3 {
274: sqlite3 db :memory:
275: db eval {
276: CREATE TABLE t1(x);
277: INSERT INTO t1 VALUES(zeroblob(400));
278: INSERT INTO t1 VALUES(zeroblob(400));
279: INSERT INTO t1 SELECT * FROM t1;
280: INSERT INTO t1 SELECT * FROM t1;
281: INSERT INTO t1 SELECT * FROM t1;
282: }
283: expr {[lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]>0}
284: } 1
285: db close
286: sqlite3_shutdown
287: sqlite3_config_memstatus 0
288: sqlite3_initialize
289: do_test memsubsys1-8.4 {
290: sqlite3 db :memory:
291: db eval {
292: CREATE TABLE t1(x);
293: INSERT INTO t1 VALUES(zeroblob(400));
294: INSERT INTO t1 VALUES(zeroblob(400));
295: INSERT INTO t1 SELECT * FROM t1;
296: INSERT INTO t1 SELECT * FROM t1;
297: INSERT INTO t1 SELECT * FROM t1;
298: SELECT rowid FROM t1;
299: }
300: } {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16}
301:
302:
303: db close
304: sqlite3_shutdown
305: sqlite3_config_memstatus 1
306: sqlite3_config_pagecache 0 0
307: sqlite3_config_scratch 0 0
308: sqlite3_config_lookaside 100 500
309: sqlite3_initialize
310: autoinstall_test_functions
311: finish_test
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>