]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Experimental changes to pre-cache a database file prior to it being fully opened.
authormistachkin <mistachkin@noemail.net>
Thu, 8 May 2014 22:01:26 +0000 (22:01 +0000)
committermistachkin <mistachkin@noemail.net>
Thu, 8 May 2014 22:01:26 +0000 (22:01 +0000)
FossilOrigin-Name: 38cbcedbb6e57dc3c2d452a0eb573cabc7df0c75

manifest
manifest.uuid
src/os_win.c

index 4aa2464bf23b6ff91bc589088a9a24226074f42d..299b6943cd839f391f83c894266b7cf4041d02b5 100644 (file)
--- 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
index 80fca0f480bc7c102e071a05afcd5d6290cf529f..3e3fe47c08e8291e2ddba86634e6cad204dd059c 100644 (file)
@@ -1 +1 @@
-a41d29691307067523c8637b486941c5f7c33775
\ No newline at end of file
+38cbcedbb6e57dc3c2d452a0eb573cabc7df0c75
\ No newline at end of file
index 10fea2638ca00d7e1d848e42a2be535412239c66..95eb7357a4b8909e24b6c392ffe33399555bf536 100644 (file)
@@ -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( 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.
@@ -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));