/ Check-in [707ea170]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Avoid some unnecessary calls to sqlite3VdbeRecordUnpack() that were being made when merging data from two or more temp files together in vdbesort.c
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 707ea170b3e26965b7e3982f7554d122d130b9a6
User & Date: dan 2014-03-19 20:01:25
References
2014-03-29
06:27
Add the optimization to avoid some unnecessary calls to sqlite3VdbeRecordUnpack() added to the trunk by [707ea170b3]. check-in: fc4d04e6 user: dan tags: threads
2014-03-25
17:07
Fix a problem in the code added by [707ea170b3] causing vdbesort.c to sort unstably. check-in: d3e640af user: dan tags: orderby-planning
Context
2014-03-20
12:17
Fix an unnecessarily obtuse use of a bitmask flag. check-in: ca314081 user: drh tags: trunk
08:59
Add an experimental fix to avoid attempting to mmap memory from an offset that is not a multiple of the system page size on systems with page sizes larger than 32KB. check-in: 6f3a5c24 user: dan tags: shm-mapping-fix
2014-03-19
23:42
Merge the vdbesort.c optimization from trunk. check-in: e4bfffb9 user: drh tags: orderby-planning
20:01
Avoid some unnecessary calls to sqlite3VdbeRecordUnpack() that were being made when merging data from two or more temp files together in vdbesort.c check-in: 707ea170 user: dan tags: trunk
2014-03-17
15:06
Clean up some obsolete "register" declarations in printf.c. check-in: ecd9d3f9 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbesort.c.

   952    952   */
   953    953   int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){
   954    954     VdbeSorter *pSorter = pCsr->pSorter;
   955    955     int rc;                         /* Return code */
   956    956   
   957    957     if( pSorter->aTree ){
   958    958       int iPrev = pSorter->aTree[1];/* Index of iterator to advance */
   959         -    int i;                        /* Index of aTree[] to recalculate */
   960         -
   961    959       rc = vdbeSorterIterNext(db, &pSorter->aIter[iPrev]);
   962         -    for(i=(pSorter->nTree+iPrev)/2; rc==SQLITE_OK && i>0; i=i/2){
   963         -      rc = vdbeSorterDoCompare(pCsr, i);
   964         -    }
          960  +    if( rc==SQLITE_OK ){
          961  +      int i;                      /* Index of aTree[] to recalculate */
          962  +      VdbeSorterIter *pIter1;     /* First iterator to compare */
          963  +      VdbeSorterIter *pIter2;     /* Second iterator to compare */
          964  +      u8 *pKey2;                  /* To pIter2->aKey, or 0 if record cached */
          965  +
          966  +      /* Find the first two iterators to compare. The one that was just
          967  +      ** advanced (iPrev) and the one next to it in the array.  */
          968  +      pIter1 = &pSorter->aIter[(iPrev & 0xFFFE)];
          969  +      pIter2 = &pSorter->aIter[(iPrev | 0x0001)];
          970  +      pKey2 = pIter2->aKey;
          971  +
          972  +      for(i=(pSorter->nTree+iPrev)/2; i>0; i=i/2){
          973  +        /* Compare pIter1 and pIter2. Store the result in variable iRes. */
          974  +        int iRes;
          975  +        if( pIter1->pFile==0 ){
          976  +          iRes = +1;
          977  +        }else if( pIter2->pFile==0 ){
          978  +          iRes = -1;
          979  +        }else{
          980  +          vdbeSorterCompare(pCsr, 0, 
          981  +              pIter1->aKey, pIter1->nKey, pKey2, pIter2->nKey, &iRes
          982  +          );
          983  +        }
          984  +
          985  +        /* If pIter1 contained the smaller value, set aTree[i] to its index.
          986  +        ** Then set pIter2 to the next iterator to compare to pIter1. In this
          987  +        ** case there is no cache of pIter2 in pSorter->pUnpacked, so set
          988  +        ** pKey2 to point to the record belonging to pIter2.
          989  +        **
          990  +        ** Alternatively, if pIter2 contains the smaller of the two values,
          991  +        ** set aTree[i] to its index and update pIter1. If vdbeSorterCompare()
          992  +        ** was actually called above, then pSorter->pUnpacked now contains
          993  +        ** a value equivalent to pIter2. So set pKey2 to NULL to prevent
          994  +        ** vdbeSorterCompare() from decoding pIter2 again.  */
          995  +        if( iRes<=0 ){
          996  +          pSorter->aTree[i] = (pIter1 - pSorter->aIter);
          997  +          pIter2 = &pSorter->aIter[ pSorter->aTree[i ^ 0x0001] ];
          998  +          pKey2 = pIter2->aKey;
          999  +        }else{
         1000  +          if( pIter1->pFile ) pKey2 = 0;
         1001  +          pSorter->aTree[i] = (pIter2 - pSorter->aIter);
         1002  +          pIter1 = &pSorter->aIter[ pSorter->aTree[i ^ 0x0001] ];
         1003  +        }
   965   1004   
   966         -    *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0);
         1005  +      }
         1006  +      *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0);
         1007  +    }
   967   1008     }else{
   968   1009       SorterRecord *pFree = pSorter->pRecord;
   969   1010       pSorter->pRecord = pFree->pNext;
   970   1011       pFree->pNext = 0;
   971   1012       vdbeSorterRecordFree(db, pFree);
   972   1013       *pbEof = !pSorter->pRecord;
   973   1014       rc = SQLITE_OK;