/ Check-in [09d50d9f]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:In vdbesort.c, rename vdbeSorterDoCompare() to vdbeMergeEngineCompare() and move it closer to the one place where it is called. Other minor comment changes.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | threads
Files: files | file ages | folders
SHA1: 09d50d9f0fe7df26dadb0a332731683a07a89fde
User & Date: drh 2014-07-28 18:57:40
Context
2014-07-28
19:58
Rename vdbeIncrMergerInit() to vdbeMergeEngineInit() - a much more accurate name. check-in: 5b084a2d user: drh tags: threads
18:57
In vdbesort.c, rename vdbeSorterDoCompare() to vdbeMergeEngineCompare() and move it closer to the one place where it is called. Other minor comment changes. check-in: 09d50d9f user: drh tags: threads
17:18
In vdbesort.c, rename all pointers to sqlite3_file objects "pFd" and use the name "pFile" only for pointers to SortFile objects. Other comment enhancements. check-in: 518290a7 user: drh tags: threads
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbesort.c.

   605    605       rc = sqlite3OsFetch(pFile->pFd, 0, (int)pFile->iEof, (void**)pp);
   606    606       testcase( rc!=SQLITE_OK );
   607    607     }
   608    608     return rc;
   609    609   }
   610    610   
   611    611   /*
   612         -** Seek PmaReader pReadr to offset iOff within file pFile. Return SQLITE_OK 
          612  +** Attach PmaReader pReadr to file pFile (if it is not already attached to
          613  +** that file) and seek it to offset iOff within the file.  Return SQLITE_OK 
   613    614   ** if successful, or an SQLite error code if an error occurs.
   614    615   */
   615    616   static int vdbePmaReaderSeek(
   616    617     SortSubtask *pTask,             /* Task context */
   617    618     PmaReader *pReadr,              /* Reader whose cursor is to be moved */
   618    619     SorterFile *pFile,              /* Sorter file to read from */
   619    620     i64 iOff                        /* Offset in pFile */
................................................................................
   755    756     UnpackedRecord *r2 = pTask->pUnpacked;
   756    757     if( pKey2 ){
   757    758       sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2);
   758    759     }
   759    760     return sqlite3VdbeRecordCompare(nKey1, pKey1, r2, 0);
   760    761   }
   761    762   
   762         -/*
   763         -** This function is called to compare two PmaReader keys when merging 
   764         -** multiple b-tree segments. Parameter iOut is the index of the aTree[] 
   765         -** value to recalculate.
   766         -*/
   767         -static int vdbeSorterDoCompare(
   768         -  SortSubtask *pTask, 
   769         -  MergeEngine *pMerger, 
   770         -  int iOut
   771         -){
   772         -  int i1;
   773         -  int i2;
   774         -  int iRes;
   775         -  PmaReader *p1;
   776         -  PmaReader *p2;
   777         -
   778         -  assert( iOut<pMerger->nTree && iOut>0 );
   779         -
   780         -  if( iOut>=(pMerger->nTree/2) ){
   781         -    i1 = (iOut - pMerger->nTree/2) * 2;
   782         -    i2 = i1 + 1;
   783         -  }else{
   784         -    i1 = pMerger->aTree[iOut*2];
   785         -    i2 = pMerger->aTree[iOut*2+1];
   786         -  }
   787         -
   788         -  p1 = &pMerger->aReadr[i1];
   789         -  p2 = &pMerger->aReadr[i2];
   790         -
   791         -  if( p1->pFd==0 ){
   792         -    iRes = i2;
   793         -  }else if( p2->pFd==0 ){
   794         -    iRes = i1;
   795         -  }else{
   796         -    int res;
   797         -    assert( pTask->pUnpacked!=0 );  /* allocated in vdbeSortSubtaskMain() */
   798         -    res = vdbeSorterCompare(
   799         -        pTask, p1->aKey, p1->nKey, p2->aKey, p2->nKey
   800         -    );
   801         -    if( res<=0 ){
   802         -      iRes = i1;
   803         -    }else{
   804         -      iRes = i2;
   805         -    }
   806         -  }
   807         -
   808         -  pMerger->aTree[iOut] = iRes;
   809         -  return SQLITE_OK;
   810         -}
   811         -
   812    763   /*
   813    764   ** Initialize the temporary index cursor just opened as a sorter cursor.
   814    765   **
   815    766   ** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nField)
   816    767   ** to determine the number of fields that should be compared from the
   817    768   ** records being sorted. However, if the value passed as argument nField
   818    769   ** is non-zero and the sorter is able to guarantee a stable sort, nField
................................................................................
  1855   1806   */
  1856   1807   static void vdbeIncrSetThreads(IncrMerger *pIncr){
  1857   1808     pIncr->bUseThread = 1;
  1858   1809     pIncr->pTask->file2.iEof -= pIncr->mxSz;
  1859   1810   }
  1860   1811   #endif /* SQLITE_MAX_WORKER_THREADS>0 */
  1861   1812   
         1813  +
         1814  +
         1815  +/*
         1816  +** Recompute pMerger->aTree[iOut] by comparing the next keys on the
         1817  +** two PmaReaders that feed that entry.  Neither of the PmaReaders
         1818  +** are advanced.  This routine merely does the comparison.
         1819  +*/
         1820  +static void vdbeMergeEngineCompare(
         1821  +  MergeEngine *pMerger,  /* Merge engine containing PmaReaders to compare */
         1822  +  int iOut               /* Store the result in pMerger->aTree[iOut] */
         1823  +){
         1824  +  int i1;
         1825  +  int i2;
         1826  +  int iRes;
         1827  +  PmaReader *p1;
         1828  +  PmaReader *p2;
         1829  +
         1830  +  assert( iOut<pMerger->nTree && iOut>0 );
         1831  +
         1832  +  if( iOut>=(pMerger->nTree/2) ){
         1833  +    i1 = (iOut - pMerger->nTree/2) * 2;
         1834  +    i2 = i1 + 1;
         1835  +  }else{
         1836  +    i1 = pMerger->aTree[iOut*2];
         1837  +    i2 = pMerger->aTree[iOut*2+1];
         1838  +  }
         1839  +
         1840  +  p1 = &pMerger->aReadr[i1];
         1841  +  p2 = &pMerger->aReadr[i2];
         1842  +
         1843  +  if( p1->pFd==0 ){
         1844  +    iRes = i2;
         1845  +  }else if( p2->pFd==0 ){
         1846  +    iRes = i1;
         1847  +  }else{
         1848  +    int res;
         1849  +    assert( pMerger->pTask->pUnpacked!=0 );  /* from vdbeSortSubtaskMain() */
         1850  +    res = vdbeSorterCompare(
         1851  +        pMerger->pTask, p1->aKey, p1->nKey, p2->aKey, p2->nKey
         1852  +    );
         1853  +    if( res<=0 ){
         1854  +      iRes = i1;
         1855  +    }else{
         1856  +      iRes = i2;
         1857  +    }
         1858  +  }
         1859  +
         1860  +  pMerger->aTree[iOut] = iRes;
         1861  +}
         1862  +
         1863  +/*
         1864  +** Allowed values for the eMode parameter to vdbeIncrMergerInit()
         1865  +** and vdbePmaReaderIncrMergeInit().
         1866  +*/
  1862   1867   #define INCRINIT_NORMAL 0
  1863   1868   #define INCRINIT_TASK   1
  1864   1869   #define INCRINIT_ROOT   2
  1865         -static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode);
         1870  +
         1871  +/* Forward reference.
         1872  +** The vdbeIncrMergeInit() and vdbePmaReaderIncrMergeInit() routines call each
         1873  +** other (when building a merge tree).
         1874  +*/
         1875  +static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode);
  1866   1876   
  1867   1877   /*
  1868   1878   ** Initialize the MergeEngine object passed as the second argument. Once this
  1869   1879   ** function returns, the first key of merged data may be read from the 
  1870   1880   ** MergeEngine object in the usual fashion.
  1871   1881   **
  1872   1882   ** If argument eMode is INCRINIT_ROOT, then it is assumed that any IncrMerge
................................................................................
  1873   1883   ** objects attached to the PmaReader objects that the merger reads from have
  1874   1884   ** already been populated, but that they have not yet populated aFile[0] and
  1875   1885   ** set the PmaReader objects up to read from it. In this case all that is
  1876   1886   ** required is to call vdbePmaReaderNext() on each PmaReader to point it at
  1877   1887   ** its first key.
  1878   1888   **
  1879   1889   ** Otherwise, if eMode is any value other than INCRINIT_ROOT, then use 
  1880         -** vdbePmaReaderIncrInit() to initialize each PmaReader that feeds data 
         1890  +** vdbePmaReaderIncrMergeInit() to initialize each PmaReader that feeds data 
  1881   1891   ** to pMerger.
  1882   1892   **
  1883   1893   ** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
  1884   1894   */
  1885         -static int vdbeIncrInitMerger(
         1895  +static int vdbeIncrMergerInit(
  1886   1896     SortSubtask *pTask,             /* Thread that will run pMerger */
  1887   1897     MergeEngine *pMerger,           /* MergeEngine to initialize */
  1888   1898     int eMode                       /* One of the INCRINIT_XXX constants */
  1889   1899   ){
  1890   1900     int rc = SQLITE_OK;             /* Return code */
  1891   1901     int i;                          /* For looping over PmaReader objects */
  1892   1902     int nTree = pMerger->nTree;
  1893   1903   
  1894   1904     /* Verify that the MergeEngine is assigned to a single thread */
  1895   1905     assert( pMerger->pTask==0 || pMerger->pTask==pTask );
  1896   1906     pMerger->pTask = pTask;
  1897   1907   
  1898         -  for(i=0; rc==SQLITE_OK && i<nTree; i++){
         1908  +  for(i=0; i<nTree; i++){
  1899   1909       if( eMode==INCRINIT_ROOT ){
  1900   1910         /* PmaReaders should be normally initialized in order, as if they are
  1901   1911         ** reading from the same temp file this makes for more linear file IO.
  1902   1912         ** However, in the INCRINIT_ROOT case, if PmaReader aReadr[nTask-1] is
  1903   1913         ** in use it will block the vdbePmaReaderNext() call while it uses
  1904   1914         ** the main thread to fill its buffer. So calling PmaReaderNext()
  1905   1915         ** on this PmaReader before any of the multi-threaded PmaReaders takes
  1906   1916         ** better advantage of multi-processor hardware. */
  1907   1917         rc = vdbePmaReaderNext(&pMerger->aReadr[nTree-i-1]);
  1908   1918       }else{
  1909         -      rc = vdbePmaReaderIncrInit(&pMerger->aReadr[i], INCRINIT_NORMAL);
         1919  +      rc = vdbePmaReaderIncrMergeInit(&pMerger->aReadr[i], INCRINIT_NORMAL);
  1910   1920       }
         1921  +    if( rc!=SQLITE_OK ) return rc;
  1911   1922     }
  1912   1923   
  1913         -  for(i=pMerger->nTree-1; rc==SQLITE_OK && i>0; i--){
  1914         -    rc = vdbeSorterDoCompare(pTask, pMerger, i);
         1924  +  for(i=pMerger->nTree-1; i>0; i--){
         1925  +    vdbeMergeEngineCompare(pMerger, i);
  1915   1926     }
  1916         -
  1917         -  return (rc==SQLITE_OK ? pTask->pUnpacked->errCode : rc);
         1927  +  return pTask->pUnpacked->errCode;
  1918   1928   }
  1919   1929   
  1920   1930   /*
         1931  +** Initialize the IncrMerge field of a PmaReader.
         1932  +**
  1921   1933   ** If the PmaReader passed as the first argument is not an incremental-reader
  1922   1934   ** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it serves
  1923   1935   ** to open and/or initialize the temp file related fields of the IncrMerge
  1924   1936   ** object at (pReadr->pIncr).
  1925   1937   **
  1926   1938   ** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders
  1927   1939   ** in the sub-tree headed by pReadr are also initialized. Data is then loaded
................................................................................
  1946   1958   ** that pReadr->pIncr is a multi-threaded IncrMerge objects, and that all
  1947   1959   ** child-trees have already been initialized using IncrInit(INCRINIT_TASK).
  1948   1960   ** In this case vdbePmaReaderNext() is called on all child PmaReaders and
  1949   1961   ** the current PmaReader set to point to the first key in its range.
  1950   1962   **
  1951   1963   ** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
  1952   1964   */
  1953         -static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode){
         1965  +static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){
  1954   1966     int rc = SQLITE_OK;
  1955   1967     IncrMerger *pIncr = pReadr->pIncr;
  1956   1968     if( pIncr ){
  1957   1969       SortSubtask *pTask = pIncr->pTask;
  1958   1970       sqlite3 *db = pTask->pSorter->db;
  1959   1971   
  1960         -    rc = vdbeIncrInitMerger(pTask, pIncr->pMerger, eMode);
         1972  +    rc = vdbeIncrMergerInit(pTask, pIncr->pMerger, eMode);
  1961   1973   
  1962   1974       /* Set up the required files for pIncr. A multi-theaded IncrMerge object
  1963   1975       ** requires two temp files to itself, whereas a single-threaded object
  1964   1976       ** only requires a region of pTask->file2. */
  1965   1977       if( rc==SQLITE_OK ){
  1966   1978         int mxSz = pIncr->mxSz;
  1967   1979   #if SQLITE_MAX_WORKER_THREADS>0
................................................................................
  2001   2013       }
  2002   2014     }
  2003   2015     return rc;
  2004   2016   }
  2005   2017   
  2006   2018   #if SQLITE_MAX_WORKER_THREADS>0
  2007   2019   /*
  2008         -** The main routine for vdbePmaReaderIncrInit() operations run in 
         2020  +** The main routine for vdbePmaReaderIncrMergeInit() operations run in 
  2009   2021   ** background threads.
  2010   2022   */
  2011   2023   static void *vdbePmaReaderBgInit(void *pCtx){
  2012   2024     PmaReader *pReader = (PmaReader*)pCtx;
  2013         -  void *pRet = SQLITE_INT_TO_PTR(vdbePmaReaderIncrInit(pReader,INCRINIT_TASK));
         2025  +  void *pRet = SQLITE_INT_TO_PTR(
         2026  +                  vdbePmaReaderIncrMergeInit(pReader,INCRINIT_TASK)
         2027  +               );
  2014   2028     pReader->pIncr->pTask->bDone = 1;
  2015   2029     return pRet;
  2016   2030   }
  2017   2031   
  2018   2032   /*
  2019         -** Use a background thread to invoke vdbePmaReaderIncrInit(INCRINIT_TASK) 
         2033  +** Use a background thread to invoke vdbePmaReaderIncrMergeInit(INCRINIT_TASK) 
  2020   2034   ** on the the PmaReader object passed as the first argument.
  2021   2035   **
  2022   2036   ** This call will initialize the various fields of the pReadr->pIncr 
  2023   2037   ** structure and, if it is a multi-threaded IncrMerger, launch a 
  2024   2038   ** background thread to populate aFile[1].
  2025   2039   */
  2026   2040   static int vdbePmaReaderBgIncrInit(PmaReader *pReadr){
................................................................................
  2266   2280               }
  2267   2281             }
  2268   2282             for(iTask=0; rc==SQLITE_OK && iTask<pSorter->nTask; iTask++){
  2269   2283               PmaReader *p = &pMain->aReadr[iTask];
  2270   2284               assert( p->pIncr==0 || p->pIncr->pTask==&pSorter->aTask[iTask] );
  2271   2285               if( p->pIncr ){ 
  2272   2286                 if( iTask==pSorter->nTask-1 ){
  2273         -                rc = vdbePmaReaderIncrInit(p, INCRINIT_TASK);
         2287  +                rc = vdbePmaReaderIncrMergeInit(p, INCRINIT_TASK);
  2274   2288                 }else{
  2275   2289                   rc = vdbePmaReaderBgIncrInit(p);
  2276   2290                 }
  2277   2291               }
  2278   2292             }
  2279   2293           }
  2280   2294           pMain = 0;
  2281   2295         }
  2282   2296         if( rc==SQLITE_OK ){
  2283         -        rc = vdbePmaReaderIncrInit(pReadr, INCRINIT_ROOT);
         2297  +        rc = vdbePmaReaderIncrMergeInit(pReadr, INCRINIT_ROOT);
  2284   2298         }
  2285   2299       }else
  2286   2300   #endif
  2287   2301       {
  2288         -      rc = vdbeIncrInitMerger(pTask0, pMain, INCRINIT_NORMAL);
         2302  +      rc = vdbeIncrMergerInit(pTask0, pMain, INCRINIT_NORMAL);
  2289   2303         pSorter->pMerger = pMain;
  2290   2304         pMain = 0;
  2291   2305       }
  2292   2306     }
  2293   2307   
  2294   2308     if( rc!=SQLITE_OK ){
  2295   2309       vdbeMergeEngineFree(pMain);