]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Reduce the size of the large allocation (approx 8KB for every 4000 frames in the...
authordan <dan@noemail.net>
Fri, 25 Jun 2010 15:16:25 +0000 (15:16 +0000)
committerdan <dan@noemail.net>
Fri, 25 Jun 2010 15:16:25 +0000 (15:16 +0000)
FossilOrigin-Name: 29887487ed549f97c3c9b37f852bae179b6ea9a9

manifest
manifest.uuid
src/wal.c

index 4ccc5d9a42e77723f9ac0041d00b33b31ba39ca9..9a8531a0cda96451b24a917328d67bd1a7865a32 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,5 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-C Fix\sup\sa\sbranch\sin\ssqlite3ValueFromExpr()\sso\sthat\swe\scan\sachieve\sfull\nbranch\stest\scoverage\sregardless\sof\swhether\sor\snot\sSQLITE_ENABLE_STAT2\sis\nused.
-D 2010-06-25T14:17:58
+C Reduce\sthe\ssize\sof\sthe\slarge\sallocation\s(approx\s8KB\sfor\severy\s4000\sframes\sin\sthe\slog)\sthat\soccurs\sduring\scheckpoint.\sUse\sthe\s'scratch'\smemory\sfor\sthis\sallocation\sinstead\sof\sthe\sgeneral\spurpose\sallocation.
+D 2010-06-25T15:16:25
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -229,7 +226,7 @@ F src/vdbeblob.c 258a6010ba7a82b72b327fb24c55790655689256
 F src/vdbemem.c 5e579abf6532001dfbee0e640dc34eae897a9807
 F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
 F src/vtab.c a0f8a40274e4261696ef57aa806de2776ab72cda
-F src/wal.c a6648b66a8990439d5d5c124191590b00929b9e4
+F src/wal.c 7f2c67f14fd3f84fb725cbfdf4df894eeee80a6d
 F src/wal.h 4ace25262452d17e7d3ec970c89ee17794004008
 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
 F src/where.c 1c895bef33d0dfc7ed90fb1f74120435d210ea56
@@ -828,14 +825,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 5995cb15080cfb707ddda501f975673f658106f7
-R b293a589c96868961d62e21f054fc0b8
-U drh
-Z 4fc1bd811dc80b4ce7415da853fc1e91
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.6 (GNU/Linux)
-
-iD8DBQFMJLqZoxKgR168RlERAkSsAJ4tTxR+vXkcVc8afivjpTTCf6qYLACfVFaM
-B4uK0hleb5qyn2q3SH3rYII=
-=XoGT
------END PGP SIGNATURE-----
+P af471ed79f539ff495f6d4cb3b69188c8af7ae3d
+R 3f79fa337bc0c5c5671e54a144204fa5
+U dan
+Z 49c1806c3eb5e28123879bb170870e95
index 0adb4d0664243d64b1eb25d483104f5339ce3dab..8c14e61b740fab0bc7ff9a1d2074570c1bec880f 100644 (file)
@@ -1 +1 @@
-af471ed79f539ff495f6d4cb3b69188c8af7ae3d
\ No newline at end of file
+29887487ed549f97c3c9b37f852bae179b6ea9a9
\ No newline at end of file
index 30ec85906b85c4ccaec21ccd7f188ab61fd6735c..62ed887f307c47b37662f2a18abac26421cf9d33 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -1361,6 +1361,7 @@ static void walMergesort(
     for(iSub=0; iList & (1<<iSub); iSub++){
       struct Sublist *p = &aSub[iSub];
       assert( p->aList && p->nList<=(1<<iSub) );
+      assert( p->aList==&aList[iList&~((2<<iSub)-1)] );
       walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer);
     }
     aSub[iSub].aList = aMerge;
@@ -1370,7 +1371,8 @@ static void walMergesort(
   for(iSub++; iSub<ArraySize(aSub); iSub++){
     if( nList & (1<<iSub) ){
       struct Sublist *p = &aSub[iSub];
-      assert( p->nList<=(2<<iSub) );
+      assert( p->nList<=(1<<iSub) );
+      assert( p->aList==&aList[nList&~((2<<iSub)-1)] );
       walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer);
     }
   }
@@ -1391,22 +1393,19 @@ static void walMergesort(
 ** Free an iterator allocated by walIteratorInit().
 */
 static void walIteratorFree(WalIterator *p){
-  sqlite3_free(p);
+  sqlite3ScratchFree(p);
 }
 
 /*
-** Map the wal-index into memory owned by this thread, if it is not
-** mapped already.  Then construct a WalInterator object that can be
-** used to loop over all pages in the WAL in ascending order.  
+** Construct a WalInterator object that can be used to loop over all 
+** pages in the WAL in ascending order. The caller must hold the checkpoint
 **
 ** On success, make *pp point to the newly allocated WalInterator object
-** return SQLITE_OK.  Otherwise, leave *pp unchanged and return an error
-** code.
+** return SQLITE_OK. Otherwise, return an error code. If this routine
+** returns an error, the value of *pp is undefined.
 **
 ** The calling routine should invoke walIteratorFree() to destroy the
-** WalIterator object when it has finished with it.  The caller must
-** also unmap the wal-index.  But the wal-index must not be unmapped
-** prior to the WalIterator object being destroyed.
+** WalIterator object when it has finished with it.
 */
 static int walIteratorInit(Wal *pWal, WalIterator **pp){
   WalIterator *p;                 /* Return value */
@@ -1415,63 +1414,66 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
   int nByte;                      /* Number of bytes to allocate */
   int i;                          /* Iterator variable */
   ht_slot *aTmp;                  /* Temp space used by merge-sort */
-  ht_slot *aSpace;                /* Space at the end of the allocation */
+  int rc = SQLITE_OK;             /* Return Code */
 
-  /* This routine only runs while holding SQLITE_SHM_CHECKPOINT.  No other
-  ** thread is able to write to shared memory while this routine is
-  ** running (or, indeed, while the WalIterator object exists).  Hence,
-  ** we can cast off the volatile qualification from shared memory
+  /* This routine only runs while holding the checkpoint lock. And
+  ** it only runs if there is actually content in the log (mxFrame>0).
   */
-  assert( pWal->ckptLock );
+  assert( pWal->ckptLock && pWal->hdr.mxFrame>0 );
   iLast = pWal->hdr.mxFrame;
 
-  /* Allocate space for the WalIterator object */
+  /* Allocate space for the WalIterator object. */
   nSegment = walFramePage(iLast) + 1;
   nByte = sizeof(WalIterator) 
-        + nSegment*(sizeof(struct WalSegment))
-        + (nSegment+1)*(HASHTABLE_NPAGE * sizeof(ht_slot));
-  p = (WalIterator *)sqlite3_malloc(nByte);
+        + (nSegment-1)*(sizeof(struct WalSegment))
+        + nSegment*(HASHTABLE_NPAGE * sizeof(ht_slot));
+  p = (WalIterator *)sqlite3ScratchMalloc(nByte);
   if( !p ){
     return SQLITE_NOMEM;
   }
   memset(p, 0, nByte);
-
-  /* Allocate space for the WalIterator object */
   p->nSegment = nSegment;
-  aSpace = (ht_slot *)&p->aSegment[nSegment];
-  aTmp = &aSpace[HASHTABLE_NPAGE*nSegment];
-  for(i=0; i<nSegment; i++){
+
+  /* Allocate temporary space used by the merge-sort routine. This block
+  ** of memory will be freed before this function returns.
+  */
+  aTmp = (ht_slot *)sqlite3ScratchMalloc(HASHTABLE_NPAGE * sizeof(ht_slot));
+  if( !aTmp ){
+    rc = SQLITE_NOMEM;
+  }
+
+  for(i=0; rc==SQLITE_OK && i<nSegment; i++){
     volatile ht_slot *aHash;
     int j;
     u32 iZero;
     int nEntry;
     volatile u32 *aPgno;
-    int rc;
+    ht_slot *aIndex;
 
     rc = walHashGet(pWal, i, &aHash, &aPgno, &iZero);
-    if( rc!=SQLITE_OK ){
-      walIteratorFree(p);
-      return rc;
-    }
-    aPgno++;
-    nEntry = ((i+1)==nSegment)?iLast-iZero:(u32 *)aHash-(u32 *)aPgno;
-    iZero++;
-
-    for(j=0; j<nEntry; j++){
-      aSpace[j] = j;
+    if( rc==SQLITE_OK ){
+      aPgno++;
+      nEntry = ((i+1)==nSegment)?iLast-iZero:(u32 *)aHash-(u32 *)aPgno;
+      iZero++;
+  
+      aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[i*HASHTABLE_NPAGE];
+      for(j=0; j<nEntry; j++){
+        aIndex[j] = j;
+      }
+      walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry);
+      p->aSegment[i].iZero = iZero;
+      p->aSegment[i].nEntry = nEntry;
+      p->aSegment[i].aIndex = aIndex;
+      p->aSegment[i].aPgno = (u32 *)aPgno;
     }
-    walMergesort((u32 *)aPgno, aTmp, aSpace, &nEntry);
-    p->aSegment[i].iZero = iZero;
-    p->aSegment[i].nEntry = nEntry;
-    p->aSegment[i].aIndex = aSpace;
-    p->aSegment[i].aPgno = (u32 *)aPgno;
-    aSpace += HASHTABLE_NPAGE;
   }
-  assert( aSpace==aTmp );
+  sqlite3ScratchFree(aTmp);
 
-  /* Return the fully initialized WalIterator object */
+  if( rc!=SQLITE_OK ){
+    walIteratorFree(p);
+  }
   *pp = p;
-  return SQLITE_OK ;
+  return rc;
 }
 
 /*
@@ -1525,7 +1527,7 @@ static int walCheckpoint(
   /* Allocate the iterator */
   rc = walIteratorInit(pWal, &pIter);
   if( rc!=SQLITE_OK ){
-    goto walcheckpoint_out;
+    return rc;
   }
   assert( pIter );