From: dan Date: Fri, 2 Sep 2011 15:41:33 +0000 (+0000) Subject: Reduce the number of malloc() calls made when creating an index on more than 2 columns. X-Git-Tag: version-3.7.8~22^2~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7f72114547ec18b5458e332faca908f81916f27c;p=thirdparty%2Fsqlite.git Reduce the number of malloc() calls made when creating an index on more than 2 columns. FossilOrigin-Name: 065b0c9858da0ebb41722f3c56bdaf62f28b2f2c --- diff --git a/manifest b/manifest index 7f37801bfe..3c9140975f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sall\sdata\sbeing\ssorted\sfits\sin\smemory,\savoid\swriting\sany\sdata\sout\sto\stemporary\sfiles\sin\svdbesort.c. -D 2011-09-02T11:45:31.600 +C Reduce\sthe\snumber\sof\smalloc()\scalls\smade\swhen\screating\san\sindex\son\smore\sthan\s2\scolumns. +D 2011-09-02T15:41:33.781 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in d314143fa6be24828021d3f583ad37d9afdce505 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -245,7 +245,7 @@ F src/vdbeapi.c 11dc47987abacb76ad016dcf5abc0dc422482a98 F src/vdbeaux.c e58acbc5ea3823922a0cd8fa21f94f39af51ee88 F src/vdbeblob.c f024f0bf420f36b070143c32b15cc7287341ffd3 F src/vdbemem.c 5e6effb96dd53d233361cbfaa3f0a43b9af689e9 -F src/vdbesort.c 1e9d4437c7520e09b18f37d2c520bfa01e638655 +F src/vdbesort.c a49d44498cc19af9bdbdc8e9fa882dd26cc17066 F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582 F src/wal.c 3154756177d6219e233d84291d5b05f4e06ff5e9 @@ -961,7 +961,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P 7769fb988d9be0f2d8129aaac19620ac88f9b4a6 -R 023e08b29250dcfb353aa799966d9eeb +P 71075673c625f243969c3f34c73f28f378924007 +R 16433222f8a97f40a1aa6bc60c6c3db0 U dan -Z 052620c5c09aadfa96f446950f8f8dff +Z 8c008bdf93f87673bd214d386e7f6cf5 diff --git a/manifest.uuid b/manifest.uuid index 6963963883..c870d49dd3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -71075673c625f243969c3f34c73f28f378924007 \ No newline at end of file +065b0c9858da0ebb41722f3c56bdaf62f28b2f2c \ No newline at end of file diff --git a/src/vdbesort.c b/src/vdbesort.c index 83c1c5d132..63c6f543b8 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -104,6 +104,8 @@ struct VdbeSorter { SorterRecord *pRecord; /* Head of in-memory record list */ int nLimit1; /* Minimum PMA size, in bytes */ int nLimit2; /* Maximum PMA size, in bytes */ + char *aSpace; /* Space for UnpackRecord() */ + int nSpace; /* Size of aSpace in bytes */ }; /* @@ -303,18 +305,31 @@ static int vdbeSorterIterInit( ** be less than key2. Even if key2 also contains NULL values. */ static int vdbeSorterCompare( - KeyInfo *pKeyInfo, /* Collation functions to use in comparison */ + VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ int bOmitRowid, /* Ignore rowid field at end of keys */ void *pKey1, int nKey1, /* Left side of comparison */ void *pKey2, int nKey2, /* Right side of comparison */ int *pRes /* OUT: Result of comparison */ ){ - char aSpace[150]; + KeyInfo *pKeyInfo = pCsr->pKeyInfo; + VdbeSorter *pSorter = pCsr->pSorter; + char *aSpace = pSorter->aSpace; + int nSpace = pSorter->nSpace; UnpackedRecord *r2; int i; - r2 = sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, aSpace, sizeof(aSpace)); - if( r2==0 ) return SQLITE_NOMEM; + if( aSpace==0 ){ + nSpace = ROUND8(sizeof(UnpackedRecord))+(pKeyInfo->nField+1)*sizeof(Mem); + aSpace = (char *)sqlite3Malloc(nSpace); + if( aSpace==0 ) return SQLITE_NOMEM; + pSorter->aSpace = aSpace; + pSorter->nSpace = nSpace; + } + + /* This call cannot fail. As the memory is already allocated. */ + r2 = sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, aSpace, nSpace); + assert( r2 && (r2->flags & UNPACKED_NEED_FREE)==0 ); + if( bOmitRowid ){ for(i=0; inField-1; i++){ if( r2->aMem[i].flags & MEM_Null ){ @@ -329,7 +344,7 @@ static int vdbeSorterCompare( } *pRes = sqlite3VdbeRecordCompare(nKey1, pKey1, r2); - sqlite3VdbeDeleteUnpackedRecord(r2); + /* sqlite3VdbeDeleteUnpackedRecord(r2); */ return SQLITE_OK; } @@ -366,7 +381,7 @@ static int vdbeSorterDoCompare(VdbeCursor *pCsr, int iOut){ }else{ int res; int rc = vdbeSorterCompare( - pCsr->pKeyInfo, 0, p1->aKey, p1->nKey, p2->aKey, p2->nKey, &res + pCsr, 0, p1->aKey, p1->nKey, p2->aKey, p2->nKey, &res ); if( rc!=SQLITE_OK ) return rc; if( res<=0 ){ @@ -429,6 +444,7 @@ void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){ sqlite3OsCloseFree(pSorter->pTemp1); } vdbeSorterRecordFree(db, pSorter->pRecord); + sqlite3_free(pSorter->aSpace); sqlite3DbFree(db, pSorter); pCsr->pSorter = 0; } @@ -454,7 +470,7 @@ static int vdbeSorterOpenTempFile(sqlite3 *db, sqlite3_file **ppFile){ */ static int vdbeSorterMerge( sqlite3 *db, /* Database handle */ - KeyInfo *pKeyInfo, /* Collation functions to use in comparison */ + VdbeCursor *pCsr, /* For pKeyInfo */ SorterRecord *p1, /* First list to merge */ SorterRecord *p2, /* Second list to merge */ SorterRecord **ppOut /* OUT: Head of merged list */ @@ -473,7 +489,7 @@ static int vdbeSorterMerge( }else{ int res; rc = vdbeSorterCompare( - pKeyInfo, 0, p1->pVal, p1->nVal, p2->pVal, p2->nVal, &res + pCsr, 0, p1->pVal, p1->nVal, p2->pVal, p2->nVal, &res ); if( rc!=SQLITE_OK ){ vdbeSorterRecordFree(db, p1); @@ -510,7 +526,6 @@ static int vdbeSorterSort(sqlite3 *db, VdbeCursor *pCsr){ SorterRecord **aSlot; SorterRecord *p; VdbeSorter *pSorter = pCsr->pSorter; - KeyInfo *pKeyInfo = pCsr->pKeyInfo; aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *)); if( !aSlot ){ @@ -522,7 +537,7 @@ static int vdbeSorterSort(sqlite3 *db, VdbeCursor *pCsr){ SorterRecord *pNext = p->pNext; p->pNext = 0; for(i=0; rc==SQLITE_OK && aSlot[i]; i++){ - rc = vdbeSorterMerge(db, pKeyInfo, p, aSlot[i], &p); + rc = vdbeSorterMerge(db, pCsr, p, aSlot[i], &p); aSlot[i] = 0; } if( rc!=SQLITE_OK ){ @@ -536,7 +551,7 @@ static int vdbeSorterSort(sqlite3 *db, VdbeCursor *pCsr){ p = 0; for(i=0; i<64; i++){ if( rc==SQLITE_OK ){ - rc = vdbeSorterMerge(db, pKeyInfo, p, aSlot[i], &p); + rc = vdbeSorterMerge(db, pCsr, p, aSlot[i], &p); }else{ vdbeSorterRecordFree(db, aSlot[i]); } @@ -550,7 +565,7 @@ static int vdbeSorterSort(sqlite3 *db, VdbeCursor *pCsr){ for(pTmp2=pSorter->pRecord; pTmp2 && rc==SQLITE_OK; pTmp2=pTmp2->pNext){ if( pTmp1 ){ int res; - rc = vdbeSorterCompare(pKeyInfo, + rc = vdbeSorterCompare(pCsr, 0, pTmp1->pVal, pTmp1->nVal, pTmp2->pVal, pTmp2->nVal, &res ); assert( rc!=SQLITE_OK || res<0 ); @@ -913,7 +928,7 @@ int sqlite3VdbeSorterCompare( void *pKey; int nKey; /* Sorter key to compare pVal with */ pKey = vdbeSorterRowkey(pSorter, &nKey); - rc = vdbeSorterCompare(pCsr->pKeyInfo, 1, pVal->z, pVal->n, pKey, nKey, pRes); + rc = vdbeSorterCompare(pCsr, 1, pVal->z, pVal->n, pKey, nKey, pRes); assert( rc!=SQLITE_OK || *pRes<=0 ); return rc; }