]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Reduce the number of mallocs required of writers in server mode.
authordan <dan@noemail.net>
Fri, 28 Jul 2017 21:02:13 +0000 (21:02 +0000)
committerdan <dan@noemail.net>
Fri, 28 Jul 2017 21:02:13 +0000 (21:02 +0000)
FossilOrigin-Name: 60953997f62208f82b1efb53b8a1b0c6a26370411041457f747917e10d9a0e68

manifest
manifest.uuid
src/pager.c
src/server.c
src/server.h
tool/tserver.c

index bcc354d573182f43b1d406a5258436bba5382d22..24090665cf7955e4be5274dd76ee017e7e33cd6b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Update\sthis\sbranch\swith\slatest\schanges\sfrom\strunk.
-D 2017-07-24T19:43:58.292
+C Reduce\sthe\snumber\sof\smallocs\srequired\sof\swriters\sin\sserver\smode.
+D 2017-07-28T21:02:13.200
 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016
@@ -439,7 +439,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
 F src/os_unix.c 98df292b72d8c15c6292be663ee917ac0316a0d9ec652e6e55e06bc4d83f84b7
 F src/os_win.c 2a6c73eef01c51a048cc4ddccd57f981afbec18a
 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
-F src/pager.c bd64887fbd1df4cdc503ccb1c9413ffdb7e7db9fb1dc787e170f3ddb784a0811
+F src/pager.c d3a15bf7861cc9be235ff424cdddde7fae3cd06fbcacbd967c6dad2d313e1d90
 F src/pager.h 857d21f70acefc76e5bae4584f0133e754a2448b197d1e79b7179f26f9a11bc1
 F src/parse.y 3a1babd6645a8103898a5e7e239dcf56cdafbdc25fd8133bb4a9160f9471d42d
 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870
@@ -453,8 +453,8 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20
 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
 F src/select.c c6bf96a7f9d7d68f929de84738c599a30d0a725ab0b54420e70545743cd5ee7b
-F src/server.c 9b76ad62dffa41a9ddaaf23592499b967acae3c210090ba7c3fcbd1484f8389b
-F src/server.h a8477ae61546a9a4c8e06dd31936b06abf18bd086ae6a183ed57f721a3a194b4
+F src/server.c cc07e5ee19436c08ae2331e8476db0c968ade42528df68cfa40eb58314cd21e1
+F src/server.h adcc122084f9370c91479bd9f7bbac1ccd7f63784249de40f63dae8a9fae1bfe
 F src/shell.c bd6a37cbe8bf64ef6a6a74fdc50f067d3148149b4ce2b4d03154663e66ded55f
 F src/shell.c.in b5725acacba95ccefa57b6d068f710e29ba8239c3aa704628a1902a1f729c175
 F src/sqlite.h.in 17faafcb9f410b8140c766c5faf8334da37079ddf4c5054da201071a02190f54
@@ -1618,7 +1618,7 @@ F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
 F tool/symbols.sh c5a617b8c61a0926747a56c65f5671ef8ac0e148
 F tool/tostr.tcl 96022f35ada2194f6f8ccf6fd95809e90ed277c4
-F tool/tserver.c c04e49b7809c01a513df645b7bbaa12a74514e660c491ee753cc0e2573c68512
+F tool/tserver.c b3f368766b6bcef6d58b057de2fc3d3e33510b2b92fd0a53a6bfbe243b58d027
 F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003
 F tool/vdbe-compress.tcl 5926c71f9c12d2ab73ef35c29376e756eb68361c
 F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
@@ -1646,7 +1646,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P e77d29f64480179d7aae7d88adab2ba9ff042701e1f4e624a3a7775cb56a51cc 9a5a3d60a5c6ce23bbdab5832f706bee8acdc4b1767aeed82b1aceb294f050f7
-R 39bfb8b2bfec98e167ee487affa19155
+P d0719ad757bdf7cf2d7d7a4f7b0e713c262ffb434b91ddbb12e190e479abd19e
+R 45df4a0aef3166ba81de04b37f949988
 U dan
-Z 721200f0a7600d1433b52c73bd4b04b3
+Z b12068c542ae27866a718f970ab635de
index 46e3d465fd638ca6e9d59c03fbf4ed59c8316509..4dccf405fb2936a7fd30879cba300cb3a088ded5 100644 (file)
@@ -1 +1 @@
-d0719ad757bdf7cf2d7d7a4f7b0e713c262ffb434b91ddbb12e190e479abd19e
\ No newline at end of file
+60953997f62208f82b1efb53b8a1b0c6a26370411041457f747917e10d9a0e68
\ No newline at end of file
index 3c17b565d54ddf22b05d82c58d31d90db018bfb4..14ec8321b572ca3ad1bf141d30dcfa5c28d11e82 100644 (file)
@@ -5991,9 +5991,12 @@ static SQLITE_NOINLINE int pagerAddPageToRollbackJournal(PgHdr *pPg){
 
 #ifdef SQLITE_SERVER_EDITION
   if( pagerIsServer(pPager) ){
-    int nByte = sizeof(ServerPage) + pPager->pageSize;
-    ServerPage *p = (ServerPage*)sqlite3_malloc(nByte);
-    if( !p ) return SQLITE_NOMEM_BKPT;
+    ServerPage *p = sqlite3ServerBuffer(pPager->pServer);
+    if( p==0 ){
+      int nByte = sizeof(ServerPage) + pPager->pageSize;
+      p = (ServerPage*)sqlite3_malloc(nByte);
+      if( !p ) return SQLITE_NOMEM_BKPT;
+    }
     memset(p, 0, sizeof(ServerPage));
     p->aData = (u8*)&p[1];
     p->nData = pPager->pageSize;
index cb319d966fe045c06bdaad3e08293b7148be4d2b..5632f771bffd8a16334a9b81ba8c25229129f602 100644 (file)
@@ -109,6 +109,8 @@ struct ServerDb {
   ServerPage *pPgFirst;           /* First (oldest) in list of pages */
   ServerPage *pPgLast;            /* Last (newest) in list of pages */
   ServerPage *apPg[HMA_HASH_SIZE];
+
+  ServerPage *pFree;              /* List of free page buffers */
 };
 
 /*
@@ -281,11 +283,16 @@ void sqlite3ServerDisconnect(Server *p, sqlite3_file *dbfd){
   serverEnterMutex();
   pDb->nClient--;
   if( pDb->nClient==0 ){
+    ServerPage *pFree;
     ServerDb **pp;
     serverShutdownDatabase(pDb);
     for(pp=&g_server.pDb; *pp!=pDb; pp=&((*pp)->pNext));
     *pp = pDb->pNext;
     sqlite3_mutex_free(pDb->mutex);
+    while( pFree=pDb->pFree ){
+      pDb->pFree = pFree->pNext;
+      sqlite3_free(pFree);
+    }
     sqlite3_free(pDb);
   }
   serverLeaveMutex();
@@ -409,7 +416,6 @@ int sqlite3ServerEnd(Server *p){
   if( p->eTrans!=SERVER_TRANS_NONE ){
     Server **pp;
     ServerDb *pDb = p->pDb;
-    ServerPage *pFree = 0;
     ServerPage *pPg = 0;
 
     sqlite3_mutex_enter(pDb->mutex);
@@ -437,6 +443,7 @@ int sqlite3ServerEnd(Server *p){
     ** them from the linked list and hash table, but do not call sqlite3_free()
     ** on them until the mutex has been released.  */
     if( pDb->pPgFirst ){
+      ServerPage *pLast = 0;
       Server *pIter;
       int iOldest = 0x7FFFFFFF;
       for(pIter=pDb->pReader; pIter; pIter=pIter->pNext){
@@ -446,7 +453,6 @@ int sqlite3ServerEnd(Server *p){
         iOldest = MIN(iOldest, pIter->iCommitId);
       }
 
-      pFree = pDb->pPgFirst;
       for(pPg=pDb->pPgFirst; pPg && pPg->iCommitId<iOldest; pPg=pPg->pNext){
         if( pPg->pHashPrev ){
           pPg->pHashPrev->pHashNext = pPg->pHashNext;
@@ -458,7 +464,15 @@ int sqlite3ServerEnd(Server *p){
         if( pPg->pHashNext ){
           pPg->pHashNext->pHashPrev = pPg->pHashPrev;
         }
+        pLast = pPg;
+      }
+
+      if( pLast ){
+        assert( pLast->pNext==pPg );
+        pLast->pNext = pDb->pFree;
+        pDb->pFree = pDb->pPgFirst;
       }
+
       if( pPg==0 ){
         pDb->pPgFirst = pDb->pPgLast = 0;
       }else{
@@ -468,14 +482,6 @@ int sqlite3ServerEnd(Server *p){
 
     sqlite3_mutex_leave(pDb->mutex);
 
-    /* Call sqlite3_free() on any pages that were unlinked from the hash
-    ** table above. */
-    while( pFree && pFree!=pPg ){
-      ServerPage *pNext = pFree->pNext;
-      sqlite3_free(pFree);
-      pFree = pNext;
-    }
-
     p->pNext = 0;
     p->eTrans = SERVER_TRANS_NONE;
     p->iTransId = -1;
@@ -672,4 +678,17 @@ void sqlite3ServerEndReadPage(Server *p, Pgno pgno){
   }
 }
 
+ServerPage *sqlite3ServerBuffer(Server *p){
+  ServerDb *pDb = p->pDb;
+  ServerPage *pRet = 0;
+  sqlite3_mutex_enter(pDb->mutex);
+  if( pDb->pFree ){
+    pRet = pDb->pFree;
+    pDb->pFree = pRet->pNext;
+    pRet->pNext = 0;
+  }
+  sqlite3_mutex_leave(pDb->mutex);
+  return pRet;
+}
+
 #endif /* ifdef SQLITE_SERVER_EDITION */
index 8e9ea33fe49c7d75896f3a47995dbcb1d2ee300c..a86bd0a38f04971ce28aa325a5c9d2ebeabf64c5 100644 (file)
@@ -44,6 +44,9 @@ int sqlite3ServerLock(Server *p, Pgno pgno, int bWrite, int bBlock);
 
 int sqlite3ServerHasLock(Server *p, Pgno pgno, int bWrite);
 
+ServerPage *sqlite3ServerBuffer(Server*);
+
+/* For "BEGIN READONLY" clients. */
 void sqlite3ServerReadPage(Server*, Pgno, u8**);
 void sqlite3ServerEndReadPage(Server*, Pgno);
 
index 8275b237794c07f18acca26c56e2c48ff3e89502..ba44f0df3c77f9f89b6d0e556d61d0fcc1214358 100644 (file)
@@ -63,6 +63,8 @@
 /* Database used by this server */
 static char *zDatabaseName = 0;
 
+static char *zGlobalVfs = 0;
+
 typedef struct ClientCtx ClientCtx;
 struct ClientCtx {
   sqlite3 *db;                    /* Database handle for this client */
@@ -299,7 +301,9 @@ static void *handle_client(void *pArg){
 
   ctx.fd = (int)(intptr_t)pArg;
   ctx.nRepeat = 1;
-  rc = sqlite3_open(zDatabaseName, &ctx.db);
+  rc = sqlite3_open_v2(zDatabaseName, &ctx.db,
+      SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zGlobalVfs
+  );
   if( rc!=SQLITE_OK ){
     fprintf(stderr, "sqlite3_open(): %s\n", sqlite3_errmsg(ctx.db));
     return 0;
@@ -380,6 +384,11 @@ static void *handle_client(void *pArg){
   return 0;
 } 
 
+static void usage(const char *zExec){
+  fprintf(stderr, "Usage: %s ?-vfs VFS? DATABASE\n", zExec);
+  exit(1);
+}
+
 int main(int argc, char *argv[]) {
   sqlite3 *db;
   int sfd;
@@ -391,13 +400,19 @@ int main(int argc, char *argv[]) {
   ** abruptly.  */
   signal(SIGPIPE, SIG_IGN);
 
-  if( argc!=2 ){
-    fprintf(stderr, "Usage: %s DATABASE\n", argv[0]);
-    return 1;
+  if( argc!=2 && argc!=4 ){
+    usage(argv[0]);
+  }
+  if( argc==4 ){
+    int n = strlen(argv[1]);
+    if( n<2 || n>4 || memcmp("-vfs", argv[1], 4) ) usage(argv[0]);
+    zGlobalVfs = argv[2];
   }
-  zDatabaseName = argv[1];
+  zDatabaseName = argv[argc-1];
 
-  rc = sqlite3_open(zDatabaseName, &db);
+  rc = sqlite3_open_v2(zDatabaseName, &db,
+      SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zGlobalVfs
+  );
   if( rc!=SQLITE_OK ){
     fprintf(stderr, "sqlite3_open(): %s\n", sqlite3_errmsg(db));
     return 1;