/ Check-in [a9a64592]
Login

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

Overview
Comment:Remove some dead code. Fix a faulty assert(). Improve some variable names.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | merge-sort
Files: files | file ages | folders
SHA1: a9a64592cf88580cb254fb0aac65a2f2085976ec
User & Date: drh 2011-09-02 21:42:33
Context
2011-09-03
00:17
The build works again with -DSQLITE_OMIT_MERGE_SORT. The merge-sorter now avoids spilling to disk (letting the in-memory linked list grow without bound) if PRAGMA temp_store=3. check-in: 68e26c44 user: drh tags: merge-sort
2011-09-02
21:42
Remove some dead code. Fix a faulty assert(). Improve some variable names. check-in: a9a64592 user: drh tags: merge-sort
18:03
Combine two malloc calls in vdbesort.c. check-in: cf48ad83 user: dan tags: merge-sort
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
    */
    zeroPage(pPage, PTF_INTKEY|PTF_LEAF );
    releasePage(pPage);
  }
  return rc;  
}
int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
  BtShared *pBt = p->pBt;
  int rc;
  sqlite3BtreeEnter(p);
  rc = btreeDropTable(p, iTable, piMoved);
  sqlite3BtreeLeave(p);
  return rc;
}








<







7281
7282
7283
7284
7285
7286
7287

7288
7289
7290
7291
7292
7293
7294
    */
    zeroPage(pPage, PTF_INTKEY|PTF_LEAF );
    releasePage(pPage);
  }
  return rc;  
}
int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){

  int rc;
  sqlite3BtreeEnter(p);
  rc = btreeDropTable(p, iTable, piMoved);
  sqlite3BtreeLeave(p);
  return rc;
}

Changes to src/pager.c.

617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
...
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
....
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
....
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
  u8 fullSync;                /* Do extra syncs of the journal for robustness */
  u8 ckptSyncFlags;           /* SYNC_NORMAL or SYNC_FULL for checkpoint */
  u8 syncFlags;               /* SYNC_NORMAL or SYNC_FULL otherwise */
  u8 tempFile;                /* zFilename is a temporary file */
  u8 readOnly;                /* True for a read-only database */
  u8 memDb;                   /* True to inhibit all file I/O */
  u8 hasSeenStress;           /* pagerStress() called one or more times */
  u8 isSorter;                /* True for a PAGER_SORTER */

  /**************************************************************************
  ** The following block contains those class members that change during
  ** routine opertion.  Class members not in this block are either fixed
  ** when the pager is first created or else only change when there is a
  ** significant mode change (such as changing the page_size, locking_mode,
  ** or the journal_mode).  From another view, these class members describe
................................................................................
    assert( p->journalMode==PAGER_JOURNALMODE_OFF 
         || p->journalMode==PAGER_JOURNALMODE_MEMORY 
    );
    assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN );
    assert( pagerUseWal(p)==0 );
  }

  /* A sorter is a temp file that never spills to disk and always has
  ** the doNotSpill flag set
  */
  if( p->isSorter ){
    assert( p->tempFile );
    assert( p->doNotSpill );
    assert( p->fd->pMethods==0 );
  }

  /* If changeCountDone is set, a RESERVED lock or greater must be held
  ** on the file.
  */
  assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK );
  assert( p->eLock!=PENDING_LOCK );

  switch( p->eState ){
................................................................................
  }else if( memDb ){
    pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
  }
  /* pPager->xBusyHandler = 0; */
  /* pPager->pBusyHandlerArg = 0; */
  pPager->xReiniter = xReinit;
  /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
#ifndef SQLITE_OMIT_MERGE_SORT
  if( flags & PAGER_SORTER ){
    pPager->doNotSpill = 1;
    pPager->isSorter = 1;
  }
#endif

  *ppPager = pPager;
  return SQLITE_OK;
}



................................................................................
/*
** Return true if this is an in-memory pager.
*/
int sqlite3PagerIsMemdb(Pager *pPager){
  return MEMDB;
}

#ifndef SQLITE_OMIT_MERGE_SORT
/*
** Return true if the pager has seen a pagerStress callback.
*/
int sqlite3PagerUnderStress(Pager *pPager){
  assert( pPager->isSorter );
  assert( pPager->doNotSpill );
  return pPager->hasSeenStress;
}
#endif

/*
** Check that there are at least nSavepoint savepoints open. If there are
** currently less than nSavepoints open, then open one or more savepoints
** to make up the difference. If the number of savepoints is already
** equal to nSavepoint, then this function is a no-op.
**
** If a memory allocation fails, SQLITE_NOMEM is returned. If an error 







<







 







<
<
<
<
<
<
<
<
<







 







<
<
<
<
<
<







 







<
<
<
<
<
<
<
<
<
<
<







617
618
619
620
621
622
623

624
625
626
627
628
629
630
...
840
841
842
843
844
845
846









847
848
849
850
851
852
853
....
4543
4544
4545
4546
4547
4548
4549






4550
4551
4552
4553
4554
4555
4556
....
6087
6088
6089
6090
6091
6092
6093











6094
6095
6096
6097
6098
6099
6100
  u8 fullSync;                /* Do extra syncs of the journal for robustness */
  u8 ckptSyncFlags;           /* SYNC_NORMAL or SYNC_FULL for checkpoint */
  u8 syncFlags;               /* SYNC_NORMAL or SYNC_FULL otherwise */
  u8 tempFile;                /* zFilename is a temporary file */
  u8 readOnly;                /* True for a read-only database */
  u8 memDb;                   /* True to inhibit all file I/O */
  u8 hasSeenStress;           /* pagerStress() called one or more times */


  /**************************************************************************
  ** The following block contains those class members that change during
  ** routine opertion.  Class members not in this block are either fixed
  ** when the pager is first created or else only change when there is a
  ** significant mode change (such as changing the page_size, locking_mode,
  ** or the journal_mode).  From another view, these class members describe
................................................................................
    assert( p->journalMode==PAGER_JOURNALMODE_OFF 
         || p->journalMode==PAGER_JOURNALMODE_MEMORY 
    );
    assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN );
    assert( pagerUseWal(p)==0 );
  }










  /* If changeCountDone is set, a RESERVED lock or greater must be held
  ** on the file.
  */
  assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK );
  assert( p->eLock!=PENDING_LOCK );

  switch( p->eState ){
................................................................................
  }else if( memDb ){
    pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
  }
  /* pPager->xBusyHandler = 0; */
  /* pPager->pBusyHandlerArg = 0; */
  pPager->xReiniter = xReinit;
  /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */







  *ppPager = pPager;
  return SQLITE_OK;
}



................................................................................
/*
** Return true if this is an in-memory pager.
*/
int sqlite3PagerIsMemdb(Pager *pPager){
  return MEMDB;
}












/*
** Check that there are at least nSavepoint savepoints open. If there are
** currently less than nSavepoints open, then open one or more savepoints
** to make up the difference. If the number of savepoints is already
** equal to nSavepoint, then this function is a no-op.
**
** If a memory allocation fails, SQLITE_NOMEM is returned. If an error 

Changes to src/pager.h.

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
const char *sqlite3PagerFilename(Pager*);
const sqlite3_vfs *sqlite3PagerVfs(Pager*);
sqlite3_file *sqlite3PagerFile(Pager*);
const char *sqlite3PagerJournalname(Pager*);
int sqlite3PagerNosync(Pager*);
void *sqlite3PagerTempSpace(Pager*);
int sqlite3PagerIsMemdb(Pager*);
#ifndef SQLITE_OMIT_MERGE_SORT
int sqlite3PagerUnderStress(Pager*);
#endif

/* Functions used to truncate the database file. */
void sqlite3PagerTruncateImage(Pager*,Pgno);

#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
void *sqlite3PagerCodec(DbPage *);
#endif







<
<
<







152
153
154
155
156
157
158



159
160
161
162
163
164
165
const char *sqlite3PagerFilename(Pager*);
const sqlite3_vfs *sqlite3PagerVfs(Pager*);
sqlite3_file *sqlite3PagerFile(Pager*);
const char *sqlite3PagerJournalname(Pager*);
int sqlite3PagerNosync(Pager*);
void *sqlite3PagerTempSpace(Pager*);
int sqlite3PagerIsMemdb(Pager*);




/* Functions used to truncate the database file. */
void sqlite3PagerTruncateImage(Pager*,Pgno);

#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
void *sqlite3PagerCodec(DbPage *);
#endif

Changes to src/vdbesort.c.

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
...
396
397
398
399
400
401
402


403
404
405
406
407
408
409
410
411
412


413
414
415
416
417
418
419
...
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
...
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
...
916
917
918
919
920
921
922
923
924
925
926
927
  VdbeSorterIter *aIter;          /* Array of iterators to merge */
  int *aTree;                     /* Current state of incremental merge */
  i64 iWriteOff;                  /* Current write offset within file pTemp1 */
  i64 iReadOff;                   /* Current read offset within file pTemp1 */
  sqlite3_file *pTemp1;           /* PMA file 1 */
  int nPMA;                       /* Number of PMAs stored in pTemp1 */
  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 */
};

/*
** The following type is an iterator for a PMA. It caches the current key in 
** variables nKey/aKey. If the iterator is at EOF, pFile==0.
................................................................................
}

/*
** Initialize the temporary index cursor just opened as a sorter cursor.
*/
int sqlite3VdbeSorterInit(sqlite3 *db, VdbeCursor *pCsr){
  int pgsz;                       /* Page size of main database */



  assert( pCsr->pKeyInfo && pCsr->pBt==0 );
  pCsr->pSorter = sqlite3DbMallocZero(db, sizeof(VdbeSorter));
  if( pCsr->pSorter==0 ){
    return SQLITE_NOMEM;
  }

  pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
  pCsr->pSorter->nLimit1 = 10 * pgsz;
  pCsr->pSorter->nLimit2 = db->aDb[0].pSchema->cache_size * pgsz;



  return SQLITE_OK;
}

/*
** Free the list of sorted records starting at pRecord.
*/
................................................................................
      rc = vdbeSorterMerge(db, pCsr, p, aSlot[i], &p);
    }else{
      vdbeSorterRecordFree(db, aSlot[i]);
    }
  }
  pSorter->pRecord = p;

#if 0
  {
    SorterRecord *pTmp1 = 0;
    SorterRecord *pTmp2;
    for(pTmp2=pSorter->pRecord; pTmp2 && rc==SQLITE_OK; pTmp2=pTmp2->pNext){
      if( pTmp1 ){
        int res;
        rc = vdbeSorterCompare(pCsr, 
            0, pTmp1->pVal, pTmp1->nVal, pTmp2->pVal, pTmp2->nVal, &res
        );
        assert( rc!=SQLITE_OK || res<0 );
      }
      pTmp1 = pTmp2;
    }
  }
#endif

  if( rc!=SQLITE_OK ){
  }
  sqlite3_free(aSlot);
  return rc;
}


/*
** Write the current contents of the in-memory linked-list to a PMA. Return
................................................................................
  **   * The total memory allocated for the in-memory list is greater 
  **     than (page-size * cache-size), or
  **
  **   * The total memory allocated for the in-memory list is greater 
  **     than (page-size * 10) and sqlite3HeapNearlyFull() returns true.
  */
  if( rc==SQLITE_OK && (
        (pSorter->nInMemory>pSorter->nLimit2)
     || (pSorter->nInMemory>pSorter->nLimit1 && sqlite3HeapNearlyFull())
  )){
    rc = vdbeSorterListToPMA(db, pCsr);
    pSorter->nInMemory = 0;
  }

  return rc;
}
................................................................................
){
  int rc;
  VdbeSorter *pSorter = pCsr->pSorter;
  void *pKey; int nKey;           /* Sorter key to compare pVal with */

  pKey = vdbeSorterRowkey(pSorter, &nKey);
  rc = vdbeSorterCompare(pCsr, 1, pVal->z, pVal->n, pKey, nKey, pRes);
  assert( rc!=SQLITE_OK || *pRes<=0 );
  return rc;
}

#endif /* #ifndef SQLITE_OMIT_MERGE_SORT */







|
|







 







>
>


|
|




|
|
>
>







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|
|







 







|




98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
...
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
...
557
558
559
560
561
562
563



















564
565
566
567
568
569
570
...
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
...
901
902
903
904
905
906
907
908
909
910
911
912
  VdbeSorterIter *aIter;          /* Array of iterators to merge */
  int *aTree;                     /* Current state of incremental merge */
  i64 iWriteOff;                  /* Current write offset within file pTemp1 */
  i64 iReadOff;                   /* Current read offset within file pTemp1 */
  sqlite3_file *pTemp1;           /* PMA file 1 */
  int nPMA;                       /* Number of PMAs stored in pTemp1 */
  SorterRecord *pRecord;          /* Head of in-memory record list */
  int mnPmaSize;                  /* Minimum PMA size, in bytes */
  int mxPmaSize;                  /* Maximum PMA size, in bytes.  0==no limit */
  char *aSpace;                   /* Space for UnpackRecord() */
  int nSpace;                     /* Size of aSpace in bytes */
};

/*
** The following type is an iterator for a PMA. It caches the current key in 
** variables nKey/aKey. If the iterator is at EOF, pFile==0.
................................................................................
}

/*
** Initialize the temporary index cursor just opened as a sorter cursor.
*/
int sqlite3VdbeSorterInit(sqlite3 *db, VdbeCursor *pCsr){
  int pgsz;                       /* Page size of main database */
  int mxCache;                    /* Cache size */
  VdbeSorter *pSorter;            /* The new sorter */

  assert( pCsr->pKeyInfo && pCsr->pBt==0 );
  pCsr->pSorter = pSorter = sqlite3DbMallocZero(db, sizeof(VdbeSorter));
  if( pSorter==0 ){
    return SQLITE_NOMEM;
  }

  pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
  pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz;
  mxCache = db->aDb[0].pSchema->cache_size;
  if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING;
  pSorter->mxPmaSize = mxCache * pgsz;

  return SQLITE_OK;
}

/*
** Free the list of sorted records starting at pRecord.
*/
................................................................................
      rc = vdbeSorterMerge(db, pCsr, p, aSlot[i], &p);
    }else{
      vdbeSorterRecordFree(db, aSlot[i]);
    }
  }
  pSorter->pRecord = p;




















  sqlite3_free(aSlot);
  return rc;
}


/*
** Write the current contents of the in-memory linked-list to a PMA. Return
................................................................................
  **   * The total memory allocated for the in-memory list is greater 
  **     than (page-size * cache-size), or
  **
  **   * The total memory allocated for the in-memory list is greater 
  **     than (page-size * 10) and sqlite3HeapNearlyFull() returns true.
  */
  if( rc==SQLITE_OK && (
        (pSorter->nInMemory>pSorter->mxPmaSize)
     || (pSorter->nInMemory>pSorter->mnPmaSize && sqlite3HeapNearlyFull())
  )){
    rc = vdbeSorterListToPMA(db, pCsr);
    pSorter->nInMemory = 0;
  }

  return rc;
}
................................................................................
){
  int rc;
  VdbeSorter *pSorter = pCsr->pSorter;
  void *pKey; int nKey;           /* Sorter key to compare pVal with */

  pKey = vdbeSorterRowkey(pSorter, &nKey);
  rc = vdbeSorterCompare(pCsr, 1, pVal->z, pVal->n, pKey, nKey, pRes);
  assert( rc!=SQLITE_OK || pVal->db->mallocFailed || (*pRes)<=0 );
  return rc;
}

#endif /* #ifndef SQLITE_OMIT_MERGE_SORT */