/ Check-in [a683c05f]
Login

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

Overview
Comment:Fix a problem in vdbesort.c causing spurious SQLITE_NOMEM errors when using memsys3 or memsys5.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | threads
Files: files | file ages | folders
SHA1: a683c05f6250389e84b980b16559e162ba1a27c2
User & Date: dan 2014-03-29 09:34:45
Context
2014-03-29
10:01
Fix a broken assert() in vdbesort.c. check-in: 18d1b402 user: dan tags: threads
09:34
Fix a problem in vdbesort.c causing spurious SQLITE_NOMEM errors when using memsys3 or memsys5. check-in: a683c05f user: dan tags: threads
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
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbesort.c.

  1042   1042   static int vdbeSorterNext(
  1043   1043     SorterThread *pThread, 
  1044   1044     SorterMerger *pMerger, 
  1045   1045     int *pbEof
  1046   1046   ){
  1047   1047     int rc;
  1048   1048     int iPrev = pMerger->aTree[1];/* Index of iterator to advance */
  1049         -  int i;                        /* Index of aTree[] to recalculate */
  1050   1049   
  1051   1050     /* Advance the current iterator */
  1052   1051     rc = vdbeSorterIterNext(&pMerger->aIter[iPrev]);
  1053   1052   
  1054   1053     /* Update contents of aTree[] */
  1055   1054     if( rc==SQLITE_OK ){
  1056   1055       int i;                      /* Index of aTree[] to recalculate */
................................................................................
  1277   1276         pThread->aListMemory = pSorter->aMemory;
  1278   1277         pSorter->aMemory = aMem;
  1279   1278       }
  1280   1279   
  1281   1280       if( bUseFg==0 ){
  1282   1281         /* Launch a background thread for this operation */
  1283   1282         void *pCtx = (void*)pThread;
  1284         -      if( pSorter->aMemory==0 ){
  1285         -        pSorter->aMemory = sqlite3Malloc(pSorter->nMemory);
  1286         -        if( pSorter->aMemory==0 ) return SQLITE_NOMEM;
  1287         -      }else{
  1288         -        pSorter->nMemory = sqlite3MallocSize(pSorter->aMemory);
         1283  +      assert( pSorter->aMemory==0 || pThread->aListMemory==0 );
         1284  +      if( pThread->aListMemory ){
         1285  +        if( pSorter->aMemory==0 ){
         1286  +          pSorter->aMemory = sqlite3Malloc(pSorter->nMemory);
         1287  +          if( pSorter->aMemory==0 ) return SQLITE_NOMEM;
         1288  +        }else{
         1289  +          pSorter->nMemory = sqlite3MallocSize(pSorter->aMemory);
         1290  +        }
  1289   1291         }
  1290   1292         rc = sqlite3ThreadCreate(&pThread->pThread, vdbeSorterThreadMain, pCtx);
  1291   1293       }else{
  1292   1294         /* Use the foreground thread for this operation */
  1293   1295         u8 *aMem;
  1294   1296         rc = vdbeSorterRunThread(pThread);
  1295   1297         aMem = pThread->aListMemory;
................................................................................
  1333   1335     **     than (page-size * cache-size), or
  1334   1336     **
  1335   1337     **   * The total memory allocated for the in-memory list is greater 
  1336   1338     **     than (page-size * 10) and sqlite3HeapNearlyFull() returns true.
  1337   1339     */
  1338   1340     nReq = pVal->n + sizeof(SorterRecord);
  1339   1341     nPMA = pVal->n + sqlite3VarintLen(pVal->n);
  1340         -  if( pSorter->aMemory ){
  1341         -    bFlush = pSorter->iMemory && (pSorter->iMemory+nReq) > pSorter->mxPmaSize;
  1342         -  }else{
  1343         -    bFlush = (
  1344         -        (pSorter->nInMemory > pSorter->mxPmaSize)
  1345         -     || (pSorter->nInMemory > pSorter->mnPmaSize && sqlite3HeapNearlyFull())
  1346         -    );
  1347         -  }
  1348         -  if( bFlush ){
  1349         -    rc = vdbeSorterFlushPMA(db, pCsr, 0);
  1350         -    pSorter->nInMemory = 0;
  1351         -    pSorter->iMemory = 0;
  1352         -    assert( rc!=SQLITE_OK || pSorter->pRecord==0 );
         1342  +  if( pSorter->mxPmaSize ){
         1343  +    if( pSorter->aMemory ){
         1344  +      bFlush = pSorter->iMemory && (pSorter->iMemory+nReq) > pSorter->mxPmaSize;
         1345  +    }else{
         1346  +      bFlush = (
         1347  +          (pSorter->nInMemory > pSorter->mxPmaSize)
         1348  +       || (pSorter->nInMemory > pSorter->mnPmaSize && sqlite3HeapNearlyFull())
         1349  +      );
         1350  +    }
         1351  +    if( bFlush ){
         1352  +      rc = vdbeSorterFlushPMA(db, pCsr, 0);
         1353  +      pSorter->nInMemory = 0;
         1354  +      pSorter->iMemory = 0;
         1355  +      assert( rc!=SQLITE_OK || pSorter->pRecord==0 );
         1356  +    }
  1353   1357     }
  1354   1358   
  1355   1359     pSorter->nInMemory += nPMA;
  1356   1360   
  1357   1361     if( pSorter->aMemory ){
  1358   1362       int nMin = pSorter->iMemory + nReq;
  1359   1363   
................................................................................
  1371   1375         pSorter->nMemory = nNew;
  1372   1376       }
  1373   1377   
  1374   1378       pNew = (SorterRecord*)&pSorter->aMemory[pSorter->iMemory];
  1375   1379       pSorter->iMemory += ROUND8(nReq);
  1376   1380       pNew->u.iNext = (u8*)(pSorter->pRecord) - pSorter->aMemory;
  1377   1381     }else{
  1378         -    pNew = (SorterRecord *)sqlite3Malloc(pVal->n+sizeof(SorterRecord));
         1382  +    pNew = (SorterRecord *)sqlite3Malloc(nReq);
  1379   1383       if( pNew==0 ){
  1380   1384         return SQLITE_NOMEM;
  1381   1385       }
  1382   1386       pNew->u.pNext = pSorter->pRecord;
  1383   1387     }
  1384   1388   
  1385   1389     memcpy(SRVAL(pNew), pVal->z, pVal->n);