SQLite

Check-in [28fd0a50ca]
Login

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

Overview
Comment:Performance enhancement: avoid calling reparentChildPages() from balance_nonroot(). (CVS 5743)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 28fd0a50ca8529892f5b1ababd38d494889eed6d
User & Date: danielk1977 2008-09-26 17:31:55.000
Context
2008-09-26
20:02
Make sure the queueMutex is held prior to writing the pQueueLast field of the write queue in the async demonstration code. Ticket #3405. (CVS 5744) (check-in: 5622a1e285 user: drh tags: trunk)
17:31
Performance enhancement: avoid calling reparentChildPages() from balance_nonroot(). (CVS 5743) (check-in: 28fd0a50ca user: danielk1977 tags: trunk)
2008-09-24
14:03
On windows, avoid running those tests in exclusive.test that require the journal file to be externally accessed while SQLite is holding it open. This doesn't work on windows. (CVS 5742) (check-in: 5debf12fa4 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.516 2008/09/19 16:39:38 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"












|







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.517 2008/09/26 17:31:55 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"

5582
5583
5584
5585
5586
5587
5588


5589




























5590

5591
5592
5593
5594
5595
5596

5597
5598
5599
5600
5601
5602
5603
  }else{
    /* Right-most sibling is the left child of the first entry in pParent
    ** past the right-most divider entry */
    put4byte(findOverflowCell(pParent, nxDiv), pgnoNew[nNew-1]);
  }

  /*


  ** Reparent children of all cells.




























  */

  for(i=0; i<nNew; i++){
    rc = reparentChildPages(apNew[i], 0);
    if( rc!=SQLITE_OK ) goto balance_cleanup;
  }
  rc = reparentChildPages(pParent, 0);
  if( rc!=SQLITE_OK ) goto balance_cleanup;


  /*
  ** Balance the parent page.  Note that the current page (pPage) might
  ** have been added to the freelist so it might no longer be initialized.
  ** But the parent page will always be initialized.
  */
  assert( pParent->isInit==PAGE_ISINIT_FULL );







>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>






>







5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
  }else{
    /* Right-most sibling is the left child of the first entry in pParent
    ** past the right-most divider entry */
    put4byte(findOverflowCell(pParent, nxDiv), pgnoNew[nNew-1]);
  }

  /*
  ** At this point we used to call reparentChildPages() to make sure that
  ** the MemPage.pParent and MemPage.idxParent variables are correct for
  ** all children of the pages modified by this balance operation. Even
  ** if this is an auto-vacuum database there is no need to update the
  ** pointer-map entries for child pages - that has already been done
  ** by the block above.
  **
  ** However, this is no longer necessary because the MemPage.pParent and
  ** MemPage.idxParent variables are only assumed to be valid when there
  ** are one or more references to the page (when isInit==PAGE_ISINIT_FULL). 
  ** At this point we can account for all references to the pages
  ** manipulated by this function and deduce that it is not necessary to
  ** update these two variables because:
  **
  **   a) it must have been called, directly or indirectly, from BtreeInsert()
  **      or BtreeDelete(). Both these functions call saveAllCursors(), so
  **      we can be sure that there exactly one write-cursor (and no
  **      read-cursors) open on the b-tree being manipulated. No other
  **      cursor may be holding references to any pages in the b-tree.
  **
  **   b) After this function returns, the one open write-cursor will be
  **      moved to point at the root of the table using moveToRoot(). The
  **      code that does this (see BtreeInsert() and BtreeDelete()) ensures
  **      that the MemPage.pParent variables are not used to find the root
  **      page of the b-tree, it is located using BtCursor.pgnoRoot.
  **
  **   c) the other page references are those held by this function, on
  **      the pages in apNew[] and apOld[]. They are about to be released.
  **
  ** Therefore, no need to call reparentChildPages(). This can be a
  ** significant performance boost.
  */
#if 0
  for(i=0; i<nNew; i++){
    rc = reparentChildPages(apNew[i], 0);
    if( rc!=SQLITE_OK ) goto balance_cleanup;
  }
  rc = reparentChildPages(pParent, 0);
  if( rc!=SQLITE_OK ) goto balance_cleanup;
#endif

  /*
  ** Balance the parent page.  Note that the current page (pPage) might
  ** have been added to the freelist so it might no longer be initialized.
  ** But the parent page will always be initialized.
  */
  assert( pParent->isInit==PAGE_ISINIT_FULL );
5969
5970
5971
5972
5973
5974
5975







5976
5977
5978
5979
5980
5981
5982
  }else{
    assert( pPage->leaf );
  }
  rc = insertCell(pPage, pCur->idx, newCell, szNew, 0, 0);
  if( rc!=SQLITE_OK ) goto end_insert;
  rc = balance(pPage, 1);
  if( rc==SQLITE_OK ){







    moveToRoot(pCur);
  }
end_insert:
  return rc;
}

/*







>
>
>
>
>
>
>







6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
  }else{
    assert( pPage->leaf );
  }
  rc = insertCell(pPage, pCur->idx, newCell, szNew, 0, 0);
  if( rc!=SQLITE_OK ) goto end_insert;
  rc = balance(pPage, 1);
  if( rc==SQLITE_OK ){
    /* balance() may have messed up the chain of MemPage.pParent pointers.
    ** To prevent moveToRoot() from trying to use them to locate the root
    ** page of this table, release the reference to the current page before
    ** calling it.
    */
    releasePage(pCur->pPage);
    pCur->pPage = 0;
    moveToRoot(pCur);
  }
end_insert:
  return rc;
}

/*
6085
6086
6087
6088
6089
6090
6091







6092
6093
6094
6095
6096
6097
6098
  }else{
    TRACE(("DELETE: table=%d delete from leaf %d\n",
       pCur->pgnoRoot, pPage->pgno));
    dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell));
    rc = balance(pPage, 0);
  }
  if( rc==SQLITE_OK ){







    moveToRoot(pCur);
  }
  return rc;
}

/*
** Create a new BTree table.  Write into *piTable the page







>
>
>
>
>
>
>







6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
  }else{
    TRACE(("DELETE: table=%d delete from leaf %d\n",
       pCur->pgnoRoot, pPage->pgno));
    dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell));
    rc = balance(pPage, 0);
  }
  if( rc==SQLITE_OK ){
    /* balance() may have messed up the chain of MemPage.pParent pointers.
    ** To prevent moveToRoot() from trying to use them to locate the root
    ** page of this table, release the reference to the current page before
    ** calling it.
    */
    releasePage(pCur->pPage);
    pCur->pPage = 0;
    moveToRoot(pCur);
  }
  return rc;
}

/*
** Create a new BTree table.  Write into *piTable the page