diff options
author | drh <drh@noemail.net> | 2008-06-15 02:51:47 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2008-06-15 02:51:47 +0000 |
commit | e5ae5735c0abbd832e12a9633d1a10e9074bf82a (patch) | |
tree | dd8af64eb83c92bd4b226f3ae983d19ad9cb7b42 | |
parent | fec00eabb3c144813164c9f04cc0fffd93c45247 (diff) | |
download | sqlite-e5ae5735c0abbd832e12a9633d1a10e9074bf82a.tar.gz sqlite-e5ae5735c0abbd832e12a9633d1a10e9074bf82a.zip |
Continuing work on the new memory allocation subsystem.
Added routines for temporary memory allocation. Right the btree
balance mechanism to only do one temporary allocation at a time. (CVS 5220)
FossilOrigin-Name: 65fe7b62cfe7d11cd667681a64c96fe7b2fe5685
-rw-r--r-- | manifest | 58 | ||||
-rw-r--r-- | manifest.uuid | 2 | ||||
-rw-r--r-- | src/attach.c | 16 | ||||
-rw-r--r-- | src/btree.c | 97 | ||||
-rw-r--r-- | src/btreeInt.h | 5 | ||||
-rw-r--r-- | src/build.c | 4 | ||||
-rw-r--r-- | src/date.c | 4 | ||||
-rw-r--r-- | src/func.c | 4 | ||||
-rw-r--r-- | src/hash.c | 6 | ||||
-rw-r--r-- | src/legacy.c | 4 | ||||
-rw-r--r-- | src/malloc.c | 60 | ||||
-rw-r--r-- | src/mem1.c | 4 | ||||
-rw-r--r-- | src/mem2.c | 4 | ||||
-rw-r--r-- | src/mutex.c | 4 | ||||
-rw-r--r-- | src/mutex.h | 4 | ||||
-rw-r--r-- | src/os.c | 6 | ||||
-rw-r--r-- | src/pager.c | 18 | ||||
-rw-r--r-- | src/prepare.c | 4 | ||||
-rw-r--r-- | src/printf.c | 8 | ||||
-rw-r--r-- | src/sqlite.h.in | 12 | ||||
-rw-r--r-- | src/sqliteInt.h | 4 | ||||
-rw-r--r-- | src/tokenize.c | 4 | ||||
-rw-r--r-- | src/vdbe.c | 6 | ||||
-rw-r--r-- | src/vdbeaux.c | 4 | ||||
-rw-r--r-- | src/vdbefifo.c | 4 | ||||
-rw-r--r-- | src/where.c | 4 |
26 files changed, 208 insertions, 142 deletions
@@ -1,5 +1,5 @@ -C Continuing\sprogress\son\sthe\snew\smemory\sallocation\ssubsystem.\s\sAdded\sthe\nsqlite3_mem_methods\sstructure\sfor\sdefining\snew\smemory\sallocators\sat\nrun-time.\s(CVS\s5219) -D 2008-06-14T16:56:22 +C Continuing\swork\son\sthe\snew\smemory\sallocation\ssubsystem.\nAdded\sroutines\sfor\stemporary\smemory\sallocation.\s\sRight\sthe\sbtree\nbalance\smechanism\sto\sonly\sdo\sone\stemporary\sallocation\sat\sa\stime.\s(CVS\s5220) +D 2008-06-15T02:51:47 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.in dc5608df93faf4406cfd7a1c8ed9ab93d8bfbfd5 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -92,60 +92,60 @@ F sqlite3.def a1be7b9a4b8b51ac41c6ff6e8e44a14ef66b338b F sqlite3.pc.in 32b8a014799c2028c8e0c9cc5659718262fc493f F src/alter.c cc38b9e2a8cf19428f64e5da7ec4da35b7c02779 F src/analyze.c 9ee63497ee720728abe630d169ab91323ac7519c -F src/attach.c 496cc628b2e8c4d8db99d7c136761fcbebd8420b +F src/attach.c b18ba42c77f7d3941f5d23d2ca20fa1d841a4e91 F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627 F src/bitvec.c ab50c4b8c6a899dae499f5a805eebe4223c78269 F src/btmutex.c 483ced3c52205b04b97df69161fadbf87f4f1ea2 -F src/btree.c 1f4a3f8307b04c98ce250705b95555f820e857b2 +F src/btree.c b374c2ba457f442371aa92b065d1ba698cdee1dc F src/btree.h b1bd7e0b8c2e33658aaf447cb0d1d94f74664b6b -F src/btreeInt.h dc04ee33d8eb84714b2acdf81336fbbf6e764530 -F src/build.c a52d9d51341444a2131e3431608f245db80d9591 +F src/btreeInt.h 02325f04758dba0fcd0c08ac55cd9b189dad61a5 +F src/build.c 88cc5501a87f72d0538b040001d88d31f994edea F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0 F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c -F src/date.c 76a5ba94772346efedf0c412c47e67891bbb266c +F src/date.c bbc4114d1b946d6a94d060bc5b9edce7142c6086 F src/delete.c d3fc5987f2eb88f7b9549d58a5dfea079a83fe8b F src/expr.c ecb3b23d3543427cba3e2ac12a6c6ae4bb20d39b F src/fault.c 1f6177188edb00641673e462f3fab8cba9f7422b -F src/func.c 77a910a1ca7613d291fd0b5cba3be14c02f0dce0 +F src/func.c 6ebd44016c5a6c6d5dd9fe4cbbef2bd517313d0d F src/global.c 2304cfa3288763bd2fed10caf8c6fbaa2b383f4e -F src/hash.c fd8cb06fb54c2fe7d48c9195792059a2e5be8b70 +F src/hash.c 283864c1adf546d4f0a6ee3694b62beeda8fbd35 F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53 F src/hwtime.h 745961687a65ef8918cd551c02e5ccb4b8e772de F src/insert.c c2ead6c36566de8e3f130e7ab1431723a269d5d7 F src/journal.c cffd2cd214e58c0e99c3ff632b3bee6c7cbb260e -F src/legacy.c 8f5a2b25d9673b4004287cf2bf51dbf7d0738406 +F src/legacy.c 3626c71fb70912abec9a4312beba753a9ce800df F src/loadext.c f99a75534a53e281fa2461239ee4a4b4bf6ad564 F src/main.c 4540ec2c0ba99a0dcb8bd114f733007958c6258e -F src/malloc.c ed5c36588992e63ce5dccdfeb3c8071b8fb34e17 +F src/malloc.c c5bdf8967df9acc9765ed1b55c0c0eba9fe9494c F src/md5.c 008216bbb5d34c6fbab5357aa68575ad8a31516a -F src/mem1.c 9ac005ab606a58ffe32e40edd7526375be82a008 -F src/mem2.c 10df776854bee610d5228e6184aaf3bd19f6e542 +F src/mem1.c c8e07e9e6620b1aabf9bdefd19dee93831f67733 +F src/mem2.c 53d29d8275753e05676536c5db8f4867a622b31c F src/mem3.c 617c2e2a72a10ecc5c01af14efc8c2596d2c2e87 F src/mem4.c 45c328ec6dcb7e8d319cb383615b5fe547ca5409 F src/mem5.c 3d2ff00c6e3bc37f5d82cd82e1a123b246fb7b39 -F src/mutex.c 639881f679d75b30813536ddf9224154321c31fb -F src/mutex.h 91292a8351b5844f7d622b0da83df4e651a8f40b +F src/mutex.c 20f6ec9e2d85e257cae9e2ecc40a6769fad9e9e7 +F src/mutex.h b9b9baf7050f3bb1c723e1d22088a704783a2927 F src/mutex_os2.c b8c1231319e966875f251a7ec137bea353546b87 F src/mutex_unix.c 28588d08a2221623d66655e536880003fd5234d6 F src/mutex_w32.c 36fbcf9f50bf0cd9be2c106cd69e5f59021402be -F src/os.c 4f253152aefa4ba54ac7e2dc389a503862a9016c +F src/os.c cf7e09d4215f35fc8269f0fa99f03fd2c2978658 F src/os.h c9a7f94e80193fd4cf27f5c5698eb56753f1b05a F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60 F src/os_os2.c 9f74147f1899793a106827f6bc770363ec377912 F src/os_unix.c dd4a7b19ec00869764c389560c3faf566cf98a71 F src/os_win.c 0b90d9a1ce18bfd2a5f3c4a6bdb13ec369c805a9 -F src/pager.c be98ceeb55bbcda9251c1a846d28c3d323885708 +F src/pager.c 5599fb3ebb63a60ecb44a18a594b371484a7e128 F src/pager.h 6aa3050a3c684475a5a9dbad5ff1cebad612acba F src/parse.y 8c2c3145eebe1964eb279cb3c4e502eae28bb0fa F src/pragma.c 70e7c865dce85fdf9df81848af2169009a56ed08 -F src/prepare.c cbc9301aba1d0fc3d05fae576f2eb667c189cb36 -F src/printf.c f2d4f6c5b0ec24b643e85fe60258adad8b1f6acc +F src/prepare.c 3c19149e75fbf3b08471a389f064da7302cad9c5 +F src/printf.c ff67198b0deee15b4415149880b8e3ab0a36705b F src/random.c 2b2db2de4ab491f5a14d3480466f8f4b5a5db74a F src/select.c 669687459e7d0193c89de06c5dbed55b4a41191c F src/shell.c a12ea645271b7876c8f080146f48e20b00d367ec -F src/sqlite.h.in 0995188c694b36d041424e1b65b6e01d1802c70b +F src/sqlite.h.in 9ff44542f18937a987f13dbc64f29f9a93b8b521 F src/sqlite3ext.h faacd0e6a81aabee0861c6d7883c9172e74ef5b3 -F src/sqliteInt.h cd66968455ee85b1ffed33bb241cbf30fe760d32 +F src/sqliteInt.h bf561dab8a5155f25d3415fa056f570a731e2792 F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8 F src/table.c 1fa8f8113ac9cbc09ae4801c6d2a7f0af82c5822 F src/tclsqlite.c c57e740e30bd6dda678796eed62c7f0e64689834 @@ -174,22 +174,22 @@ F src/test_schema.c e3f93725f7c5b2cff84a69dc4332040dfbc8f81a F src/test_server.c 7e579eb9bf6fbe9cc45e84e4c74d3d06d049a825 F src/test_tclvar.c e99b975614735553fa1c43503d85b0dd988c0e77 F src/test_thread.c e297dd41db0b249646e69f97d36ec13e56e8b730 -F src/tokenize.c d07c7482a59dd8e02f3f73e86ff55eccdc0d8f26 +F src/tokenize.c d39f0d6ce75ca9d0fa4041baec42b5e0411a74fc F src/trigger.c 1e751f8d5ceeb328d26bf1ccfb2de50653670d49 F src/update.c 2d7143b9014e955509cc4f323f9a9584fb898f34 F src/utf.c 8c94fa10efc78c2568d08d436acc59df4df7191b F src/util.c 920d6d5dfdf25f7b85d2093705d8716f9b387e3b F src/vacuum.c a5c289e561ed72283e97d2485491986bc7d684eb -F src/vdbe.c 1936425c3455535a1a20e26a65c470fb009a1ed8 +F src/vdbe.c f6866986de706b98c2738040bc65907728650e8d F src/vdbe.h 1e3722d471739c2b213c6283b60373290e52f7ea F src/vdbeInt.h de321b2c02593e1420106634ed1f5a7d77ad35a7 F src/vdbeapi.c 22b01ed175e4d4c613ee82cabc7a44a275641206 -F src/vdbeaux.c 08ec9a7d9dd47df2faa31d1bdf9595d88789f141 +F src/vdbeaux.c 34b9478ea0c8b41a6dbce6b1bb1c392c87bb0264 F src/vdbeblob.c 554736781ee273a8089c776e96bdb53e66f57ce6 -F src/vdbefifo.c 1644a41c6366ff25a920df4ca675f12d3f559687 +F src/vdbefifo.c c46dae1194e4277bf007144d7e5b0c0b1c24f136 F src/vdbemem.c a39a822e6ae61c4cab4a512df4a315888b206911 F src/vtab.c ce9d19ca9053812a557010fd4be7e842f8ebba2d -F src/where.c 6af9313bdcb6a1986402028864c4d4cf9879d873 +F src/where.c 5c4a999f6aed992131479bfaec9b874326d9963c F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/all.test d56a3ca8acdf761204aff0a2e7aa5eb8e11b31e6 @@ -594,7 +594,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P a03c5af115889f477e17187a198a7d2d40bc76bf -R 7a7d2d9fd4f0061599821d0212d56ac9 +P f00305f4cd2f487f660f34a21c1c24a0b37c7275 +R 959050eddfb58749f141d64dc00b9d92 U drh -Z 3478c8b21bc53c2ad4322f8aef50d224 +Z a529f10f0af791d96bfc33f5cbab9f39 diff --git a/manifest.uuid b/manifest.uuid index 119311b89..e562e1d47 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f00305f4cd2f487f660f34a21c1c24a0b37c7275
\ No newline at end of file +65fe7b62cfe7d11cd667681a64c96fe7b2fe5685
\ No newline at end of file diff --git a/src/attach.c b/src/attach.c index c0f177328..3964f379e 100644 --- a/src/attach.c +++ b/src/attach.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. ** -** $Id: attach.c,v 1.75 2008/04/17 17:02:01 drh Exp $ +** $Id: attach.c,v 1.76 2008/06/15 02:51:47 drh Exp $ */ #include "sqliteInt.h" @@ -112,18 +112,12 @@ static void attachFunc( ** hash tables. */ if( db->aDb==db->aDbStatic ){ - aNew = sqlite3_malloc( sizeof(db->aDb[0])*3 ); - if( aNew==0 ){ - db->mallocFailed = 1; - return; - } + aNew = sqlite3DbMallocRaw(db, sizeof(db->aDb[0])*3 ); + if( aNew==0 ) return; memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); }else{ - aNew = sqlite3_realloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); - if( aNew==0 ){ - db->mallocFailed = 1; - return; - } + aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); + if( aNew==0 ) return; } db->aDb = aNew; aNew = &db->aDb[db->nDb++]; diff --git a/src/btree.c b/src/btree.c index 9d7c2266b..1140e7756 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.463 2008/06/11 18:27:55 danielk1977 Exp $ +** $Id: btree.c,v 1.464 2008/06/15 02:51:47 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -300,7 +300,7 @@ static int saveCursorPosition(BtCursor *pCur){ ** data. */ if( rc==SQLITE_OK && 0==pCur->pPage->intKey){ - void *pKey = sqlite3_malloc(pCur->nKey); + void *pKey = sqlite3Malloc(pCur->nKey); if( pKey ){ rc = sqlite3BtreeKey(pCur, 0, pCur->nKey, pKey); if( rc==SQLITE_OK ){ @@ -1190,7 +1190,7 @@ int sqlite3BtreeOpen( ){ if( sqlite3SharedCacheEnabled ){ int nFullPathname = pVfs->mxPathname+1; - char *zFullPathname = (char *)sqlite3_malloc(nFullPathname); + char *zFullPathname = sqlite3Malloc(nFullPathname); sqlite3_mutex *mutexShared; p->sharable = 1; if( db ){ @@ -1267,9 +1267,6 @@ int sqlite3BtreeOpen( || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){ pBt->pageSize = 0; sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize); - pBt->maxEmbedFrac = 64; /* 25% */ - pBt->minEmbedFrac = 32; /* 12.5% */ - pBt->minLeafFrac = 32; /* 12.5% */ #ifndef SQLITE_OMIT_AUTOVACUUM /* If the magic name ":memory:" will create an in-memory database, then ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if @@ -1285,9 +1282,6 @@ int sqlite3BtreeOpen( nReserve = 0; }else{ nReserve = zDbHeader[20]; - pBt->maxEmbedFrac = zDbHeader[21]; - pBt->minEmbedFrac = zDbHeader[22]; - pBt->minLeafFrac = zDbHeader[23]; pBt->pageSizeFixed = 1; #ifndef SQLITE_OMIT_AUTOVACUUM pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0); @@ -1677,6 +1671,15 @@ static int lockBtree(BtShared *pBt){ if( page1[19]>1 ){ goto page1_init_failed; } + + /* The maximum embedded fraction must be exactly 25%. And the minimum + ** embedded fraction must be 12.5% for both leaf-data and non-leaf-data. + ** The original design allowed these amounts to vary, but as of + ** version 3.6.0, we require them to be fixed. + */ + if( memcmp(&page1[21], "\100\040\040",3)!=0 ){ + goto page1_init_failed; + } pageSize = get2byte(&page1[16]); if( ((pageSize-1)&pageSize)!=0 || pageSize<512 || (SQLITE_MAX_PAGE_SIZE<32768 && pageSize>SQLITE_MAX_PAGE_SIZE) @@ -1705,9 +1708,6 @@ static int lockBtree(BtShared *pBt){ } pBt->pageSize = pageSize; pBt->usableSize = usableSize; - pBt->maxEmbedFrac = page1[21]; - pBt->minEmbedFrac = page1[22]; - pBt->minLeafFrac = page1[23]; #ifndef SQLITE_OMIT_AUTOVACUUM pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0); pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0); @@ -1727,10 +1727,10 @@ static int lockBtree(BtShared *pBt){ ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow ** page pointer. */ - pBt->maxLocal = (pBt->usableSize-12)*pBt->maxEmbedFrac/255 - 23; - pBt->minLocal = (pBt->usableSize-12)*pBt->minEmbedFrac/255 - 23; + pBt->maxLocal = (pBt->usableSize-12)*64/255 - 23; + pBt->minLocal = (pBt->usableSize-12)*32/255 - 23; pBt->maxLeaf = pBt->usableSize - 35; - pBt->minLeaf = (pBt->usableSize-12)*pBt->minLeafFrac/255 - 23; + pBt->minLeaf = (pBt->usableSize-12)*32/255 - 23; if( pBt->minLocal>pBt->maxLocal || pBt->maxLocal<0 ){ goto page1_init_failed; } @@ -1823,9 +1823,9 @@ static int newDatabase(BtShared *pBt){ data[18] = 1; data[19] = 1; data[20] = pBt->pageSize - pBt->usableSize; - data[21] = pBt->maxEmbedFrac; - data[22] = pBt->minEmbedFrac; - data[23] = pBt->minLeafFrac; + data[21] = 64; + data[22] = 32; + data[23] = 32; memset(&data[24], 0, 100-24); zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA ); pBt->pageSizeFixed = 1; @@ -3719,14 +3719,14 @@ int sqlite3BtreeMoveto( if( available>=nCellKey ){ c = sqlite3VdbeRecordCompare(nCellKey, pCellKey, pUnKey); }else{ - pCellKey = sqlite3_malloc( nCellKey ); + pCellKey = sqlite3TempMalloc( nCellKey ); if( pCellKey==0 ){ rc = SQLITE_NOMEM; goto moveto_finish; } rc = sqlite3BtreeKey(pCur, 0, nCellKey, (void *)pCellKey); c = sqlite3VdbeRecordCompare(nCellKey, pCellKey, pUnKey); - sqlite3_free(pCellKey); + sqlite3TempFree(pCellKey); if( rc ) goto moveto_finish; } } @@ -4858,7 +4858,8 @@ static int balance_nonroot(MemPage *pPage){ 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 iSpace = 0; /* First unused byte of aSpace[] */ + int iSpace1 = 0; /* First unused byte of aSpace1[] */ + int iSpace2 = 0; /* First unused byte of aSpace2[] */ 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 */ @@ -4869,8 +4870,9 @@ static int balance_nonroot(MemPage *pPage){ int szNew[NB+2]; /* Combined size of cells place on i-th page */ u8 **apCell = 0; /* All cells begin balanced */ u16 *szCell; /* Local size of all cells in apCell[] */ - u8 *aCopy[NB]; /* Space for holding data of apCopy[] */ - u8 *aSpace; /* Space to hold copies of dividers cells */ + u8 *aCopy[NB]; /* Space for holding data of apCopy[] */ + u8 *aSpace1; /* Space for copies of dividers cells before balance */ + u8 *aSpace2 = 0; /* Space for overflow dividers cells after balance */ #ifndef SQLITE_OMIT_AUTOVACUUM u8 *aFrom = 0; #endif @@ -4988,11 +4990,11 @@ static int balance_nonroot(MemPage *pPage){ /* ** Allocate space for memory structures */ - apCell = sqlite3_malloc( + apCell = sqlite3TempMalloc( nMaxCells*sizeof(u8*) /* apCell */ + nMaxCells*sizeof(u16) /* szCell */ + (ROUND8(sizeof(MemPage))+pBt->pageSize)*NB /* aCopy */ - + pBt->pageSize*5 /* aSpace */ + + pBt->pageSize /* aSpace1 */ + (ISAUTOVACUUM ? nMaxCells : 0) /* aFrom */ ); if( apCell==0 ){ @@ -5006,13 +5008,18 @@ static int balance_nonroot(MemPage *pPage){ aCopy[i] = &aCopy[i-1][pBt->pageSize+ROUND8(sizeof(MemPage))]; assert( ((aCopy[i] - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */ } - aSpace = &aCopy[NB-1][pBt->pageSize+ROUND8(sizeof(MemPage))]; - assert( ((aSpace - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */ + aSpace1 = &aCopy[NB-1][pBt->pageSize+ROUND8(sizeof(MemPage))]; + assert( ((aSpace1 - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */ #ifndef SQLITE_OMIT_AUTOVACUUM if( pBt->autoVacuum ){ - aFrom = &aSpace[5*pBt->pageSize]; + aFrom = &aSpace1[pBt->pageSize]; } #endif + aSpace2 = sqlite3Malloc(pBt->pageSize); + if( aSpace2==0 ){ + rc = SQLITE_NOMEM; + goto balance_cleanup; + } /* ** Make copies of the content of pPage and its siblings into aOld[]. @@ -5030,12 +5037,12 @@ static int balance_nonroot(MemPage *pPage){ /* ** Load pointers to all cells on sibling pages and the divider cells ** into the local apCell[] array. Make copies of the divider cells - ** into space obtained form aSpace[] and remove the the divider Cells + ** into space obtained form aSpace1[] and remove the the divider Cells ** from pParent. ** ** If the siblings are on leaf pages, then the child pointers of the ** divider cells are stripped from the cells before they are copied - ** into aSpace[]. In this way, all cells in apCell[] are without + ** into aSpace1[]. In this way, all cells in apCell[] are without ** child pointers. If siblings are not leaves, then all cell in ** apCell[] include child pointers. Either way, all cells in apCell[] ** are alike. @@ -5080,9 +5087,10 @@ static int balance_nonroot(MemPage *pPage){ u8 *pTemp; assert( nCell<nMaxCells ); szCell[nCell] = sz; - pTemp = &aSpace[iSpace]; - iSpace += sz; - assert( iSpace<=pBt->pageSize*5 ); + pTemp = &aSpace1[iSpace1]; + iSpace1 += sz; + assert( sz<=pBt->pageSize/4 ); + assert( iSpace1<=pBt->pageSize ); memcpy(pTemp, apDiv[i], sz); apCell[nCell] = pTemp+leafCorrection; #ifndef SQLITE_OMIT_AUTOVACUUM @@ -5303,9 +5311,9 @@ static int balance_nonroot(MemPage *pPage){ assert( j<nMaxCells ); pCell = apCell[j]; sz = szCell[j] + leafCorrection; + pTemp = &aSpace2[iSpace2]; if( !pNew->leaf ){ memcpy(&pNew->aData[8], pCell, 4); - pTemp = 0; }else if( leafData ){ /* If the tree is a leaf-data tree, and the siblings are leaves, ** then there is no divider cell in apCell[]. Instead, the divider @@ -5315,16 +5323,11 @@ static int balance_nonroot(MemPage *pPage){ CellInfo info; j--; sqlite3BtreeParseCellPtr(pNew, apCell[j], &info); - pCell = &aSpace[iSpace]; + pCell = pTemp; fillInCell(pParent, pCell, 0, info.nKey, 0, 0, 0, &sz); - iSpace += sz; - assert( iSpace<=pBt->pageSize*5 ); pTemp = 0; }else{ pCell -= 4; - pTemp = &aSpace[iSpace]; - iSpace += sz; - assert( iSpace<=pBt->pageSize*5 ); /* Obscure case for non-leaf-data trees: If the cell at pCell was ** previously stored on a leaf node, and its reported size was 4 ** bytes, then it may actually be smaller than this @@ -5341,6 +5344,9 @@ static int balance_nonroot(MemPage *pPage){ sz = cellSizePtr(pParent, pCell); } } + iSpace2 += sz; + assert( sz<=pBt->pageSize/4 ); + assert( iSpace2<=pBt->pageSize ); rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4); if( rc!=SQLITE_OK ) goto balance_cleanup; put4byte(findOverflowCell(pParent,nxDiv), pNew->pgno); @@ -5391,13 +5397,16 @@ static int balance_nonroot(MemPage *pPage){ ** But the parent page will always be initialized. */ assert( pParent->isInit ); + sqlite3TempFree(apCell); + apCell = 0; rc = balance(pParent, 0); /* ** Cleanup before returning. */ balance_cleanup: - sqlite3_free(apCell); + sqlite3_free(aSpace2); + sqlite3TempFree(apCell); for(i=0; i<nOld; i++){ releasePage(apOld[i]); } @@ -5429,7 +5438,7 @@ static int balance_shallower(MemPage *pPage){ assert( sqlite3_mutex_held(pPage->pBt->mutex) ); pBt = pPage->pBt; mxCellPerPage = MX_CELL(pBt); - apCell = sqlite3_malloc( mxCellPerPage*(sizeof(u8*)+sizeof(u16)) ); + apCell = sqlite3Malloc( mxCellPerPage*(sizeof(u8*)+sizeof(u16)) ); if( apCell==0 ) return SQLITE_NOMEM; szCell = (u16*)&apCell[mxCellPerPage]; if( pPage->leaf ){ @@ -5673,7 +5682,7 @@ static int checkReadLocks( */ static void allocateTempSpace(BtShared *pBt){ if( !pBt->pTmpSpace ){ - pBt->pTmpSpace = sqlite3_malloc(MX_CELL_SIZE(pBt)); + pBt->pTmpSpace = sqlite3Malloc(MX_CELL_SIZE(pBt)); } } @@ -6729,7 +6738,7 @@ char *sqlite3BtreeIntegrityCheck( sqlite3BtreeLeave(p); return 0; } - sCheck.anRef = sqlite3_malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) ); + sCheck.anRef = sqlite3Malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) ); if( !sCheck.anRef ){ unlockBtreeIfUnused(pBt); *pnErr = 1; diff --git a/src/btreeInt.h b/src/btreeInt.h index a60e1cbe8..f5783fa24 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btreeInt.h,v 1.21 2008/04/24 19:15:10 shane Exp $ +** $Id: btreeInt.h,v 1.22 2008/06/15 02:51:47 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -371,9 +371,6 @@ struct BtShared { MemPage *pPage1; /* First page of the database */ u8 inStmt; /* True if we are in a statement subtransaction */ u8 readOnly; /* True if the underlying file is readonly */ - u8 maxEmbedFrac; /* Maximum payload as % of total page size */ - u8 minEmbedFrac; /* Minimum payload as % of total page size */ - u8 minLeafFrac; /* Minimum leaf payload as % of total page size */ u8 pageSizeFixed; /* True if the page size can no longer be changed */ #ifndef SQLITE_OMIT_AUTOVACUUM u8 autoVacuum; /* True if auto-vacuum is enabled */ diff --git a/src/build.c b/src/build.c index c1b5a4530..09a82cbaf 100644 --- a/src/build.c +++ b/src/build.c @@ -22,7 +22,7 @@ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.484 2008/05/01 17:16:53 drh Exp $ +** $Id: build.c,v 1.485 2008/06/15 02:51:47 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -1367,7 +1367,7 @@ static char *createTableStmt(sqlite3 *db, Table *p, int isTemp){ zEnd = "\n)"; } n += 35 + 6*p->nCol; - zStmt = sqlite3_malloc( n ); + zStmt = sqlite3Malloc( n ); if( zStmt==0 ){ db->mallocFailed = 1; return 0; diff --git a/src/date.c b/src/date.c index f258d5cfd..c698eb92e 100644 --- a/src/date.c +++ b/src/date.c @@ -16,7 +16,7 @@ ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: date.c,v 1.83 2008/06/12 16:35:38 drh Exp $ +** $Id: date.c,v 1.84 2008/06/15 02:51:47 drh Exp $ ** ** SQLite processes all times and dates as Julian Day numbers. The ** dates and times are stored as the number of days since noon @@ -888,7 +888,7 @@ static void strftimeFunc( sqlite3_result_error_toobig(context); return; }else{ - z = sqlite3_malloc( n ); + z = sqlite3Malloc( n ); if( z==0 ){ sqlite3_result_error_nomem(context); return; diff --git a/src/func.c b/src/func.c index 10c3baa31..bb2ba4900 100644 --- a/src/func.c +++ b/src/func.c @@ -16,7 +16,7 @@ ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.192 2008/04/27 18:40:12 drh Exp $ +** $Id: func.c,v 1.193 2008/06/15 02:51:47 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -249,7 +249,7 @@ static void *contextMalloc(sqlite3_context *context, i64 nByte){ sqlite3_result_error_toobig(context); z = 0; }else{ - z = sqlite3_malloc(nByte); + z = sqlite3Malloc(nByte); if( !z && nByte>0 ){ sqlite3_result_error_nomem(context); } diff --git a/src/hash.c b/src/hash.c index b8d0af629..12f5593c9 100644 --- a/src/hash.c +++ b/src/hash.c @@ -12,7 +12,7 @@ ** This is the implementation of generic hash-tables ** used in SQLite. ** -** $Id: hash.c,v 1.28 2008/05/13 13:27:34 drh Exp $ +** $Id: hash.c,v 1.29 2008/06/15 02:51:47 drh Exp $ */ #include "sqliteInt.h" #include <assert.h> @@ -387,10 +387,10 @@ void *sqlite3HashInsert(Hash *pH, const void *pKey, int nKey, void *data){ } } if( data==0 ) return 0; - new_elem = (HashElem*)sqlite3_malloc( sizeof(HashElem) ); + new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) ); if( new_elem==0 ) return data; if( pH->copyKey && pKey!=0 ){ - new_elem->pKey = sqlite3_malloc( nKey ); + new_elem->pKey = sqlite3Malloc( nKey ); if( new_elem->pKey==0 ){ sqlite3_free(new_elem); return data; diff --git a/src/legacy.c b/src/legacy.c index 130ba0174..6d84d7039 100644 --- a/src/legacy.c +++ b/src/legacy.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: legacy.c,v 1.26 2008/05/20 15:44:31 drh Exp $ +** $Id: legacy.c,v 1.27 2008/06/15 02:51:47 drh Exp $ */ #include "sqliteInt.h" @@ -133,7 +133,7 @@ exec_out: rc = sqlite3ApiExit(db, rc); if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){ int nErrMsg = 1 + strlen(sqlite3_errmsg(db)); - *pzErrMsg = sqlite3_malloc(nErrMsg); + *pzErrMsg = sqlite3Malloc(nErrMsg); if( *pzErrMsg ){ memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg); } diff --git a/src/malloc.c b/src/malloc.c index 5916ec251..3c567c9c0 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -12,7 +12,7 @@ ** ** Memory allocation functions used throughout sqlite. ** -** $Id: malloc.c,v 1.16 2008/06/14 16:56:22 drh Exp $ +** $Id: malloc.c,v 1.17 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" #include <stdarg.h> @@ -90,7 +90,8 @@ static struct { */ sqlite3_int64 nowUsed; /* Main memory currently in use */ sqlite3_int64 mxUsed; /* Highwater mark for nowUsed */ - int mxReq; /* maximum request size for main or page-cache mem */ + int mxReq; /* Max request size for ordinary mallocs */ + int mxTempReq; /* Max request size for xTemp mallocs */ } mem0; /* @@ -227,6 +228,55 @@ void *sqlite3_malloc(int 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 +** is outstanding clearing it when the allocation is freed. +*/ +#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) +static int tempAllocOut = 0; +#endif + + +/* +** Allocate memory that is to be used and released right away. +** This routine is similar to alloca() in that it is not intended +** 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 *p; + assert( n>0 ); + if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){ + return 0; + } +#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) + assert( tempAllocOut==0 ); + tempAllocOut = 1; +#endif + if( sqlite3Config.bMemstat ){ + sqlite3_mutex_enter(mem0.mutex); + if( n>mem0.mxTempReq ) mem0.mxTempReq = n; + p = sqlite3Config.m.xTempMalloc(n); + sqlite3_mutex_leave(mem0.mutex); + }else{ + p = sqlite3Config.m.xTempMalloc(n); + } + return p; +} +void sqlite3TempFree(void *p){ + if( p ){ +#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) + assert( tempAllocOut==1 ); + tempAllocOut = 0; +#endif + sqlite3Config.m.xTempFree(p); + } +} + +/* ** Return the size of a memory allocation previously obtained from ** sqlite3Malloc() or sqlite3_malloc(). */ @@ -386,14 +436,14 @@ char *sqlite3StrDup(const char *z){ int n; if( z==0 ) return 0; n = strlen(z)+1; - zNew = sqlite3_malloc(n); + zNew = sqlite3Malloc(n); if( zNew ) memcpy(zNew, z, n); return zNew; } char *sqlite3StrNDup(const char *z, int n){ char *zNew; if( z==0 ) return 0; - zNew = sqlite3_malloc(n+1); + zNew = sqlite3Malloc(n+1); if( zNew ){ memcpy(zNew, z, n); zNew[n] = 0; @@ -437,7 +487,7 @@ void sqlite3SetString(char **pz, ...){ } va_end(ap); sqlite3_free(*pz); - *pz = zResult = sqlite3_malloc(nByte); + *pz = zResult = sqlite3Malloc(nByte); if( zResult==0 ){ return; } diff --git a/src/mem1.c b/src/mem1.c index e7491f8ab..120fc040c 100644 --- a/src/mem1.c +++ b/src/mem1.c @@ -17,7 +17,7 @@ ** This file contains implementations of the low-level memory allocation ** routines specified in the sqlite3_mem_methods object. ** -** $Id: mem1.c,v 1.19 2008/06/14 16:56:22 drh Exp $ +** $Id: mem1.c,v 1.20 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" @@ -130,6 +130,8 @@ void sqlite3MemSetDefault(void){ sqlite3MemRealloc, sqlite3MemSize, sqlite3MemRoundup, + sqlite3MemMalloc, + sqlite3MemFree, sqlite3MemInit, sqlite3MemShutdown, 0 diff --git a/src/mem2.c b/src/mem2.c index 3206b25a5..ffc31987c 100644 --- a/src/mem2.c +++ b/src/mem2.c @@ -19,7 +19,7 @@ ** This file contains implementations of the low-level memory allocation ** routines specified in the sqlite3_mem_methods object. ** -** $Id: mem2.c,v 1.28 2008/06/14 16:56:22 drh Exp $ +** $Id: mem2.c,v 1.29 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" @@ -312,6 +312,8 @@ void sqlite3MemSetDefault(void){ sqlite3MemRealloc, sqlite3MemSize, sqlite3MemRoundup, + sqlite3MemMalloc, + sqlite3MemFree, sqlite3MemInit, sqlite3MemShutdown, 0 diff --git a/src/mutex.c b/src/mutex.c index 82812bc75..23c0422f6 100644 --- a/src/mutex.c +++ b/src/mutex.c @@ -19,7 +19,7 @@ ** implementation is suitable for testing. ** debugging purposes ** -** $Id: mutex.c,v 1.19 2008/06/14 16:56:23 drh Exp $ +** $Id: mutex.c,v 1.20 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" @@ -55,7 +55,7 @@ sqlite3_mutex *sqlite3_mutex_alloc(int id){ switch( id ){ case SQLITE_MUTEX_FAST: case SQLITE_MUTEX_RECURSIVE: { - pNew = sqlite3_malloc(sizeof(*pNew)); + pNew = sqlite3Malloc(sizeof(*pNew)); if( pNew ){ pNew->id = id; pNew->cnt = 0; diff --git a/src/mutex.h b/src/mutex.h index f85739d2c..91922862a 100644 --- a/src/mutex.h +++ b/src/mutex.h @@ -19,7 +19,7 @@ ** Source files should #include the sqliteInt.h file and let that file ** include this one indirectly. ** -** $Id: mutex.h,v 1.3 2008/06/13 18:24:27 drh Exp $ +** $Id: mutex.h,v 1.4 2008/06/15 02:51:48 drh Exp $ */ @@ -77,7 +77,7 @@ #define sqlite3_mutex_leave(X) #define sqlite3_mutex_held(X) 1 #define sqlite3_mutex_notheld(X) 1 -#define sqlite3_mutex_init() +#define sqlite3_mutex_init() SQLITE_OK #define sqlite3_mutex_end() #endif @@ -13,7 +13,7 @@ ** This file contains OS interface code that is common to all ** architectures. ** -** $Id: os.c,v 1.112 2008/06/13 18:24:27 drh Exp $ +** $Id: os.c,v 1.113 2008/06/15 02:51:48 drh Exp $ */ #define _SQLITE_OS_C_ 1 #include "sqliteInt.h" @@ -38,7 +38,7 @@ */ #if defined(SQLITE_TEST) && (OS_WIN==0) #define DO_OS_MALLOC_TEST if (1) { \ - void *pTstAlloc = sqlite3_malloc(10); \ + void *pTstAlloc = sqlite3Malloc(10); \ if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \ sqlite3_free(pTstAlloc); \ } @@ -168,7 +168,7 @@ int sqlite3OsOpenMalloc( ){ int rc = SQLITE_NOMEM; sqlite3_file *pFile; - pFile = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile); + pFile = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile); if( pFile ){ rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); if( rc!=SQLITE_OK ){ diff --git a/src/pager.c b/src/pager.c index 06fce97b2..5dab5a41d 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.456 2008/06/07 08:58:22 danielk1977 Exp $ +** @(#) $Id: pager.c,v 1.457 2008/06/15 02:51:48 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -1650,7 +1650,7 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){ /* Open the master journal file exclusively in case some other process ** is running this routine also. Not that it makes too much difference. */ - pMaster = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile * 2); + pMaster = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile * 2); pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile); if( !pMaster ){ rc = SQLITE_NOMEM; @@ -1672,7 +1672,7 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){ /* Load the entire master journal file into space obtained from ** sqlite3_malloc() and pointed to by zMasterJournal. */ - zMasterJournal = (char *)sqlite3_malloc(nMasterJournal + nMasterPtr); + zMasterJournal = (char *)sqlite3Malloc(nMasterJournal + nMasterPtr); if( !zMasterJournal ){ rc = SQLITE_NOMEM; goto delmaster_out; @@ -2193,7 +2193,7 @@ int sqlite3PagerOpen( */ if( zFilename && zFilename[0] ){ nPathname = pVfs->mxPathname+1; - zPathname = sqlite3_malloc(nPathname*2); + zPathname = sqlite3Malloc(nPathname*2); if( zPathname==0 ){ return SQLITE_NOMEM; } @@ -2421,7 +2421,7 @@ int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize){ if( pageSize && pageSize!=pPager->pageSize && !pPager->memDb && pPager->nRef==0 ){ - char *pNew = (char *)sqlite3_malloc(pageSize); + char *pNew = (char *)sqlite3Malloc(pageSize); if( !pNew ){ rc = SQLITE_NOMEM; }else{ @@ -3647,9 +3647,9 @@ static int pagerAllocatePage(Pager *pPager, PgHdr **ppPg){ pagerLeave(pPager); nByteHdr = sizeof(*pPg) + sizeof(u32) + pPager->nExtra + MEMDB*sizeof(PgHistory); - pPg = sqlite3_malloc( nByteHdr ); + pPg = sqlite3Malloc( nByteHdr ); if( pPg ){ - pData = sqlite3_malloc( pPager->pageSize ); + pData = sqlite3Malloc( pPager->pageSize ); if( pData==0 ){ sqlite3_free(pPg); pPg = 0; @@ -4223,7 +4223,7 @@ static int pager_write(PgHdr *pPg){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); PAGERTRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); assert( pHist->pOrig==0 ); - pHist->pOrig = sqlite3_malloc( pPager->pageSize ); + pHist->pOrig = sqlite3Malloc( pPager->pageSize ); if( !pHist->pOrig ){ return SQLITE_NOMEM; } @@ -4293,7 +4293,7 @@ static int pager_write(PgHdr *pPg){ if( MEMDB ){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); assert( pHist->pStmt==0 ); - pHist->pStmt = sqlite3_malloc( pPager->pageSize ); + pHist->pStmt = sqlite3Malloc( pPager->pageSize ); if( pHist->pStmt ){ memcpy(pHist->pStmt, PGHDR_TO_DATA(pPg), pPager->pageSize); } diff --git a/src/prepare.c b/src/prepare.c index 5fa16f2d3..676f4370e 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -13,7 +13,7 @@ ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: prepare.c,v 1.86 2008/05/23 14:49:49 drh Exp $ +** $Id: prepare.c,v 1.87 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -448,7 +448,7 @@ static int schemaIsValid(sqlite3 *db){ int cookie; int allOk = 1; - curTemp = (BtCursor *)sqlite3_malloc(sqlite3BtreeCursorSize()); + curTemp = (BtCursor *)sqlite3Malloc(sqlite3BtreeCursorSize()); if( curTemp ){ assert( sqlite3_mutex_held(db->mutex) ); for(iDb=0; allOk && iDb<db->nDb; iDb++){ diff --git a/src/printf.c b/src/printf.c index 333765a53..d0b219a41 100644 --- a/src/printf.c +++ b/src/printf.c @@ -5,7 +5,7 @@ ** an historical reference. Most of the "enhancements" have been backed ** out so that the functionality is now the same as standard printf(). ** -** $Id: printf.c,v 1.85 2008/05/16 04:51:55 danielk1977 Exp $ +** $Id: printf.c,v 1.86 2008/06/15 02:51:48 drh Exp $ ** ************************************************************************** ** @@ -650,7 +650,7 @@ static void vxprintf( needQuote = !isnull && xtype==etSQLESCAPE2; n += i + 1 + needQuote*2; if( n>etBUFSIZE ){ - bufpt = zExtra = sqlite3_malloc( n ); + bufpt = zExtra = sqlite3Malloc( n ); if( bufpt==0 ) return; }else{ bufpt = buf; @@ -752,7 +752,7 @@ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ }else{ p->nAlloc = szNew; } - zNew = sqlite3_malloc( p->nAlloc ); + zNew = sqlite3Malloc( p->nAlloc ); if( zNew ){ memcpy(zNew, p->zText, p->nChar); sqlite3StrAccumReset(p); @@ -777,7 +777,7 @@ char *sqlite3StrAccumFinish(StrAccum *p){ if( p->zText ){ p->zText[p->nChar] = 0; if( p->useMalloc && p->zText==p->zBase ){ - p->zText = sqlite3_malloc( p->nChar+1 ); + p->zText = sqlite3Malloc( p->nChar+1 ); if( p->zText ){ memcpy(p->zText, p->zBase, p->nChar+1); }else{ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index ea46093ee..ca26f2c71 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -30,7 +30,7 @@ ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** -** @(#) $Id: sqlite.h.in,v 1.327 2008/06/14 16:56:23 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.328 2008/06/15 02:51:48 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ @@ -977,6 +977,14 @@ int sqlite3_config(int, ...); ** 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. +** ** 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 @@ -991,6 +999,8 @@ struct sqlite3_mem_methods { 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() */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6b9eda6c8..cccc29e77 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.709 2008/06/14 16:56:23 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.710 2008/06/15 02:51:48 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1791,6 +1791,8 @@ void *sqlite3Realloc(void*, int); void *sqlite3DbReallocOrFree(sqlite3 *, void *, int); void *sqlite3DbRealloc(sqlite3 *, void *, int); int sqlite3MallocSize(void *); +void *sqlite3TempMalloc(int); +void sqlite3TempFree(void*); void sqlite3MemSetDefault(void); int sqlite3IsNaN(double); diff --git a/src/tokenize.c b/src/tokenize.c index 9af0e95ee..4b545a324 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -15,7 +15,7 @@ ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** -** $Id: tokenize.c,v 1.143 2008/06/02 13:00:33 danielk1977 Exp $ +** $Id: tokenize.c,v 1.144 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -393,7 +393,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ pParse->rc = SQLITE_OK; pParse->zTail = pParse->zSql = zSql; i = 0; - pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3_malloc); + pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3Malloc); if( pEngine==0 ){ db->mallocFailed = 1; return SQLITE_NOMEM; diff --git a/src/vdbe.c b/src/vdbe.c index 0b2a7e3ab..354edf938 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.748 2008/06/07 08:58:22 danielk1977 Exp $ +** $Id: vdbe.c,v 1.749 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -3380,7 +3380,7 @@ case OP_Insert: { pData->zMalloc = 0; } }else{ - pC->pData = sqlite3_malloc( pC->nData+2 ); + pC->pData = sqlite3Malloc( pC->nData+2 ); if( !pC->pData ) goto no_mem; memcpy(pC->pData, pData->z, pC->nData); pC->pData[pC->nData] = 0; @@ -4140,7 +4140,7 @@ case OP_IntegrityCk: { nRoot = pOp->p2; assert( nRoot>0 ); - aRoot = sqlite3_malloc( sizeof(int)*(nRoot+1) ); + aRoot = sqlite3Malloc( sizeof(int)*(nRoot+1) ); if( aRoot==0 ) goto no_mem; assert( pOp->p3>0 && pOp->p3<=p->nMem ); pnErr = &p->aMem[pOp->p3]; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8818378f6..cb670edf5 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -14,7 +14,7 @@ ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** -** $Id: vdbeaux.c,v 1.386 2008/06/06 15:04:37 drh Exp $ +** $Id: vdbeaux.c,v 1.387 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -547,7 +547,7 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){ nField = ((KeyInfo*)zP4)->nField; nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField; - pKeyInfo = sqlite3_malloc( nByte ); + pKeyInfo = sqlite3Malloc( nByte ); pOp->p4.pKeyInfo = pKeyInfo; if( pKeyInfo ){ memcpy(pKeyInfo, zP4, nByte); diff --git a/src/vdbefifo.c b/src/vdbefifo.c index 8bf465f6c..956321c05 100644 --- a/src/vdbefifo.c +++ b/src/vdbefifo.c @@ -12,7 +12,7 @@ ** This file implements a FIFO queue of rowids used for processing ** UPDATE and DELETE statements. ** -** $Id: vdbefifo.c,v 1.6 2008/05/16 04:51:55 danielk1977 Exp $ +** $Id: vdbefifo.c,v 1.7 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" @@ -38,7 +38,7 @@ static FifoPage *allocateFifoPage(int nEntry){ if( nEntry>FIFOSIZE_MAX ){ nEntry = FIFOSIZE_MAX; } - pPage = sqlite3_malloc( sizeof(FifoPage) + sizeof(i64)*(nEntry-1) ); + pPage = sqlite3Malloc( sizeof(FifoPage) + sizeof(i64)*(nEntry-1) ); if( pPage ){ pPage->nSlot = nEntry; pPage->iWrite = 0; diff --git a/src/where.c b/src/where.c index 011357281..3a14bf321 100644 --- a/src/where.c +++ b/src/where.c @@ -16,7 +16,7 @@ ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.308 2008/06/12 00:07:29 drh Exp $ +** $Id: where.c,v 1.309 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" @@ -228,7 +228,7 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, int flags){ int idx; if( pWC->nTerm>=pWC->nSlot ){ WhereTerm *pOld = pWC->a; - pWC->a = sqlite3_malloc( sizeof(pWC->a[0])*pWC->nSlot*2 ); + pWC->a = sqlite3Malloc( sizeof(pWC->a[0])*pWC->nSlot*2 ); if( pWC->a==0 ){ pWC->pParse->db->mallocFailed = 1; if( flags & TERM_DYNAMIC ){ |