]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Optimize cases where all the sorter is sorting a set of records that all begin with...
authordan <dan@noemail.net>
Thu, 26 Mar 2015 11:55:03 +0000 (11:55 +0000)
committerdan <dan@noemail.net>
Thu, 26 Mar 2015 11:55:03 +0000 (11:55 +0000)
FossilOrigin-Name: ce5ad17c25cf2f8274ce304c51e4421faae0b32b

manifest
manifest.uuid
src/vdbesort.c

index 6fdfb0ad409f5ec1b0d98bc29769ec5db2c87229..65ccebc2d0c6b9c4ab18c2ffdfeb3381c8299065 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Change\san\sunreachable\sbranch\sinto\san\sassert().
-D 2015-03-25T18:29:10.982
+C Optimize\scases\swhere\sall\sthe\ssorter\sis\ssorting\sa\sset\sof\srecords\sthat\sall\sbegin\swith\sinteger\svalues,\sor\sthat\sall\sbegin\swith\stext\svalues\sto\sbe\scompared\susing\sBINARY.
+D 2015-03-26T11:55:03.488
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -300,7 +300,7 @@ F src/vdbeapi.c 583d56b129dd27f12bed518270de9ebe521e6a75
 F src/vdbeaux.c 413dc496248ac18eb0c19e35e86bb1ffd47b8907
 F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90
 F src/vdbemem.c c0dc81285b7571b0a31c40f17846fe2397ec1cd9
-F src/vdbesort.c 919717d7599fa31d343ec28bffd0f9e91a4ff5f6
+F src/vdbesort.c a8d82ed4b09f3b1f5390c7546a9bcad72d483abf
 F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
 F src/vtab.c 62d49237bd8f3be4863815a39387b0f9897fa5e1
 F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
@@ -1247,7 +1247,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 37866b4d483296ab9b7fcb9f5486695d4c2b8ddd
-R 6f3611ab9d4988693f727ae20dc9c9e5
-U drh
-Z 3f028f44e21ab0b1619e9687cba7cf7a
+P fb076b28c36975ff2e41440f22fe5de115c195da
+R 1e1c6c1ab8dfb515d00c85e16ae436f0
+T *branch * sorter-opt
+T *sym-sorter-opt *
+T -sym-trunk *
+U dan
+Z 9752268c90db4ae1847219cb63314e99
index 849f782137b5178c2001e3e5cd50b23f24d2ac93..dfa9f943535ab495a4039129bb2a978c776838eb 100644 (file)
@@ -1 +1 @@
-fb076b28c36975ff2e41440f22fe5de115c195da
\ No newline at end of file
+ce5ad17c25cf2f8274ce304c51e4421faae0b32b
\ No newline at end of file
index bbdafa82304ad434885c4c775b79ffd38eba79f5..4faeebf963aa5eda6a95d13b83d86701af738d23 100644 (file)
@@ -298,6 +298,7 @@ struct SortSubtask {
   UnpackedRecord *pUnpacked;      /* Space to unpack a record */
   SorterList list;                /* List for thread to write to a PMA */
   int nPMA;                       /* Number of PMAs currently in file */
+  RecordCompare xCompare;         /* Compare function to use */
   SorterFile file;                /* Temp file for level-0 PMAs */
   SorterFile file2;               /* Space for other PMAs */
 };
@@ -328,9 +329,13 @@ struct VdbeSorter {
   u8 bUseThreads;                 /* True to use background threads */
   u8 iPrev;                       /* Previous thread used to flush PMA */
   u8 nTask;                       /* Size of aTask[] array */
+  u8 typeMask;
   SortSubtask aTask[1];           /* One or more subtasks */
 };
 
+#define SORTER_TYPE_INTEGER 0x01
+#define SORTER_TYPE_TEXT    0x02
+
 /*
 ** An instance of the following object is used to read records out of a
 ** PMA, in sorted order.  The next key to be read is cached in nKey/aKey.
@@ -765,7 +770,7 @@ static int vdbeSorterCompare(
   if( pKey2 ){
     sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2);
   }
-  return sqlite3VdbeRecordCompare(nKey1, pKey1, r2);
+  return pTask->xCompare(nKey1, pKey1, r2);
 }
 
 /*
@@ -835,9 +840,13 @@ int sqlite3VdbeSorterInit(
     pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
     memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
     pKeyInfo->db = 0;
-    if( nField && nWorker==0 ) pKeyInfo->nField = nField;
+    if( nField && nWorker==0 ){
+      pKeyInfo->nXField += (pKeyInfo->nField - nField);
+      pKeyInfo->nField = nField;
+    }
     pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
     pSorter->nTask = nWorker + 1;
+    pSorter->iPrev = nWorker-1;
     pSorter->bUseThreads = (pSorter->nTask>1);
     pSorter->db = db;
     for(i=0; i<pSorter->nTask; i++){
@@ -863,6 +872,10 @@ int sqlite3VdbeSorterInit(
         if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM;
       }
     }
+
+    if( (pKeyInfo->nField+pKeyInfo->nXField)<13 && pKeyInfo->aColl[0]==0 ){
+      pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT;
+    }
   }
 
   return rc;
@@ -1182,6 +1195,13 @@ static int vdbeSortAllocUnpacked(SortSubtask *pTask){
     if( pFree==0 ) return SQLITE_NOMEM;
     pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nField;
     pTask->pUnpacked->errCode = 0;
+    if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
+      pTask->pUnpacked->r1 = 1;
+      pTask->pUnpacked->r2 = -1;
+    }else{
+      pTask->pUnpacked->r1 = -1;
+      pTask->pUnpacked->r2 = 1;
+    }
   }
   return SQLITE_OK;
 }
@@ -1235,12 +1255,20 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
   rc = vdbeSortAllocUnpacked(pTask);
   if( rc!=SQLITE_OK ) return rc;
 
+  p = pList->pList;
+  if( pTask->pSorter->typeMask==0 ){
+    pTask->xCompare = sqlite3VdbeRecordCompare;
+  }else{
+    UnpackedRecord *pRec = pTask->pUnpacked;
+    sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, p->nVal, SRVAL(p), pRec);
+    pTask->xCompare = sqlite3VdbeFindCompare(pRec);
+  }
+
   aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *));
   if( !aSlot ){
     return SQLITE_NOMEM;
   }
 
-  p = pList->pList;
   while( p ){
     SorterRecord *pNext;
     if( pList->aMemory ){
@@ -1602,6 +1630,16 @@ int sqlite3VdbeSorterWrite(
   int bFlush;                     /* True to flush contents of memory to PMA */
   int nReq;                       /* Bytes of memory required */
   int nPMA;                       /* Bytes of PMA space required */
+  int t;                          /* serial type of first record field */
+
+  getVarint32((const u8*)&pVal->z[1], t);
+  if( t>0 && t<10 && t!=7 ){
+    pSorter->typeMask &= SORTER_TYPE_INTEGER;
+  }else if( t & 0x01 ){
+    pSorter->typeMask &= SORTER_TYPE_TEXT;
+  }else{
+    pSorter->typeMask = 0;
+  }
 
   assert( pSorter );
 
@@ -2288,6 +2326,13 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
   MergeEngine *pMain = 0;
 #if SQLITE_MAX_WORKER_THREADS
   sqlite3 *db = pTask0->pSorter->db;
+  RecordCompare xCompare = (pSorter->typeMask==0 ? 
+      sqlite3VdbeRecordCompare : pSorter->aTask[0].xCompare
+  );
+  int i;
+  for(i=0; i<pSorter->nTask; i++){
+    pSorter->aTask[i].xCompare = xCompare;
+  }
 #endif
 
   rc = vdbeSorterMergeTreeBuild(pSorter, &pMain);