------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
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
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
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;
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);
}
}
** 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 */
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;
}
/*
/* Allocate the iterator */
rc = walIteratorInit(pWal, &pIter);
if( rc!=SQLITE_OK ){
- goto walcheckpoint_out;
+ return rc;
}
assert( pIter );