]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Reduce the number of malloc() calls made when creating an index on more than 2 columns.
authordan <dan@noemail.net>
Fri, 2 Sep 2011 15:41:33 +0000 (15:41 +0000)
committerdan <dan@noemail.net>
Fri, 2 Sep 2011 15:41:33 +0000 (15:41 +0000)
FossilOrigin-Name: 065b0c9858da0ebb41722f3c56bdaf62f28b2f2c

manifest
manifest.uuid
src/vdbesort.c

index 7f37801bfef94e7a49aaf11a497f395da5fe24bb..3c9140975fe56c8f527e3bedfa1dc19226357f7f 100644 (file)
--- 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
index 6963963883661bdca47d033a83928a8ff600c707..c870d49dd3c15dc979baddeaa7bbf9ee230dc942 100644 (file)
@@ -1 +1 @@
-71075673c625f243969c3f34c73f28f378924007
\ No newline at end of file
+065b0c9858da0ebb41722f3c56bdaf62f28b2f2c
\ No newline at end of file
index 83c1c5d132b5bd81898c01fa2719fbb355f0d852..63c6f543b8986504dca99634a2f4017fa44ab6f9 100644 (file)
@@ -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; i<r2->nField-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;
 }