Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch winMmapNoWal Excluding Merge-Ins
This is equivalent to a diff from d423349d2c to 6fc4ead26d
2014-11-05
| ||
21:34 | Fixes to the Windows VFS to allow memory mapped files to work without WAL support. (check-in: 272fddc14c user: drh tags: trunk) | |
2014-11-04
| ||
21:38 | Improved output formatting for the showstat4 tool. (check-in: 7df82c46da user: drh tags: trunk) | |
19:52 | Skip tests that require WAL mode when it is not enabled. (Closed-Leaf check-in: 6fc4ead26d user: mistachkin tags: winMmapNoWal) | |
19:37 | For the Win32 VFS, allow memory mapped files to work when compiled without WAL support. (check-in: 1fc7e2f3d3 user: mistachkin tags: winMmapNoWal) | |
17:23 | Add various requirements evidence marks for sqlite3_config() options. (check-in: d423349d2c user: drh tags: trunk) | |
14:22 | Change the definition of SQLITE_CONFIG_SCRATCH so that at most one scratch buffer is used per thread. Use the generic heap memory allocator for the WalIterator object when running a checkpoint. (check-in: 391c9b85ab user: drh tags: trunk) | |
Changes to src/os_win.c.
30 30 ** available in Windows platforms based on the NT kernel. 31 31 */ 32 32 #if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL) 33 33 # error "WAL mode requires support from the Windows NT kernel, compile\ 34 34 with SQLITE_OMIT_WAL." 35 35 #endif 36 36 37 +#if !SQLITE_OS_WINNT && SQLITE_MAX_MMAP_SIZE>0 38 +# error "Memory mapped files require support from the Windows NT kernel,\ 39 + compile with SQLITE_MAX_MMAP_SIZE=0." 40 +#endif 41 + 37 42 /* 38 43 ** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions 39 44 ** based on the sub-platform)? 40 45 */ 41 46 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(SQLITE_WIN32_NO_ANSI) 42 47 # define SQLITE_WIN32_HAS_ANSI 43 48 #endif ................................................................................ 159 164 */ 160 165 #ifndef winGetDirSep 161 166 # define winGetDirSep() '\\' 162 167 #endif 163 168 164 169 /* 165 170 ** Do we need to manually define the Win32 file mapping APIs for use with WAL 166 -** mode (e.g. these APIs are available in the Windows CE SDK; however, they 167 -** are not present in the header file)? 171 +** mode or memory mapped files (e.g. these APIs are available in the Windows 172 +** CE SDK; however, they are not present in the header file)? 168 173 */ 169 -#if SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL) 174 +#if SQLITE_WIN32_FILEMAPPING_API && \ 175 + (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) 170 176 /* 171 177 ** Two of the file mapping APIs are different under WinRT. Figure out which 172 178 ** set we need. 173 179 */ 174 180 #if SQLITE_OS_WINRT 175 181 WINBASEAPI HANDLE WINAPI CreateFileMappingFromApp(HANDLE, \ 176 182 LPSECURITY_ATTRIBUTES, ULONG, ULONG64, LPCWSTR); ................................................................................ 190 196 WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T); 191 197 #endif /* SQLITE_OS_WINRT */ 192 198 193 199 /* 194 200 ** This file mapping API is common to both Win32 and WinRT. 195 201 */ 196 202 WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID); 197 -#endif /* SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL) */ 203 +#endif /* SQLITE_WIN32_FILEMAPPING_API */ 198 204 199 205 /* 200 206 ** Some Microsoft compilers lack this definition. 201 207 */ 202 208 #ifndef INVALID_FILE_ATTRIBUTES 203 209 # define INVALID_FILE_ATTRIBUTES ((DWORD)-1) 204 210 #endif ................................................................................ 483 489 { "CreateFileW", (SYSCALL)0, 0 }, 484 490 #endif 485 491 486 492 #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ 487 493 LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) 488 494 489 495 #if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \ 490 - !defined(SQLITE_OMIT_WAL)) 496 + (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)) 491 497 { "CreateFileMappingA", (SYSCALL)CreateFileMappingA, 0 }, 492 498 #else 493 499 { "CreateFileMappingA", (SYSCALL)0, 0 }, 494 500 #endif 495 501 496 502 #define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ 497 503 DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent) 498 504 499 505 #if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ 500 - !defined(SQLITE_OMIT_WAL)) 506 + (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)) 501 507 { "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 }, 502 508 #else 503 509 { "CreateFileMappingW", (SYSCALL)0, 0 }, 504 510 #endif 505 511 506 512 #define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ 507 513 DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent) ................................................................................ 833 839 #endif 834 840 835 841 #ifndef osLockFileEx 836 842 #define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \ 837 843 LPOVERLAPPED))aSyscall[48].pCurrent) 838 844 #endif 839 845 840 -#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)) 846 +#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && \ 847 + (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)) 841 848 { "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 }, 842 849 #else 843 850 { "MapViewOfFile", (SYSCALL)0, 0 }, 844 851 #endif 845 852 846 853 #define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ 847 854 SIZE_T))aSyscall[49].pCurrent) ................................................................................ 903 910 #else 904 911 { "UnlockFileEx", (SYSCALL)0, 0 }, 905 912 #endif 906 913 907 914 #define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ 908 915 LPOVERLAPPED))aSyscall[58].pCurrent) 909 916 910 -#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) 917 +#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 911 918 { "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 }, 912 919 #else 913 920 { "UnmapViewOfFile", (SYSCALL)0, 0 }, 914 921 #endif 915 922 916 923 #define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent) 917 924 ................................................................................ 966 973 #else 967 974 { "GetFileInformationByHandleEx", (SYSCALL)0, 0 }, 968 975 #endif 969 976 970 977 #define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \ 971 978 FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent) 972 979 973 -#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL) 980 +#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) 974 981 { "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 }, 975 982 #else 976 983 { "MapViewOfFileFromApp", (SYSCALL)0, 0 }, 977 984 #endif 978 985 979 986 #define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \ 980 987 SIZE_T))aSyscall[67].pCurrent) ................................................................................ 1030 1037 1031 1038 #define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent) 1032 1039 1033 1040 { "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 }, 1034 1041 1035 1042 #define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent) 1036 1043 1037 -#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL) 1044 +#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) 1038 1045 { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 }, 1039 1046 #else 1040 1047 { "CreateFileMappingFromApp", (SYSCALL)0, 0 }, 1041 1048 #endif 1042 1049 1043 1050 #define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \ 1044 1051 LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)
Changes to test/mmap1.test.
29 29 } 30 30 31 31 proc register_rblob_code {dbname seed} { 32 32 return [subst -nocommands { 33 33 set ::rcnt $seed 34 34 proc rblob {n} { 35 35 set ::rcnt [expr (([set ::rcnt] << 3) + [set ::rcnt] + 456) & 0xFFFFFFFF] 36 - set str [format %.8x [expr [set ::rcnt] ^ 0xbdf20da3]] 36 + set str [format %.8x [expr [set ::rcnt] ^ 0xbdf20da3]] 37 37 string range [string repeat [set str] [expr [set n]/4]] 1 [set n] 38 38 } 39 39 $dbname func rblob rblob 40 40 }] 41 41 } 42 42 43 43 # For cases 1.1 and 1.4, the number of pages read using xRead() is 4 on 44 44 # unix and 9 on windows. The difference is that windows only ever maps 45 -# an integer number of OS pages (i.e. creates mappings that are a multiple 45 +# an integer number of OS pages (i.e. creates mappings that are a multiple 46 46 # of 4KB in size). Whereas on unix any sized mapping may be created. 47 47 # 48 48 foreach {t mmap_size nRead c2init} { 49 49 1.1 { PRAGMA mmap_size = 67108864 } /[49]/ {PRAGMA mmap_size = 0} 50 50 1.2 { PRAGMA mmap_size = 53248 } 150 {PRAGMA mmap_size = 0} 51 51 1.3 { PRAGMA mmap_size = 0 } 344 {PRAGMA mmap_size = 0} 52 52 1.4 { PRAGMA mmap_size = 67108864 } /[49]/ {PRAGMA mmap_size = 67108864 } ................................................................................ 102 102 do_test $t.$tn.5 { nRead db } $nRead 103 103 } 104 104 } 105 105 106 106 set ::rcnt 0 107 107 proc rblob {n} { 108 108 set ::rcnt [expr (($::rcnt << 3) + $::rcnt + 456) & 0xFFFFFFFF] 109 - set str [format %.8x [expr $::rcnt ^ 0xbdf20da3]] 109 + set str [format %.8x [expr $::rcnt ^ 0xbdf20da3]] 110 110 string range [string repeat $str [expr $n/4]] 1 $n 111 111 } 112 112 113 113 reset_db 114 114 db func rblob rblob 115 115 116 -do_execsql_test 2.1 { 117 - PRAGMA auto_vacuum = 1; 118 - PRAGMA mmap_size = 67108864; 119 - PRAGMA journal_mode = wal; 120 - CREATE TABLE t1(a, b, UNIQUE(a, b)); 121 - INSERT INTO t1 VALUES(rblob(500), rblob(500)); 122 - INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 2 123 - INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 4 124 - INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 8 125 - INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 16 126 - INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 32 127 - PRAGMA wal_checkpoint; 128 -} {67108864 wal 0 103 103} 129 - 130 -do_execsql_test 2.2 { 131 - PRAGMA auto_vacuum; 132 - SELECT count(*) FROM t1; 133 -} {1 32} 134 - 135 -if {[permutation] != "inmemory_journal"} { 136 - do_test 2.3 { 137 - sqlite3 db2 test.db 138 - db2 func rblob rblob 139 - db2 eval { 140 - DELETE FROM t1 WHERE (rowid%4); 141 - PRAGMA wal_checkpoint; 142 - } 143 - db2 eval { 144 - INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 16 145 - SELECT count(*) FROM t1; 146 - } 147 - } {16} 148 - 149 - do_execsql_test 2.4 { 116 +ifcapable wal { 117 + do_execsql_test 2.1 { 118 + PRAGMA auto_vacuum = 1; 119 + PRAGMA mmap_size = 67108864; 120 + PRAGMA journal_mode = wal; 121 + CREATE TABLE t1(a, b, UNIQUE(a, b)); 122 + INSERT INTO t1 VALUES(rblob(500), rblob(500)); 123 + INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 2 124 + INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 4 125 + INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 8 126 + INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 16 127 + INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 32 150 128 PRAGMA wal_checkpoint; 151 - } {0 24 24} 152 - db2 close 129 + } {67108864 wal 0 103 103} 130 + 131 + do_execsql_test 2.2 { 132 + PRAGMA auto_vacuum; 133 + SELECT count(*) FROM t1; 134 + } {1 32} 135 + 136 + if {[permutation] != "inmemory_journal"} { 137 + do_test 2.3 { 138 + sqlite3 db2 test.db 139 + db2 func rblob rblob 140 + db2 eval { 141 + DELETE FROM t1 WHERE (rowid%4); 142 + PRAGMA wal_checkpoint; 143 + } 144 + db2 eval { 145 + INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; -- 16 146 + SELECT count(*) FROM t1; 147 + } 148 + } {16} 149 + 150 + do_execsql_test 2.4 { 151 + PRAGMA wal_checkpoint; 152 + } {0 24 24} 153 + db2 close 154 + } 153 155 } 154 156 155 157 reset_db 156 158 execsql { PRAGMA mmap_size = 67108864; } 157 159 db func rblob rblob 158 160 do_execsql_test 3.1 { 159 161 PRAGMA auto_vacuum = 1; ................................................................................ 223 225 do_test 4.4 { 224 226 sqlite3_finalize $::STMT 225 227 } SQLITE_OK 226 228 227 229 do_execsql_test 4.5 { COMMIT } 228 230 229 231 #------------------------------------------------------------------------- 230 -# Ensure that existing cursors holding xFetch() references are not 232 +# Ensure that existing cursors holding xFetch() references are not 231 233 # confused if those pages are moved to make way for the root page of a 232 234 # new table or index. 233 235 # 234 236 reset_db 235 237 execsql { PRAGMA mmap_size = 67108864; } 236 238 do_execsql_test 5.1 { 237 239 PRAGMA auto_vacuum = 2; ................................................................................ 292 294 293 295 code1 [register_rblob_code db 0] 294 296 code2 [register_rblob_code db2 444] 295 297 296 298 sql1 "PRAGMA mmap_size = $mmap1" 297 299 sql2 "PRAGMA mmap_size = $mmap2" 298 300 299 - do_test $tn1.$tn { 301 + do_test $tn1.$tn { 300 302 for {set i 1} {$i <= 100} {incr i} { 301 303 if {$i % 2} { 302 304 set c1 sql1 303 305 set c2 sql2 304 306 } else { 305 307 set c1 sql2 306 308 set c2 sql1 ................................................................................ 307 309 } 308 310 309 311 $c1 { 310 312 INSERT INTO t1 VALUES( rblob(5000) ); 311 313 UPDATE t2 SET x = (SELECT md5sum(a) FROM t1); 312 314 } 313 315 314 - set res [$c2 { 316 + set res [$c2 { 315 317 SELECT count(*) FROM t1; 316 318 SELECT x == (SELECT md5sum(a) FROM t1) FROM t2; 317 319 PRAGMA integrity_check; 318 320 }] 319 321 if {$res != [list $i 1 ok]} { 320 322 do_test $tn1.$tn.$i { 321 323 set ::res