SQLite

Check-in [df2c285cb9]
Login

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

Overview
Comment:Reduce the number of paths in btreeCopyFile(). (CVS 6124)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: df2c285cb99ac188c96dd1a4e6a30f689195a150
User & Date: danielk1977 2009-01-06 18:21:09.000
Context
2009-01-06
18:43
Now that we have permutations.test, it is really only necessary to run all.test for a single cycle. So make that the default. (CVS 6125) (check-in: 3c2f292fb7 user: drh tags: trunk)
18:21
Reduce the number of paths in btreeCopyFile(). (CVS 6124) (check-in: df2c285cb9 user: danielk1977 tags: trunk)
17:52
Modify test_journal.c to verify the page data being written to the journal file. (CVS 6123) (check-in: 0d258956f8 user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/btree.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
** 2004 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.555 2009/01/02 21:08:09 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
** 2004 April 6
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.556 2009/01/06 18:21:09 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
** Including a description of file format and an overview of operation.
*/
#include "btreeInt.h"

7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345

7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
  ** page size used by the pager associated with B-Tree pTo.
  **
  ** For example, say the page-size of pTo is 2048 bytes and the original 
  ** number of pages is 5 (10 KB file). If pFrom has a page size of 1024 
  ** bytes and 9 pages, then the file needs to be truncated to 9KB.
  */
  if( rc==SQLITE_OK ){
    if( nFromPageSize!=nToPageSize ){
      sqlite3_file *pFile = sqlite3PagerFile(pBtTo->pPager);
      i64 iSize = (i64)nFromPageSize * (i64)nFromPage;
      i64 iNow = (i64)((nToPage>nNewPage)?nToPage:nNewPage) * (i64)nToPageSize; 
      i64 iPending = ((i64)PENDING_BYTE_PAGE(pBtTo)-1) *(i64)nToPageSize;
  
      assert( iSize<=iNow );
  
      /* Commit phase one syncs the journal file associated with pTo 
      ** containing the original data. It does not sync the database file
      ** itself. After doing this it is safe to use OsTruncate() and other
      ** file APIs on the database file directly.
      */
      pBtTo->db = pTo->db;
      rc = sqlite3PagerCommitPhaseOne(pBtTo->pPager, 0, 1);
      if( iSize<iNow && rc==SQLITE_OK ){
        rc = sqlite3OsTruncate(pFile, iSize);
      }
  
      /* The loop that copied data from database pFrom to pTo did not
      ** populate the locking page of database pTo. If the page-size of
      ** pFrom is smaller than that of pTo, this means some data will
      ** not have been copied. 
      **
      ** This block copies the missing data from database pFrom to pTo 
      ** using file APIs. This is safe because at this point we know that
      ** all of the original data from pTo has been synced into the 
      ** journal file. At this point it would be safe to do anything at
      ** all to the database file except truncate it to zero bytes.
      */
      if( rc==SQLITE_OK && nFromPageSize<nToPageSize && iSize>iPending){
        i64 iOff;
        for(
          iOff=iPending; 
          rc==SQLITE_OK && iOff<(iPending+nToPageSize); 
          iOff += nFromPageSize
        ){
          DbPage *pFromPage = 0;
          Pgno iFrom = (Pgno)(iOff/nFromPageSize)+1;
  
          if( iFrom==PENDING_BYTE_PAGE(pBtFrom) || iFrom>nFromPage ){
            continue;
          }
  
          rc = sqlite3PagerGet(pBtFrom->pPager, iFrom, &pFromPage);
          if( rc==SQLITE_OK ){
            char *zFrom = sqlite3PagerGetData(pFromPage);
            rc = sqlite3OsWrite(pFile, zFrom, nFromPageSize, iOff);
            sqlite3PagerUnref(pFromPage);
          }
        }
      }
  

      /* Sync the database file */
      if( rc==SQLITE_OK ){
        rc = sqlite3PagerSync(pBtTo->pPager);
      }
    }else{
      rc = sqlite3PagerTruncate(pBtTo->pPager, nNewPage);
    }
    if( rc==SQLITE_OK ){
      pBtTo->pageSizeFixed = 0;
    }
  }

  if( rc ){
    sqlite3BtreeRollback(pTo);
  }

  return rc;  
}
int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
  int rc;
  sqlite3BtreeEnter(pTo);
  sqlite3BtreeEnter(pFrom);
  rc = btreeCopyFile(pTo, pFrom);
  sqlite3BtreeLeave(pFrom);







<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
<
<
<
|
|
|
<
<
<



|







7286
7287
7288
7289
7290
7291
7292

7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349



7350
7351
7352



7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
  ** page size used by the pager associated with B-Tree pTo.
  **
  ** For example, say the page-size of pTo is 2048 bytes and the original 
  ** number of pages is 5 (10 KB file). If pFrom has a page size of 1024 
  ** bytes and 9 pages, then the file needs to be truncated to 9KB.
  */
  if( rc==SQLITE_OK ){

    sqlite3_file *pFile = sqlite3PagerFile(pBtTo->pPager);
    i64 iSize = (i64)nFromPageSize * (i64)nFromPage;
    i64 iNow = (i64)((nToPage>nNewPage)?nToPage:nNewPage) * (i64)nToPageSize; 
    i64 iPending = ((i64)PENDING_BYTE_PAGE(pBtTo)-1) *(i64)nToPageSize;

    assert( iSize<=iNow );

    /* Commit phase one syncs the journal file associated with pTo 
    ** containing the original data. It does not sync the database file
    ** itself. After doing this it is safe to use OsTruncate() and other
    ** file APIs on the database file directly.
    */
    pBtTo->db = pTo->db;
    rc = sqlite3PagerCommitPhaseOne(pBtTo->pPager, 0, 1);
    if( iSize<iNow && rc==SQLITE_OK ){
      rc = sqlite3OsTruncate(pFile, iSize);
    }

    /* The loop that copied data from database pFrom to pTo did not
    ** populate the locking page of database pTo. If the page-size of
    ** pFrom is smaller than that of pTo, this means some data will
    ** not have been copied. 
    **
    ** This block copies the missing data from database pFrom to pTo 
    ** using file APIs. This is safe because at this point we know that
    ** all of the original data from pTo has been synced into the 
    ** journal file. At this point it would be safe to do anything at
    ** all to the database file except truncate it to zero bytes.
    */
    if( rc==SQLITE_OK && nFromPageSize<nToPageSize && iSize>iPending){
      i64 iOff;
      for(
        iOff=iPending; 
        rc==SQLITE_OK && iOff<(iPending+nToPageSize); 
        iOff += nFromPageSize
      ){
        DbPage *pFromPage = 0;
        Pgno iFrom = (Pgno)(iOff/nFromPageSize)+1;

        if( iFrom==PENDING_BYTE_PAGE(pBtFrom) || iFrom>nFromPage ){
          continue;
        }

        rc = sqlite3PagerGet(pBtFrom->pPager, iFrom, &pFromPage);
        if( rc==SQLITE_OK ){
          char *zFrom = sqlite3PagerGetData(pFromPage);
          rc = sqlite3OsWrite(pFile, zFrom, nFromPageSize, iOff);
          sqlite3PagerUnref(pFromPage);
        }
      }
    }
  }

  /* Sync the database file */
  if( rc==SQLITE_OK ){
    rc = sqlite3PagerSync(pBtTo->pPager);
  }



  if( rc==SQLITE_OK ){
    pBtTo->pageSizeFixed = 0;
  }else{



    sqlite3BtreeRollback(pTo);
  }

  return rc;
}
int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
  int rc;
  sqlite3BtreeEnter(pTo);
  sqlite3BtreeEnter(pFrom);
  rc = btreeCopyFile(pTo, pFrom);
  sqlite3BtreeLeave(pFrom);