-C Fix\sstatic\svariable\sdeclaration\sissue\son\sWindows.
-D 2014-05-08T22:01:08.441
+C Experimental\schanges\sto\spre-cache\sa\sdatabase\sfile\sprior\sto\sit\sbeing\sfully\sopened.
+D 2014-05-08T22:01:26.332
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in ad0921c4b2780d01868cf69b419a4f102308d125
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_unix.c ae4b5240af4619d711301d7992396e182585269f
-F src/os_win.c 187fad4d385b3b26ec6fd4b703b1b087ad6a5c4d
+F src/os_win.c 70e5fd4b931d9e4ed2395683503cc253be705192
F src/pager.c ab62a24218d87dda1be641f6c5ad291bff78fd94
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 7de6aee6a5cb5c7f89dced89f2ebf38f8be7a4fa
-R 117bf7d69b405485b3cb8ed74140d14c
+P a41d29691307067523c8637b486941c5f7c33775
+R deeebf5d0a3a3431a16dc9cbda6dc0e2
+T *branch * winPreCache
+T *sym-winPreCache *
+T -sym-threads *
U mistachkin
-Z 6be3c46bf656f034e9d870a5f4b03d3e
+Z 18b582a9491b79449552acaadfabfb63
sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */
sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */
#endif
+ SQLiteThread *preCacheThread; /* Thread used to pre-cache file contents */
};
/*
#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)
+ { "DuplicateHandle", (SYSCALL)DuplicateHandle, 0 },
+
+#define osDuplicateHandle ((BOOL(WINAPI*)(HANDLE, \
+ HANDLE,HANDLE,LPHANDLE,DWORD,BOOL,DWORD))aSyscall[76].pCurrent)
+
}; /* End of the overrideable system calls */
/*
assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
OSTRACE(("CLOSE file=%p\n", pFile->h));
+#if SQLITE_MAX_WORKER_THREADS>0
+ if( pFile->preCacheThread ){
+ void *pOut = 0;
+ sqlite3ThreadJoin(pFile->preCacheThread, &pOut);
+ }
+#endif
+
#if SQLITE_MAX_MMAP_SIZE>0
winUnmapfile(pFile);
#endif
((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0);
}
+/*
+** Thread routine that seeks to the end of an open file and reads one byte.
+** This is used to provide a hint to the operating system that the entire
+** file should be held in the cache.
+*/
+static void *winPreCacheThread(void *pCtx){
+ winFile *pFile = (winFile*)pCtx;
+ void *pBuf = 0;
+ DWORD lastErrno;
+ HANDLE dupHandle = NULL;
+ DWORD dwSize, dwRet;
+ DWORD dwAmt;
+ DWORD nRead;
+
+ if( !osDuplicateHandle(GetCurrentProcess(), pFile->h, GetCurrentProcess(),
+ &dupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS) ){
+ pFile->lastErrno = osGetLastError();
+ OSTRACE(("PRE-CACHE file=%p, rc=SQLITE_IOERR\n", dupHandle));
+ return winLogError(SQLITE_IOERR, pFile->lastErrno,
+ "winPreCacheThread1", pFile->zPath);
+ }
+ dwSize = osSetFilePointer(dupHandle, 0, 0, FILE_END);
+ if( (dwSize==INVALID_SET_FILE_POINTER
+ && ((lastErrno = osGetLastError())!=NO_ERROR)) ){
+ pFile->lastErrno = lastErrno;
+ osCloseHandle(dupHandle);
+ OSTRACE(("PRE-CACHE file=%p, rc=SQLITE_IOERR_SEEK\n", dupHandle));
+ return winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
+ "winPreCacheThread2", pFile->zPath);
+ }
+ dwRet = osSetFilePointer(dupHandle, 0, 0, FILE_BEGIN);
+ if( (dwRet==INVALID_SET_FILE_POINTER
+ && ((lastErrno = osGetLastError())!=NO_ERROR)) ){
+ pFile->lastErrno = lastErrno;
+ osCloseHandle(dupHandle);
+ OSTRACE(("PRE-CACHE file=%p, rc=SQLITE_IOERR_SEEK\n", dupHandle));
+ return winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
+ "winPreCacheThread2", pFile->zPath);
+ }
+ dwAmt = 4194304; /* TODO: Tuning. */
+ if( dwSize<dwAmt ){
+ dwAmt = dwSize;
+ }
+ pBuf = sqlite3MallocZero( dwAmt );
+ if( pBuf==0 ){
+ osCloseHandle(dupHandle);
+ OSTRACE(("PRE-CACHE file=%p, rc=SQLITE_IOERR_NOMEM\n", dupHandle));
+ return SQLITE_IOERR_NOMEM;
+ }
+ while( 1 ){
+ if( !osReadFile(dupHandle, pBuf, dwAmt, &nRead, 0) ){
+ pFile->lastErrno = osGetLastError();
+ osCloseHandle(dupHandle);
+ OSTRACE(("PRE-CACHE file=%p, rc=SQLITE_IOERR_READ\n", dupHandle));
+ return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
+ "winPreCacheThread3", pFile->zPath);
+ }
+ if( nRead<dwAmt ){
+ osCloseHandle(dupHandle);
+ OSTRACE(("PRE-CACHE file=%p, rc=SQLITE_IOERR_SHORT_READ\n", dupHandle));
+ return winLogError(SQLITE_IOERR_SHORT_READ, pFile->lastErrno,
+ "winPreCacheThread4", pFile->zPath);
+ }
+ dwSize -= dwAmt;
+ if( dwSize==0 ){
+ break;
+ }
+ }
+ osCloseHandle(dupHandle);
+ return SQLITE_OK;
+}
+
/*
** Windows will only let you create file view mappings
** on allocation size granularity boundaries.
pFile->mmapSizeActual = 0;
pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap;
#endif
+#if SQLITE_MAX_WORKER_THREADS>0
+ sqlite3ThreadCreate(&pFile->preCacheThread, winPreCacheThread, pFile);
+
+ {
+ void *pOut = 0;
+ sqlite3ThreadJoin(pFile->preCacheThread, &pOut);
+ pFile->preCacheThread = 0;
+ }
+#endif
OpenCounter(+1);
return rc;
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
- assert( ArraySize(aSyscall)==76 );
+ assert( ArraySize(aSyscall)==77 );
/* get memory map allocation granularity */
memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));