From: mistachkin Date: Thu, 8 May 2014 22:01:26 +0000 (+0000) Subject: Experimental changes to pre-cache a database file prior to it being fully opened. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=83dca19e9f72277f9da7f6efa2c821e38a94596c;p=thirdparty%2Fsqlite.git Experimental changes to pre-cache a database file prior to it being fully opened. FossilOrigin-Name: 38cbcedbb6e57dc3c2d452a0eb573cabc7df0c75 --- diff --git a/manifest b/manifest index 4aa2464bf2..299b6943cd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 @@ -205,7 +205,7 @@ F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace 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 @@ -1171,7 +1171,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 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 diff --git a/manifest.uuid b/manifest.uuid index 80fca0f480..3e3fe47c08 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a41d29691307067523c8637b486941c5f7c33775 \ No newline at end of file +38cbcedbb6e57dc3c2d452a0eb573cabc7df0c75 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 10fea2638c..95eb7357a4 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -267,6 +267,7 @@ struct winFile { 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 */ }; /* @@ -1044,6 +1045,11 @@ static struct win_syscall { #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 */ /* @@ -2354,6 +2360,13 @@ static int winClose(sqlite3_file *id){ 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 @@ -3198,6 +3211,78 @@ static int winDeviceCharacteristics(sqlite3_file *id){ ((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( dwSizelastErrno = 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( nReadlastErrno, + "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. @@ -4704,6 +4789,15 @@ static int winOpen( 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; @@ -5422,7 +5516,7 @@ int sqlite3_os_init(void){ /* 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));