SQLite

Check-in [1a8cf0a043]
Login

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

Overview
Comment:Further modifications to new code to better handle corrupt databases.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | defrag-opt
Files: files | file ages | folders
SHA1: 1a8cf0a043347772ac54d150d634c32845beee8b
User & Date: dan 2014-10-25 20:36:28.557
Context
2014-10-27
07:01
Merge trunk with this branch. (check-in: a13df3013b user: dan tags: defrag-opt)
2014-10-25
20:36
Further modifications to new code to better handle corrupt databases. (check-in: 1a8cf0a043 user: dan tags: defrag-opt)
2014-10-24
20:57
Ensure that the "Any prior cache entry associated with newKey is guaranteed not to be pinned" guarantee made to xRekey implementations is not violated. (check-in: ecc3544e71 user: dan tags: defrag-opt)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/btree.c.
6095
6096
6097
6098
6099
6100
6101

6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114

6115
6116
6117
6118
6119
6120
6121
  MemPage *pPg,                   /* Page to edit */
  int nCell,                      /* Cells to delete */
  u8 **apCell,                    /* Array of cells */
  u16 *szCell                     /* Array of cell sizes */
){
  u8 * const aData = pPg->aData;
  u8 * const pEnd = &aData[pPg->pBt->usableSize];

  int nRet = 0;
  int i;
  u8 *pFree = 0;
  int szFree = 0;

  for(i=0; i<nCell; i++){
    u8 *pCell = apCell[i];
    if( pCell>aData && pCell<pEnd ){
      int sz = szCell[i];
      if( pFree!=(pCell + sz) ){
        if( pFree ) freeSpace(pPg, pFree - aData, szFree);
        pFree = pCell;
        szFree = sz;

      }else{
        pFree = pCell;
        szFree += sz;
      }
      nRet++;
    }
  }







>







|





>







6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
  MemPage *pPg,                   /* Page to edit */
  int nCell,                      /* Cells to delete */
  u8 **apCell,                    /* Array of cells */
  u16 *szCell                     /* Array of cell sizes */
){
  u8 * const aData = pPg->aData;
  u8 * const pEnd = &aData[pPg->pBt->usableSize];
  u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize];
  int nRet = 0;
  int i;
  u8 *pFree = 0;
  int szFree = 0;

  for(i=0; i<nCell; i++){
    u8 *pCell = apCell[i];
    if( pCell>=pStart && pCell<pEnd ){
      int sz = szCell[i];
      if( pFree!=(pCell + sz) ){
        if( pFree ) freeSpace(pPg, pFree - aData, szFree);
        pFree = pCell;
        szFree = sz;
        if( pFree+sz>pEnd ) return 0;
      }else{
        pFree = pCell;
        szFree += sz;
      }
      nRet++;
    }
  }
6850
6851
6852
6853
6854
6855
6856












6857
6858
6859
6860
6861
6862
6863
  **
  ** When NB==3, this one optimization makes the database about 25% faster 
  ** for large insertions and deletions.
  */
  for(i=0; i<nNew; i++){
    aPgno[i] = apNew[i]->pgno;
    aPgFlags[i] = apNew[i]->pDbPage->flags;












  }
  for(i=0; i<nNew; i++){
    int iBest = 0;                /* aPgno[] index of page number to use */
    Pgno pgno;                    /* Page number to use */
    for(j=1; j<nNew; j++){
      if( aPgno[j]<aPgno[iBest] ) iBest = j;
    }







>
>
>
>
>
>
>
>
>
>
>
>







6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
  **
  ** When NB==3, this one optimization makes the database about 25% faster 
  ** for large insertions and deletions.
  */
  for(i=0; i<nNew; i++){
    aPgno[i] = apNew[i]->pgno;
    aPgFlags[i] = apNew[i]->pDbPage->flags;
    for(j=0; j<i; j++){
      if( aPgno[j]==aPgno[i] ){
        /* This branch is taken if the set of sibling pages somehow contains
        ** duplicate entries. This can happen if the database is corrupt. 
        ** It would be simpler to detect this as part of the loop below, but
        ** in order to avoid populating the pager cache with two separate
        ** objects associated with the same page number.  */
        assert( CORRUPT_DB );
        rc = SQLITE_CORRUPT_BKPT;
        goto balance_cleanup;
      }
    }
  }
  for(i=0; i<nNew; i++){
    int iBest = 0;                /* aPgno[] index of page number to use */
    Pgno pgno;                    /* Page number to use */
    for(j=1; j<nNew; j++){
      if( aPgno[j]<aPgno[iBest] ) iBest = j;
    }
7058
7059
7060
7061
7062
7063
7064
7065

7066
7067
7068
7069
7070

7071
7072
7073
7074
7075
7076
7077
    ** for which the pointer is stored within the content being copied.
    **
    ** The second assert below verifies that the child page is defragmented
    ** (it must be, as it was just reconstructed using assemblePage()). This
    ** is important if the parent page happens to be page 1 of the database
    ** image.  */
    assert( nNew==1 );
    defragmentPage(apNew[0]);

    assert( apNew[0]->nFree == 
        (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2) 
    );
    copyNodeContent(apNew[0], pParent, &rc);
    freePage(apNew[0], &rc);

  }else if( ISAUTOVACUUM && !leafCorrection ){
    /* Fix the pointer map entries associated with the right-child of each
    ** sibling page. All other pointer map entries have already been taken
    ** care of.  */
    for(i=0; i<nNew; i++){
      u32 key = get4byte(&apNew[i]->aData[8]);
      ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &rc);







|
>
|
|
|
|
|
>







7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
    ** for which the pointer is stored within the content being copied.
    **
    ** The second assert below verifies that the child page is defragmented
    ** (it must be, as it was just reconstructed using assemblePage()). This
    ** is important if the parent page happens to be page 1 of the database
    ** image.  */
    assert( nNew==1 );
    rc = defragmentPage(apNew[0]);
    if( rc==SQLITE_OK ){
      assert( apNew[0]->nFree == 
          (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2)
      );
      copyNodeContent(apNew[0], pParent, &rc);
      freePage(apNew[0], &rc);
    }
  }else if( ISAUTOVACUUM && !leafCorrection ){
    /* Fix the pointer map entries associated with the right-child of each
    ** sibling page. All other pointer map entries have already been taken
    ** care of.  */
    for(i=0; i<nNew; i++){
      u32 key = get4byte(&apNew[i]->aData[8]);
      ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &rc);