]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
If it is known that checksums will be recalculated on transaction commit, skip calcul...
authordan <dan@noemail.net>
Sat, 9 Jan 2016 18:57:35 +0000 (18:57 +0000)
committerdan <dan@noemail.net>
Sat, 9 Jan 2016 18:57:35 +0000 (18:57 +0000)
FossilOrigin-Name: 16b34f2537bbc7846d8e6dc2b35daae5af241c1b

manifest
manifest.uuid
src/wal.c

index 929a82b2bd62d2705d69c856a578e4a1964b8a9b..0d9cd208915490ee5430d86f0f19aba3d4ec41de 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C If\sa\ssingle\spage\sis\swritten\sto\sthe\swal\sfile\smore\sthan\sonce,\shave\seach\ssubsequent\scopy\soverwrite\sthe\soriginal\sframe.
-D 2016-01-09T16:39:29.213
+C If\sit\sis\sknown\sthat\schecksums\swill\sbe\srecalculated\son\stransaction\scommit,\sskip\scalculating\schecksums\swhen\sappending\sframes\sto\sthe\swal\sfile.\sWhen\srecalculating\schecksums,\srecalculate\sthem\sstarting\swith\sthe\sfirst\soverwritten\sframe\s-\snot\sthe\sfirst\sframe\sin\sthe\stransaction.
+D 2016-01-09T18:57:35.280
 F Makefile.in 7c8cc4c2f0179efc6fa9492141d1fb65f4807054
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc e45d8b9b56dfa3f2cd860b2c28bd9d304513b042
@@ -409,7 +409,7 @@ F src/vdbesort.c a7ec02da4494c59dfd071126dd3726be5a11459d
 F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0
 F src/vtab.c 2a8b44aa372c33f6154208e7a7f6c44254549806
 F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
-F src/wal.c 88661c24c86d88e40560c0be5df39d902502a29a
+F src/wal.c 38ca0c41b510b636dfada0801fad8a99a982dfa6
 F src/wal.h 907943dfdef10b583e81906679a347e0ec6f1b1b
 F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
 F src/where.c c6d3d2f6af57d574a7365ee2b225a5024f2a6bec
@@ -1407,10 +1407,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 52c166039831cc8423e2252019ef64a21b9d7c2a
-R 7ec438cc7bd0e0a87d33dca3e9bb783a
-T *branch * wal-overwrite-frames
-T *sym-wal-overwrite-frames *
-T -sym-trunk *
+P 5d113aef2c7d746e8eda88d4e36c04a39b0a11be
+R 68fe235d45cc69355e6b4ad2de6e1633
 U dan
-Z eba50524221f3f22640b286e867693f1
+Z 339ef03cecb2ba4cae1a0043b973d562
index 2b25ead966a14faf4dbe83043e744fe2598d844c..44ce854f87609d4d722ec0a07e0729d70cc84419 100644 (file)
@@ -1 +1 @@
-5d113aef2c7d746e8eda88d4e36c04a39b0a11be
\ No newline at end of file
+16b34f2537bbc7846d8e6dc2b35daae5af241c1b
\ No newline at end of file
index c900879d121ed6bdbeea1a1c6aec57688eeb46df..d3e2908ba15c52fd7f6718ea810d273353b43fd4 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -445,6 +445,7 @@ struct Wal {
   u8 padToSectorBoundary;    /* Pad transactions out to the next sector */
   WalIndexHdr hdr;           /* Wal-index header for current transaction */
   u32 minFrame;              /* Ignore wal frames before this one */
+  u32 iReCksum;              /* On commit, recalculate checksums from here */
   const char *zWalName;      /* Name of WAL file */
   u32 nCkpt;                 /* Checkpoint sequence counter in the wal-header */
 #ifdef SQLITE_DEBUG
@@ -462,13 +463,6 @@ struct Wal {
 #define WAL_EXCLUSIVE_MODE  1     
 #define WAL_HEAPMEMORY_MODE 2
 
-/* 
-** Values for Wal.writeLock.
-*/
-#define WAL_WRITELOCK_UNLOCKED 0
-#define WAL_WRITELOCK_LOCKED   1
-#define WAL_WRITELOCK_RECKSUM  2
-
 /*
 ** Possible values for WAL.readOnly
 */
@@ -705,14 +699,16 @@ static void walEncodeFrame(
   assert( WAL_FRAME_HDRSIZE==24 );
   sqlite3Put4byte(&aFrame[0], iPage);
   sqlite3Put4byte(&aFrame[4], nTruncate);
-  memcpy(&aFrame[8], pWal->hdr.aSalt, 8);
+  if( pWal->iReCksum==0 ){
+    memcpy(&aFrame[8], pWal->hdr.aSalt, 8);
 
-  nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
-  walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
-  walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
+    nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
+    walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
+    walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
 
-  sqlite3Put4byte(&aFrame[16], aCksum[0]);
-  sqlite3Put4byte(&aFrame[20], aCksum[1]);
+    sqlite3Put4byte(&aFrame[16], aCksum[0]);
+    sqlite3Put4byte(&aFrame[20], aCksum[1]);
+  }
 }
 
 /*
@@ -2639,6 +2635,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
   /* Cannot start a write transaction without first holding a read
   ** transaction. */
   assert( pWal->readLock>=0 );
+  assert( pWal->writeLock==0 && pWal->iReCksum==0 );
 
   if( pWal->readOnly ){
     return SQLITE_READONLY;
@@ -2674,6 +2671,7 @@ int sqlite3WalEndWriteTransaction(Wal *pWal){
   if( pWal->writeLock ){
     walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
     pWal->writeLock = 0;
+    pWal->iReCksum = 0;
     pWal->truncateOnCommit = 0;
   }
   return SQLITE_OK;
@@ -2895,41 +2893,40 @@ static int walWriteOneFrame(
 /*
 ** This function is called as part of committing a transaction within which
 ** one or more frames have been overwritten. It updates the checksums for
-** all frames written to the wal file by the current transaction.
-**
-** Argument pLive is a pointer to the first wal-index header in shared 
-** memory (the copy readers will see if they open a read-transaction now,
-** before the current commit is finished). This is safe to use because the
-** caller holds the WRITER lock. The first frame to update the checksum
-** for is (pLive->mxFrame+1). The last is argument iLast.
+** all frames written to the wal file by the current transaction starting
+** with the earliest to have been overwritten.
 **
 ** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
 */
-static int walRewriteChecksums(Wal *pWal, WalIndexHdr *pLive, u32 iLast){
+static int walRewriteChecksums(Wal *pWal, u32 iLast){
   const int szPage = pWal->szPage;/* Database page size */
   int rc = SQLITE_OK;             /* Return code */
   u8 *aBuf;                       /* Buffer to load data from wal file into */
   u8 aFrame[WAL_FRAME_HDRSIZE];   /* Buffer to assemble frame-headers in */
   u32 iRead;                      /* Next frame to read from wal file */
+  i64 iCksumOff;
 
   aBuf = sqlite3_malloc(szPage + WAL_FRAME_HDRSIZE);
   if( aBuf==0 ) return SQLITE_NOMEM;
 
-  /* Find the checksum values to use as input for the checksum of the
-  ** first frame written by this transaction. If that frame is frame 1
-  ** (implying that the current transaction restarted the wal file), 
-  ** these values must be read from the wal-file header. If the first
-  ** frame to update the checksum of is not frame 1, then the initial
-  ** checksum values can be copied from pLive.  */
-  if( pLive->mxFrame==0 ){
-    rc = sqlite3OsRead(pWal->pWalFd, aBuf, sizeof(u32)*2, 24);
-    pWal->hdr.aFrameCksum[0] = sqlite3Get4byte(aBuf);
-    pWal->hdr.aFrameCksum[1] = sqlite3Get4byte(&aBuf[sizeof(u32)]);
+  /* Find the checksum values to use as input for the recalculating the
+  ** first checksum. If the first frame is frame 1 (implying that the current
+  ** transaction restarted the wal file), these values must be read from the
+  ** wal-file header. Otherwise, read them from the frame header of the
+  ** previous frame.  */
+  assert( pWal->iReCksum>0 );
+  if( pWal->iReCksum==1 ){
+    iCksumOff = 24;
   }else{
-    memcpy(pWal->hdr.aFrameCksum, pLive->aFrameCksum, sizeof(u32)*2);
+    iCksumOff = walFrameOffset(pWal->iReCksum-1, szPage) + 16;
   }
+  rc = sqlite3OsRead(pWal->pWalFd, aBuf, sizeof(u32)*2, iCksumOff);
+  pWal->hdr.aFrameCksum[0] = sqlite3Get4byte(aBuf);
+  pWal->hdr.aFrameCksum[1] = sqlite3Get4byte(&aBuf[sizeof(u32)]);
 
-  for(iRead=pLive->mxFrame+1; rc==SQLITE_OK && iRead<=iLast; iRead++){
+  iRead = pWal->iReCksum;
+  pWal->iReCksum = 0;
+  for(; rc==SQLITE_OK && iRead<=iLast; iRead++){
     i64 iOff = walFrameOffset(iRead, szPage);
     rc = sqlite3OsRead(pWal->pWalFd, aBuf, szPage+WAL_FRAME_HDRSIZE, iOff);
     if( rc==SQLITE_OK ){
@@ -3065,7 +3062,9 @@ int sqlite3WalFrames(
       if( rc ) return rc;
       if( iWrite>=iFirst ){
         i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE;
-        pWal->writeLock = WAL_WRITELOCK_RECKSUM;
+        if( pWal->iReCksum==0 || iWrite<pWal->iReCksum ){
+          pWal->iReCksum = iWrite;
+        }
         rc = sqlite3OsWrite(pWal->pWalFd, p->pData, szPage, iOff);
         if( rc ) return rc;
         p->flags &= ~PGHDR_WAL_APPEND;
@@ -3084,8 +3083,8 @@ int sqlite3WalFrames(
   }
 
   /* Recalculate checksums within the wal file if required. */
-  if( isCommit && pWal->writeLock==WAL_WRITELOCK_RECKSUM ){
-    rc = walRewriteChecksums(pWal, pLive, iFrame);
+  if( isCommit && pWal->iReCksum ){
+    rc = walRewriteChecksums(pWal, iFrame);
     if( rc ) return rc;
   }