Index: src/btree.c ================================================================== --- src/btree.c +++ src/btree.c @@ -7,11 +7,11 @@ ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.464 2008/06/15 02:51:47 drh Exp $ +** $Id: btree.c,v 1.465 2008/06/17 15:12:01 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. ** Including a description of file format and an overview of operation. */ @@ -3717,18 +3717,18 @@ pCellKey = (void *)fetchPayload(pCur, &available, 0); nCellKey = pCur->info.nKey; if( available>=nCellKey ){ c = sqlite3VdbeRecordCompare(nCellKey, pCellKey, pUnKey); }else{ - pCellKey = sqlite3TempMalloc( nCellKey ); + pCellKey = sqlite3Malloc( nCellKey ); if( pCellKey==0 ){ rc = SQLITE_NOMEM; goto moveto_finish; } rc = sqlite3BtreeKey(pCur, 0, nCellKey, (void *)pCellKey); c = sqlite3VdbeRecordCompare(nCellKey, pCellKey, pUnKey); - sqlite3TempFree(pCellKey); + sqlite3_free(pCellKey); if( rc ) goto moveto_finish; } } if( c==0 ){ pCur->info.nKey = nCellKey; @@ -4858,10 +4858,11 @@ int usableSpace; /* Bytes in pPage beyond the header */ int pageFlags; /* Value of pPage->aData[0] */ int subtotal; /* Subtotal of bytes in cells on one page */ int iSpace1 = 0; /* First unused byte of aSpace1[] */ int iSpace2 = 0; /* First unused byte of aSpace2[] */ + int szScratch; /* Size of scratch memory requested */ MemPage *apOld[NB]; /* pPage and up to two siblings */ Pgno pgnoOld[NB]; /* Page numbers for each page in apOld[] */ MemPage *apCopy[NB]; /* Private copies of apOld[] pages */ MemPage *apNew[NB+2]; /* pPage and up to NB siblings after balancing */ Pgno pgnoNew[NB+2]; /* Page numbers for each page in apNew[] */ @@ -4988,17 +4989,17 @@ nMaxCells = (nMaxCells + 3)&~3; /* ** Allocate space for memory structures */ - apCell = sqlite3TempMalloc( + szScratch = nMaxCells*sizeof(u8*) /* apCell */ + nMaxCells*sizeof(u16) /* szCell */ + (ROUND8(sizeof(MemPage))+pBt->pageSize)*NB /* aCopy */ + pBt->pageSize /* aSpace1 */ - + (ISAUTOVACUUM ? nMaxCells : 0) /* aFrom */ - ); + + (ISAUTOVACUUM ? nMaxCells : 0); /* aFrom */ + apCell = sqlite3ScratchMalloc( szScratch ); if( apCell==0 ){ rc = SQLITE_NOMEM; goto balance_cleanup; } szCell = (u16*)&apCell[nMaxCells]; @@ -5013,11 +5014,11 @@ #ifndef SQLITE_OMIT_AUTOVACUUM if( pBt->autoVacuum ){ aFrom = &aSpace1[pBt->pageSize]; } #endif - aSpace2 = sqlite3Malloc(pBt->pageSize); + aSpace2 = sqlite3PageMalloc(pBt->pageSize); if( aSpace2==0 ){ rc = SQLITE_NOMEM; goto balance_cleanup; } @@ -5395,20 +5396,20 @@ ** Balance the parent page. Note that the current page (pPage) might ** have been added to the freelist so it might no longer be initialized. ** But the parent page will always be initialized. */ assert( pParent->isInit ); - sqlite3TempFree(apCell); + sqlite3ScratchFree(apCell); apCell = 0; rc = balance(pParent, 0); /* ** Cleanup before returning. */ balance_cleanup: - sqlite3_free(aSpace2); - sqlite3TempFree(apCell); + sqlite3PageFree(aSpace2); + sqlite3ScratchFree(apCell); for(i=0; i #include @@ -89,11 +89,11 @@ ** Performance statistics */ sqlite3_int64 nowUsed; /* Main memory currently in use */ sqlite3_int64 mxUsed; /* Highwater mark for nowUsed */ int mxReq; /* Max request size for ordinary mallocs */ - int mxTempReq; /* Max request size for xTemp mallocs */ + int mxScratchReq; /* Max request size for xTemp mallocs */ } mem0; /* ** Initialize the memory allocation subsystem. */ @@ -227,16 +227,16 @@ return sqlite3Malloc(n); } /* ** Each thread may only have a single outstanding allocation from -** xTempMalloc(). We verify this constraint in the single-threaded -** case by setting tempAllocOut to 1 when an allocation +** xScratchMalloc(). We verify this constraint in the single-threaded +** case by setting scratchAllocOut to 1 when an allocation ** is outstanding clearing it when the allocation is freed. */ #if SQLITE_THREADSAFE==0 && !defined(NDEBUG) -static int tempAllocOut = 0; +static int scratchAllocOut = 0; #endif /* ** Allocate memory that is to be used and released right away. @@ -244,39 +244,49 @@ ** for situations where the memory might be held long-term. This ** routine is intended to get memory to old large transient data ** structures that would not normally fit on the stack of an ** embedded processor. */ -void *sqlite3TempMalloc(int n){ +void *sqlite3ScratchMalloc(int n){ void *p; assert( n>0 ); if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){ return 0; } #if SQLITE_THREADSAFE==0 && !defined(NDEBUG) - assert( tempAllocOut==0 ); - tempAllocOut = 1; + assert( scratchAllocOut==0 ); + scratchAllocOut = 1; #endif if( sqlite3Config.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); - if( n>mem0.mxTempReq ) mem0.mxTempReq = n; - p = sqlite3Config.m.xTempMalloc(n); + if( n>mem0.mxScratchReq ) mem0.mxScratchReq = n; + p = sqlite3Config.m.xMalloc(n); sqlite3_mutex_leave(mem0.mutex); }else{ - p = sqlite3Config.m.xTempMalloc(n); + p = sqlite3Config.m.xMalloc(n); } return p; } -void sqlite3TempFree(void *p){ +void sqlite3ScratchFree(void *p){ if( p ){ #if SQLITE_THREADSAFE==0 && !defined(NDEBUG) - assert( tempAllocOut==1 ); - tempAllocOut = 0; + assert( scratchAllocOut==1 ); + scratchAllocOut = 0; #endif - sqlite3Config.m.xTempFree(p); + sqlite3Config.m.xFree(p); } } + +/* +** Place holders for the page-cache memory allocator. +*/ +void *sqlite3PageMalloc(int iSize){ + return sqlite3Malloc(iSize); +} +void sqlite3PageFree(void *pOld){ + sqlite3_free(pOld); +} /* ** Return the size of a memory allocation previously obtained from ** sqlite3Malloc() or sqlite3_malloc(). */ Index: src/mem1.c ================================================================== --- src/mem1.c +++ src/mem1.c @@ -15,11 +15,11 @@ ** to obtain the memory it needs. ** ** This file contains implementations of the low-level memory allocation ** routines specified in the sqlite3_mem_methods object. ** -** $Id: mem1.c,v 1.20 2008/06/15 02:51:48 drh Exp $ +** $Id: mem1.c,v 1.21 2008/06/17 15:12:01 drh Exp $ */ #include "sqliteInt.h" /* ** This version of the memory allocator is the default. It is @@ -128,15 +128,13 @@ sqlite3MemMalloc, sqlite3MemFree, sqlite3MemRealloc, sqlite3MemSize, sqlite3MemRoundup, - sqlite3MemMalloc, - sqlite3MemFree, sqlite3MemInit, sqlite3MemShutdown, 0 }; sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); } #endif /* SQLITE_SYSTEM_MALLOC */ Index: src/mem2.c ================================================================== --- src/mem2.c +++ src/mem2.c @@ -17,11 +17,11 @@ ** leaks and memory usage errors. ** ** This file contains implementations of the low-level memory allocation ** routines specified in the sqlite3_mem_methods object. ** -** $Id: mem2.c,v 1.29 2008/06/15 02:51:48 drh Exp $ +** $Id: mem2.c,v 1.30 2008/06/17 15:12:01 drh Exp $ */ #include "sqliteInt.h" /* ** This version of the memory allocator is used only if the @@ -310,12 +310,10 @@ sqlite3MemMalloc, sqlite3MemFree, sqlite3MemRealloc, sqlite3MemSize, sqlite3MemRoundup, - sqlite3MemMalloc, - sqlite3MemFree, sqlite3MemInit, sqlite3MemShutdown, 0 }; sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); Index: src/pager.c ================================================================== --- src/pager.c +++ src/pager.c @@ -16,11 +16,11 @@ ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.457 2008/06/15 02:51:48 drh Exp $ +** @(#) $Id: pager.c,v 1.458 2008/06/17 15:12:01 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include #include @@ -771,23 +771,24 @@ */ #ifdef SQLITE_ENABLE_ATOMIC_WRITE static int jrnlBufferSize(Pager *pPager){ int dc; /* Device characteristics */ int nSector; /* Sector size */ - int nPage; /* Page size */ + int szPage; /* Page size */ sqlite3_file *fd = pPager->fd; if( fd->pMethods ){ dc = sqlite3OsDeviceCharacteristics(fd); nSector = sqlite3OsSectorSize(fd); - nPage = pPager->pageSize; + szPage = pPager->pageSize; } assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); - if( !fd->pMethods || (dc&(SQLITE_IOCAP_ATOMIC|(nPage>>8))&&nSector<=nPage) ){ + if( !fd->pMethods || + (dc & (SQLITE_IOCAP_ATOMIC|(szPage>>8)) && nSector<=szPage) ){ return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager); } return 0; } #endif @@ -1292,11 +1293,11 @@ for(pPg=pPager->pAll; pPg; pPg=pNext){ IOTRACE(("PGFREE %p %d\n", pPager, pPg->pgno)); PAGER_INCR(sqlite3_pager_pgfree_count); pNext = pPg->pNextAll; lruListRemove(pPg); - sqlite3_free(pPg->pData); + sqlite3PageFree(pPg->pData); sqlite3_free(pPg); } assert(pPager->lru.pFirst==0); assert(pPager->lru.pFirstSynced==0); assert(pPager->lru.pLast==0); @@ -2178,11 +2179,11 @@ int memDb = 0; int readOnly = 0; int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; int noReadlock = (flags & PAGER_NO_READLOCK)!=0; int journalFileSize = sqlite3JournalSize(pVfs); - int nDefaultPage = SQLITE_DEFAULT_PAGE_SIZE; + int szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; char *zPathname = 0; int nPathname = 0; /* The default return is a NULL pointer */ *ppPager = 0; @@ -2257,27 +2258,27 @@ ** + The value returned by sqlite3OsSectorSize() ** + The largest page size that can be written atomically. */ if( rc==SQLITE_OK && !readOnly ){ int iSectorSize = sqlite3OsSectorSize(pPager->fd); - if( nDefaultPagefd); int ii; assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536); - for(ii=nDefaultPage; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){ - if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ) nDefaultPage = ii; + for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){ + if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ) szPageDflt = ii; } } #endif - if( nDefaultPage>SQLITE_MAX_DEFAULT_PAGE_SIZE ){ - nDefaultPage = SQLITE_MAX_DEFAULT_PAGE_SIZE; + if( szPageDflt>SQLITE_MAX_DEFAULT_PAGE_SIZE ){ + szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE; } } } }else if( !memDb ){ /* If a temporary file is requested, it is not opened immediately. @@ -2287,11 +2288,11 @@ tempFile = 1; pPager->state = PAGER_EXCLUSIVE; } if( pPager && rc==SQLITE_OK ){ - pPager->pTmpSpace = sqlite3MallocZero(nDefaultPage); + pPager->pTmpSpace = sqlite3PageMalloc(szPageDflt); } /* If an error occured in either of the blocks above. ** Free the Pager structure and close the file. ** Since the pager is not allocated there is no need to set @@ -2324,11 +2325,11 @@ pPager->noReadlock = noReadlock && readOnly; /* pPager->stmtOpen = 0; */ /* pPager->stmtInUse = 0; */ /* pPager->nRef = 0; */ pPager->dbSize = memDb-1; - pPager->pageSize = nDefaultPage; + pPager->pageSize = szPageDflt; /* pPager->stmtSize = 0; */ /* pPager->stmtJSize = 0; */ /* pPager->nPage = 0; */ pPager->mxPage = 100; pPager->mxPgno = SQLITE_MAX_PAGE_COUNT; @@ -2419,19 +2420,19 @@ u16 pageSize = *pPageSize; assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) ); if( pageSize && pageSize!=pPager->pageSize && !pPager->memDb && pPager->nRef==0 ){ - char *pNew = (char *)sqlite3Malloc(pageSize); + char *pNew = (char *)sqlite3PageMalloc(pageSize); if( !pNew ){ rc = SQLITE_NOMEM; }else{ pagerEnter(pPager); pager_reset(pPager); pPager->pageSize = pageSize; setSectorSize(pPager); - sqlite3_free(pPager->pTmpSpace); + sqlite3PageFree(pPager->pTmpSpace); pPager->pTmpSpace = pNew; pagerLeave(pPager); } } *pPageSize = pPager->pageSize; @@ -2565,12 +2566,12 @@ #ifndef SQLITE_OMIT_MEMORYDB /* ** Clear a PgHistory block */ static void clearHistory(PgHistory *pHist){ - sqlite3_free(pHist->pOrig); - sqlite3_free(pHist->pStmt); + sqlite3PageFree(pHist->pOrig); + sqlite3PageFree(pHist->pStmt); pHist->pOrig = 0; pHist->pStmt = 0; } #else #define clearHistory(x) @@ -2651,11 +2652,11 @@ *ppPg = pPg->pNextAll; IOTRACE(("PGFREE %p %d\n", pPager, pPg->pgno)); PAGER_INCR(sqlite3_pager_pgfree_count); unlinkPage(pPg); makeClean(pPg); - sqlite3_free(pPg->pData); + sqlite3PageFree(pPg->pData); sqlite3_free(pPg); pPager->nPage--; } } } @@ -2788,11 +2789,11 @@ ** sqlite3OsDelete(pPager->zFilename); ** } */ sqlite3_free(pPager->aHash); - sqlite3_free(pPager->pTmpSpace); + sqlite3PageFree(pPager->pTmpSpace); sqlite3_free(pPager); return SQLITE_OK; } #if !defined(NDEBUG) || defined(SQLITE_TEST) @@ -3345,11 +3346,11 @@ + sizeof(u32) + pPager->nExtra + MEMDB*sizeof(PgHistory) ); IOTRACE(("PGFREE %p %d *\n", pPager, pPg->pgno)); PAGER_INCR(sqlite3_pager_pgfree_count); - sqlite3_free(pPg->pData); + sqlite3PageFree(pPg->pData); sqlite3_free(pPg); pPager->nPage--; }else{ /* An error occured whilst writing to the database file or ** journal in pager_recycle(). The error is not returned to the @@ -3647,11 +3648,11 @@ pagerLeave(pPager); nByteHdr = sizeof(*pPg) + sizeof(u32) + pPager->nExtra + MEMDB*sizeof(PgHistory); pPg = sqlite3Malloc( nByteHdr ); if( pPg ){ - pData = sqlite3Malloc( pPager->pageSize ); + pData = sqlite3PageMalloc( pPager->pageSize ); if( pData==0 ){ sqlite3_free(pPg); pPg = 0; } } @@ -4221,11 +4222,11 @@ if( (int)pPg->pgno <= pPager->origDbSize ){ if( MEMDB ){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); PAGERTRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); assert( pHist->pOrig==0 ); - pHist->pOrig = sqlite3Malloc( pPager->pageSize ); + pHist->pOrig = sqlite3PageMalloc( pPager->pageSize ); if( !pHist->pOrig ){ return SQLITE_NOMEM; } memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize); }else{ @@ -4291,11 +4292,11 @@ ){ assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize ); if( MEMDB ){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); assert( pHist->pStmt==0 ); - pHist->pStmt = sqlite3Malloc( pPager->pageSize ); + pHist->pStmt = sqlite3PageMalloc( pPager->pageSize ); if( pHist->pStmt ){ memcpy(pHist->pStmt, PGHDR_TO_DATA(pPg), pPager->pageSize); } PAGERTRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); page_add_to_stmt_list(pPg); @@ -5033,11 +5034,11 @@ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); pNext = pHist->pNextStmt; assert( pHist->inStmt ); pHist->inStmt = 0; pHist->pPrevStmt = pHist->pNextStmt = 0; - sqlite3_free(pHist->pStmt); + sqlite3PageFree(pHist->pStmt); pHist->pStmt = 0; } } pPager->stmtNRec = 0; pPager->stmtInUse = 0; @@ -5061,11 +5062,11 @@ PgHistory *pHist; for(pPg=pPager->pStmt; pPg; pPg=pHist->pNextStmt){ pHist = PGHDR_TO_HIST(pPg, pPager); if( pHist->pStmt ){ memcpy(PGHDR_TO_DATA(pPg), pHist->pStmt, pPager->pageSize); - sqlite3_free(pHist->pStmt); + sqlite3PageFree(pHist->pStmt); pHist->pStmt = 0; } } pPager->dbSize = pPager->stmtSize; pager_truncate_cache(pPager); Index: src/sqlite.h.in ================================================================== --- src/sqlite.h.in +++ src/sqlite.h.in @@ -28,11 +28,11 @@ ** The name of this file under configuration management is "sqlite.h.in". ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** -** @(#) $Id: sqlite.h.in,v 1.328 2008/06/15 02:51:48 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.329 2008/06/17 15:12:01 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include /* Needed for the definition of va_list */ @@ -973,19 +973,11 @@ ** is always at least as big as the requested size but may be larger. ** ** The xRoundup method returns what would be the allocated size of ** a memory allocation given a particular requested size. Most memory ** allocators round up memory allocations at least to the next multiple -** of 8. Some round up to a larger multiple or to a power of 2. -** -** The xTempMalloc and xTempFree methods are used to allocate a large -** chunk of temporary-use memory whose lifetime is a single procedure -** call. These routines may be the same as xMalloc and xFree, if desired, -** though some specialized applications may benefit from using a different -** allocation algorithm in this case. -** SQLite will never request more than one outstanding memory allocation -** per thread using xTempMalloc. +** of 8. Some allocators round up to a larger multiple or to a power of 2. ** ** The xInit method initializes the memory allocator. (For example, ** it might allocate any require mutexes or initialize internal data ** structures. The xShutdown method is invoked (indirectly) by ** [sqlite3_shutdown()] and should deallocate any resources acquired @@ -997,12 +989,10 @@ void *(*xMalloc)(int); /* Memory allocation function */ void (*xFree)(void*); /* Free a prior allocation */ void *(*xRealloc)(void*,int); /* Resize an allocation */ int (*xSize)(void*); /* Return the size of an allocation */ int (*xRoundup)(int); /* Round up request size to allocation size */ - void *(*xTempMalloc)(int); /* Allocate temporary space */ - void (*xTempFree)(void*); /* Free space from xTempMalloc */ int (*xInit)(void*); /* Initialize the memory allocator */ void (*xShutdown)(void*); /* Deinitialize the memory allocator */ void *pAppData; /* Argument to xInit() and xShutdown() */ }; Index: src/sqliteInt.h ================================================================== --- src/sqliteInt.h +++ src/sqliteInt.h @@ -9,11 +9,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.710 2008/06/15 02:51:48 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.711 2008/06/17 15:12:01 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* @@ -1789,12 +1789,14 @@ char *sqlite3DbStrNDup(sqlite3*,const char*, int); void *sqlite3Realloc(void*, int); void *sqlite3DbReallocOrFree(sqlite3 *, void *, int); void *sqlite3DbRealloc(sqlite3 *, void *, int); int sqlite3MallocSize(void *); -void *sqlite3TempMalloc(int); -void sqlite3TempFree(void*); +void *sqlite3ScratchMalloc(int); +void sqlite3ScratchFree(void*); +void *sqlite3PageMalloc(int); +void sqlite3PageFree(void*); void sqlite3MemSetDefault(void); int sqlite3IsNaN(double); char *sqlite3MPrintf(sqlite3*,const char*, ...);