mirror of
				https://github.com/sqlite/sqlite.git
				synced 2025-11-03 16:53:36 +03:00 
			
		
		
		
	More speed improvements. (CVS 1381)
FossilOrigin-Name: cf75cac9b6bd43e60c6e25042b194ec5c60e5671
This commit is contained in:
		
							
								
								
									
										14
									
								
								manifest
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								manifest
									
									
									
									
									
								
							@@ -1,5 +1,5 @@
 | 
			
		||||
C Optimized\svarint\sroutines\sand\stests\sadded.\s(CVS\s1380)
 | 
			
		||||
D 2004-05-14T16:50:06
 | 
			
		||||
C More\sspeed\simprovements.\s(CVS\s1381)
 | 
			
		||||
D 2004-05-14T19:08:18
 | 
			
		||||
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
 | 
			
		||||
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 | 
			
		||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
 | 
			
		||||
@@ -23,7 +23,7 @@ F sqlite.def fc4f5734786fe4743cfe2aa98eb2da4b089edb5f
 | 
			
		||||
F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
 | 
			
		||||
F src/attach.c c315c58cb16fd6e913b3bfa6412aedecb4567fa5
 | 
			
		||||
F src/auth.c 5c2f0bea4729c98c2be3b69d6b466fc51448fe79
 | 
			
		||||
F src/btree.c 71c689f16d00febbdee5f474b9bc570df404a7fc
 | 
			
		||||
F src/btree.c c263f1f26b28e0ac929b9807bccf50877335c1b8
 | 
			
		||||
F src/btree.h 6f51ad0ffebfba71295fcacdbe86007512200050
 | 
			
		||||
F src/btree_rb.c 9d7973e266ee6f9c61ce592f68742ce9cd5b10e5
 | 
			
		||||
F src/build.c e93f443a20eab57ffb77ff6244b1e09a1f7d9390
 | 
			
		||||
@@ -66,7 +66,7 @@ F src/vacuum.c c134702e023db8778e6be59ac0ea7b02315b5476
 | 
			
		||||
F src/vdbe.c fff79c08b3063d8d6f7b600fc6896c255c72238c
 | 
			
		||||
F src/vdbe.h 94457ca73bae972dc61bca33a4dccc2e6e14e2f8
 | 
			
		||||
F src/vdbeInt.h 03f4c3642482570a697a42a9bbb12908c6535bbe
 | 
			
		||||
F src/vdbeaux.c 4590e8f5e064ee1e269a0b969f6f28118daf325d
 | 
			
		||||
F src/vdbeaux.c 6cf897c49c1fde153d8b9e4c168714207f07cce3
 | 
			
		||||
F src/where.c 6957bbd333cc7ffa7b3878adbe67a095319daa54
 | 
			
		||||
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
 | 
			
		||||
F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83
 | 
			
		||||
@@ -191,7 +191,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
 | 
			
		||||
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
 | 
			
		||||
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
 | 
			
		||||
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
 | 
			
		||||
P cad47917267d32ab00c8b949151c8bc3c6638479
 | 
			
		||||
R 2f283a670b4184db072fa201634f4b5a
 | 
			
		||||
P d4e0933dc72b66157164610e0b03f339bc535fb9
 | 
			
		||||
R 9330d9bd11be003784ef684f1b9c1f25
 | 
			
		||||
U drh
 | 
			
		||||
Z a43ba40aa94121177ed5f96de31aa3ea
 | 
			
		||||
Z 185a62bf4f1e1cc9ef6d8083626f74a6
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +1 @@
 | 
			
		||||
d4e0933dc72b66157164610e0b03f339bc535fb9
 | 
			
		||||
cf75cac9b6bd43e60c6e25042b194ec5c60e5671
 | 
			
		||||
							
								
								
									
										170
									
								
								src/btree.c
									
									
									
									
									
								
							
							
						
						
									
										170
									
								
								src/btree.c
									
									
									
									
									
								
							@@ -9,7 +9,7 @@
 | 
			
		||||
**    May you share freely, never taking more than you give.
 | 
			
		||||
**
 | 
			
		||||
*************************************************************************
 | 
			
		||||
** $Id: btree.c,v 1.137 2004/05/14 16:50:06 drh Exp $
 | 
			
		||||
** $Id: btree.c,v 1.138 2004/05/14 19:08:18 drh Exp $
 | 
			
		||||
**
 | 
			
		||||
** This file implements a external (disk-based) database using BTrees.
 | 
			
		||||
** For a detailed discussion of BTrees, refer to
 | 
			
		||||
@@ -279,6 +279,20 @@ struct Btree {
 | 
			
		||||
};
 | 
			
		||||
typedef Btree Bt;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
** An instance of the following structure is used to hold information
 | 
			
		||||
** about a cell.  The parseCell() function fills the structure in.
 | 
			
		||||
*/
 | 
			
		||||
typedef struct CellInfo CellInfo;
 | 
			
		||||
struct CellInfo {
 | 
			
		||||
  i64 nKey;      /* The key for INTKEY tables, or number of bytes in key */
 | 
			
		||||
  u32 nData;     /* Number of bytes of data */
 | 
			
		||||
  u16 nHeader;   /* Size of the header in bytes */
 | 
			
		||||
  u16 nLocal;    /* Amount of payload held locally */
 | 
			
		||||
  u16 iOverflow; /* Offset to overflow page number.  Zero if none */
 | 
			
		||||
  u16 nSize;     /* Size of the cell */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
** A cursor is a pointer to a particular entry in the BTree.
 | 
			
		||||
** The entry is identified by its MemPage and the index in
 | 
			
		||||
@@ -293,26 +307,14 @@ struct BtCursor {
 | 
			
		||||
  Pgno pgnoRoot;            /* The root page of this tree */
 | 
			
		||||
  MemPage *pPage;           /* Page that contains the entry */
 | 
			
		||||
  int idx;                  /* Index of the entry in pPage->aCell[] */
 | 
			
		||||
  CellInfo info;            /* A parse of the cell we are pointing at */
 | 
			
		||||
  u8 infoValid;             /* True if information in BtCursor.info is valid */
 | 
			
		||||
  u8 wrFlag;                /* True if writable */
 | 
			
		||||
  u8 iMatch;                /* compare result from last sqlite3BtreeMoveto() */
 | 
			
		||||
  u8 isValid;               /* TRUE if points to a valid entry */
 | 
			
		||||
  u8 status;                /* Set to SQLITE_ABORT if cursors is invalidated */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
** An instance of the following structure is used to hold information
 | 
			
		||||
** about a cell.  The parseCell() function fills the structure in.
 | 
			
		||||
*/
 | 
			
		||||
typedef struct CellInfo CellInfo;
 | 
			
		||||
struct CellInfo {
 | 
			
		||||
  i64 nKey;      /* The key for INTKEY tables, or number of bytes in key */
 | 
			
		||||
  u32 nData;     /* Number of bytes of data */
 | 
			
		||||
  int nHeader;   /* Size of the header in bytes */
 | 
			
		||||
  int nLocal;    /* Amount of payload held locally */
 | 
			
		||||
  int iOverflow; /* Offset to overflow page number.  Zero if none */
 | 
			
		||||
  int nSize;     /* Size of the cell */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
** Read or write a two-, four-, and eight-byte big-endian integer values.
 | 
			
		||||
*/
 | 
			
		||||
@@ -675,7 +677,12 @@ static void freeSpace(MemPage *pPage, int start, int size){
 | 
			
		||||
*/
 | 
			
		||||
static int resizeCellArray(MemPage *pPage, int nNewSz){
 | 
			
		||||
  if( pPage->nCellAlloc<nNewSz ){
 | 
			
		||||
    pPage->aCell = sqliteRealloc(pPage->aCell, nNewSz*sizeof(pPage->aCell[0]) );
 | 
			
		||||
    int n = nNewSz*sizeof(pPage->aCell[0]);
 | 
			
		||||
    if( pPage->aCell==0 ){
 | 
			
		||||
      pPage->aCell = sqliteMallocRaw( n );
 | 
			
		||||
    }else{
 | 
			
		||||
      pPage->aCell = sqliteRealloc(pPage->aCell, n);
 | 
			
		||||
    }
 | 
			
		||||
    if( sqlite3_malloc_failed ) return SQLITE_NOMEM;
 | 
			
		||||
    pPage->nCellAlloc = nNewSz;
 | 
			
		||||
  }
 | 
			
		||||
@@ -1374,6 +1381,7 @@ int sqlite3BtreeCursor(
 | 
			
		||||
  pCur->pBt = pBt;
 | 
			
		||||
  pCur->wrFlag = wrFlag;
 | 
			
		||||
  pCur->idx = 0;
 | 
			
		||||
  pCur->infoValid = 0;
 | 
			
		||||
  pCur->pNext = pBt->pCursor;
 | 
			
		||||
  if( pCur->pNext ){
 | 
			
		||||
    pCur->pNext->pPrev = pCur;
 | 
			
		||||
@@ -1538,7 +1546,7 @@ static int getPayload(
 | 
			
		||||
  MemPage *pPage;
 | 
			
		||||
  Btree *pBt;
 | 
			
		||||
  int ovflSize;
 | 
			
		||||
  CellInfo info;
 | 
			
		||||
  u32 nKey;
 | 
			
		||||
 | 
			
		||||
  assert( pCur!=0 && pCur->pPage!=0 );
 | 
			
		||||
  assert( pCur->isValid );
 | 
			
		||||
@@ -1547,22 +1555,33 @@ static int getPayload(
 | 
			
		||||
  pageIntegrity(pPage);
 | 
			
		||||
  assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
 | 
			
		||||
  aPayload = pPage->aCell[pCur->idx];
 | 
			
		||||
  parseCell(pPage, aPayload, &info);
 | 
			
		||||
  aPayload += info.nHeader;
 | 
			
		||||
  if( !pCur->infoValid ){
 | 
			
		||||
    parseCell(pPage, aPayload, &pCur->info);
 | 
			
		||||
    pCur->infoValid = 1;
 | 
			
		||||
  }else{
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
    CellInfo info;
 | 
			
		||||
    parseCell(pPage, aPayload, &info);
 | 
			
		||||
    assert( memcmp(&info, &pCur->info, sizeof(info))==0 );
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
  aPayload += pCur->info.nHeader;
 | 
			
		||||
  if( pPage->intKey ){
 | 
			
		||||
    info.nKey = 0;
 | 
			
		||||
    nKey = 0;
 | 
			
		||||
  }else{
 | 
			
		||||
    nKey = pCur->info.nKey;
 | 
			
		||||
  }
 | 
			
		||||
  assert( offset>=0 );
 | 
			
		||||
  if( skipKey ){
 | 
			
		||||
    offset += info.nKey;
 | 
			
		||||
    offset += nKey;
 | 
			
		||||
  }
 | 
			
		||||
  if( offset+amt > info.nKey+info.nData ){
 | 
			
		||||
  if( offset+amt > nKey+pCur->info.nData ){
 | 
			
		||||
    return SQLITE_ERROR;
 | 
			
		||||
  }
 | 
			
		||||
  if( offset<info.nLocal ){
 | 
			
		||||
  if( offset<pCur->info.nLocal ){
 | 
			
		||||
    int a = amt;
 | 
			
		||||
    if( a+offset>info.nLocal ){
 | 
			
		||||
      a = info.nLocal - offset;
 | 
			
		||||
    if( a+offset>pCur->info.nLocal ){
 | 
			
		||||
      a = pCur->info.nLocal - offset;
 | 
			
		||||
    }
 | 
			
		||||
    memcpy(pBuf, &aPayload[offset], a);
 | 
			
		||||
    if( a==amt ){
 | 
			
		||||
@@ -1572,10 +1591,10 @@ static int getPayload(
 | 
			
		||||
    pBuf += a;
 | 
			
		||||
    amt -= a;
 | 
			
		||||
  }else{
 | 
			
		||||
    offset -= info.nLocal;
 | 
			
		||||
    offset -= pCur->info.nLocal;
 | 
			
		||||
  }
 | 
			
		||||
  if( amt>0 ){
 | 
			
		||||
    nextPage = get4byte(&aPayload[info.nLocal]);
 | 
			
		||||
    nextPage = get4byte(&aPayload[pCur->info.nLocal]);
 | 
			
		||||
  }
 | 
			
		||||
  ovflSize = pBt->usableSize - 4;
 | 
			
		||||
  while( amt>0 && nextPage ){
 | 
			
		||||
@@ -1674,7 +1693,8 @@ static const unsigned char *fetchPayload(
 | 
			
		||||
  unsigned char *aPayload;
 | 
			
		||||
  MemPage *pPage;
 | 
			
		||||
  Btree *pBt;
 | 
			
		||||
  CellInfo info;
 | 
			
		||||
  u32 nKey;
 | 
			
		||||
  int nLocal;
 | 
			
		||||
 | 
			
		||||
  assert( pCur!=0 && pCur->pPage!=0 );
 | 
			
		||||
  assert( pCur->isValid );
 | 
			
		||||
@@ -1683,21 +1703,33 @@ static const unsigned char *fetchPayload(
 | 
			
		||||
  pageIntegrity(pPage);
 | 
			
		||||
  assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
 | 
			
		||||
  aPayload = pPage->aCell[pCur->idx];
 | 
			
		||||
  parseCell(pPage, aPayload, &info);
 | 
			
		||||
  aPayload += info.nHeader;
 | 
			
		||||
  if( !pCur->infoValid ){
 | 
			
		||||
    parseCell(pPage, aPayload, &pCur->info);
 | 
			
		||||
    pCur->infoValid = 1;
 | 
			
		||||
  }else{
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
    CellInfo info;
 | 
			
		||||
    parseCell(pPage, aPayload, &info);
 | 
			
		||||
    assert( memcmp(&info, &pCur->info, sizeof(info))==0 );
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
  aPayload += pCur->info.nHeader;
 | 
			
		||||
  if( pPage->intKey ){
 | 
			
		||||
    info.nKey = 0;
 | 
			
		||||
    nKey = 0;
 | 
			
		||||
  }else{
 | 
			
		||||
    nKey = pCur->info.nKey;
 | 
			
		||||
  }
 | 
			
		||||
  if( skipKey ){
 | 
			
		||||
    aPayload += info.nKey;
 | 
			
		||||
    info.nLocal -= info.nKey;
 | 
			
		||||
    if( amt<0 ) amt = info.nData;
 | 
			
		||||
    assert( amt<=info.nData );
 | 
			
		||||
    aPayload += nKey;
 | 
			
		||||
    nLocal = pCur->info.nLocal - nKey;
 | 
			
		||||
    if( amt<0 ) amt = pCur->info.nData;
 | 
			
		||||
    assert( amt<=pCur->info.nData );
 | 
			
		||||
  }else{
 | 
			
		||||
    if( amt<0 ) amt = info.nKey;
 | 
			
		||||
    assert( amt<=info.nKey );
 | 
			
		||||
    nLocal = pCur->info.nLocal;
 | 
			
		||||
    if( amt<0 ) amt = nKey;
 | 
			
		||||
    assert( amt<=nKey );
 | 
			
		||||
  }
 | 
			
		||||
  if( amt>info.nLocal ){
 | 
			
		||||
  if( amt>nLocal ){
 | 
			
		||||
    return 0;  /* If any of the data is not local, return nothing */
 | 
			
		||||
  }
 | 
			
		||||
  return aPayload;
 | 
			
		||||
@@ -1750,6 +1782,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
 | 
			
		||||
  releasePage(pOldPage);
 | 
			
		||||
  pCur->pPage = pNewPage;
 | 
			
		||||
  pCur->idx = 0;
 | 
			
		||||
  pCur->infoValid = 0;
 | 
			
		||||
  if( pNewPage->nCell<1 ){
 | 
			
		||||
    return SQLITE_CORRUPT;
 | 
			
		||||
  }
 | 
			
		||||
@@ -1800,6 +1833,7 @@ static void moveToParent(BtCursor *pCur){
 | 
			
		||||
  oldPgno = pPage->pgno;
 | 
			
		||||
  releasePage(pPage);
 | 
			
		||||
  pCur->pPage = pParent;
 | 
			
		||||
  pCur->infoValid = 0;
 | 
			
		||||
  assert( pParent->idxShift==0 );
 | 
			
		||||
  if( pParent->idxShift==0 ){
 | 
			
		||||
    pCur->idx = idxParent;
 | 
			
		||||
@@ -1847,6 +1881,7 @@ static int moveToRoot(BtCursor *pCur){
 | 
			
		||||
  pageIntegrity(pRoot);
 | 
			
		||||
  pCur->pPage = pRoot;
 | 
			
		||||
  pCur->idx = 0;
 | 
			
		||||
  pCur->infoValid = 0;
 | 
			
		||||
  if( pRoot->nCell==0 && !pRoot->leaf ){
 | 
			
		||||
    Pgno subpage;
 | 
			
		||||
    assert( pRoot->pgno==1 );
 | 
			
		||||
@@ -1898,6 +1933,7 @@ static int moveToRightmost(BtCursor *pCur){
 | 
			
		||||
    if( rc ) return rc;
 | 
			
		||||
  }
 | 
			
		||||
  pCur->idx = pPage->nCell - 1;
 | 
			
		||||
  pCur->infoValid = 0;
 | 
			
		||||
  return SQLITE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2000,6 +2036,7 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
 | 
			
		||||
      const void *pCellKey;
 | 
			
		||||
      i64 nCellKey;
 | 
			
		||||
      pCur->idx = (lwr+upr)/2;
 | 
			
		||||
      pCur->infoValid = 0;
 | 
			
		||||
      sqlite3BtreeKeySize(pCur, &nCellKey);
 | 
			
		||||
      if( pPage->intKey ){
 | 
			
		||||
        if( nCellKey<nKey ){
 | 
			
		||||
@@ -2052,6 +2089,7 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
 | 
			
		||||
      return SQLITE_OK;
 | 
			
		||||
    }
 | 
			
		||||
    pCur->idx = lwr;
 | 
			
		||||
    pCur->infoValid = 0;
 | 
			
		||||
    rc = moveToChild(pCur, chldPg);
 | 
			
		||||
    if( rc ){
 | 
			
		||||
      return rc;
 | 
			
		||||
@@ -2089,6 +2127,7 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
 | 
			
		||||
  assert( pPage->isInit );
 | 
			
		||||
  assert( pCur->idx<pPage->nCell );
 | 
			
		||||
  pCur->idx++;
 | 
			
		||||
  pCur->infoValid = 0;
 | 
			
		||||
  if( pCur->idx>=pPage->nCell ){
 | 
			
		||||
    if( !pPage->leaf ){
 | 
			
		||||
      rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+6]));
 | 
			
		||||
@@ -2155,6 +2194,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
 | 
			
		||||
      pPage = pCur->pPage;
 | 
			
		||||
    }
 | 
			
		||||
    pCur->idx--;
 | 
			
		||||
    pCur->infoValid = 0;
 | 
			
		||||
    if( pPage->leafData ){
 | 
			
		||||
      rc = sqlite3BtreePrevious(pCur, pRes);
 | 
			
		||||
    }else{
 | 
			
		||||
@@ -2613,6 +2653,47 @@ static void insertCell(
 | 
			
		||||
  pPage->idxShift = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
** Add a list of cells to a page.  The page should be initially empty.
 | 
			
		||||
** The cells are guaranteed to fit on the page.
 | 
			
		||||
*/
 | 
			
		||||
static void assemblePage(
 | 
			
		||||
  MemPage *pPage,   /* The page to be assemblied */
 | 
			
		||||
  int nCell,        /* The number of cells to add to this page */
 | 
			
		||||
  u8 **apCell,      /* Pointers to cell text */
 | 
			
		||||
  int *aSize        /* Sizes of the cells */
 | 
			
		||||
){
 | 
			
		||||
  int i;            /* Loop counter */
 | 
			
		||||
  int totalSize;    /* Total size of all cells */
 | 
			
		||||
  int hdr;          /* Index of page header */
 | 
			
		||||
  int pc, prevpc;   /* Addresses of cells being inserted */
 | 
			
		||||
  u8 *data;         /* Data for the page */
 | 
			
		||||
 | 
			
		||||
  assert( pPage->needRelink==0 );
 | 
			
		||||
  assert( pPage->isOverfull==0 );
 | 
			
		||||
  totalSize = 0;
 | 
			
		||||
  for(i=0; i<nCell; i++){
 | 
			
		||||
    totalSize += aSize[i];
 | 
			
		||||
  }
 | 
			
		||||
  assert( totalSize<=pPage->nFree );
 | 
			
		||||
  assert( pPage->nCell==0 );
 | 
			
		||||
  resizeCellArray(pPage, nCell);
 | 
			
		||||
  pc = allocateSpace(pPage, totalSize);
 | 
			
		||||
  data = pPage->aData;
 | 
			
		||||
  hdr = pPage->hdrOffset;
 | 
			
		||||
  prevpc = hdr+3;
 | 
			
		||||
  for(i=0; i<nCell; i++){
 | 
			
		||||
    memcpy(data+pc, apCell[i], aSize[i]);
 | 
			
		||||
    put2byte(data+prevpc, pc);
 | 
			
		||||
    pPage->aCell[i] = data+pc;
 | 
			
		||||
    prevpc = pc;
 | 
			
		||||
    pc += aSize[i];
 | 
			
		||||
    assert( pc<=pPage->pBt->usableSize );
 | 
			
		||||
  }
 | 
			
		||||
  pPage->nCell = nCell;
 | 
			
		||||
  put2byte(data+prevpc, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
** Rebuild the linked list of cells on a page so that the cells
 | 
			
		||||
** occur in the order specified by the pPage->aCell[] array.  
 | 
			
		||||
@@ -2810,11 +2891,10 @@ static int balance(MemPage *pPage){
 | 
			
		||||
            /* The child information will fit on the root page, so do the
 | 
			
		||||
            ** copy */
 | 
			
		||||
            zeroPage(pPage, pChild->aData[0]);
 | 
			
		||||
            resizeCellArray(pPage, pChild->nCell);
 | 
			
		||||
            for(i=0; i<pChild->nCell; i++){
 | 
			
		||||
              insertCell(pPage, i, pChild->aCell[i], 
 | 
			
		||||
                        cellSize(pChild, pChild->aCell[i]), 0);
 | 
			
		||||
              szCell[i]  = cellSize(pChild, pChild->aCell[i]);
 | 
			
		||||
            }
 | 
			
		||||
            assemblePage(pPage, pChild->nCell, pChild->aCell, szCell);
 | 
			
		||||
            freePage(pChild);
 | 
			
		||||
            TRACE(("BALANCE: child %d transfer to page 1\n", pChild->pgno));
 | 
			
		||||
          }else{
 | 
			
		||||
@@ -3121,11 +3201,8 @@ static int balance(MemPage *pPage){
 | 
			
		||||
    MemPage *pNew = apNew[i];
 | 
			
		||||
    assert( pNew->pgno==pgnoNew[i] );
 | 
			
		||||
    resizeCellArray(pNew, cntNew[i] - j);
 | 
			
		||||
    while( j<cntNew[i] ){
 | 
			
		||||
      assert( pNew->nFree>=szCell[j] );
 | 
			
		||||
      insertCell(pNew, pNew->nCell, apCell[j], szCell[j], 0);
 | 
			
		||||
      j++;
 | 
			
		||||
    }
 | 
			
		||||
    assemblePage(pNew, cntNew[i]-j, &apCell[j], &szCell[j]);
 | 
			
		||||
    j = cntNew[i];
 | 
			
		||||
    assert( pNew->nCell>0 );
 | 
			
		||||
    assert( !pNew->isOverfull );
 | 
			
		||||
    relinkCellList(pNew);
 | 
			
		||||
@@ -3305,6 +3382,7 @@ int sqlite3BtreeInsert(
 | 
			
		||||
  }else if( loc<0 && pPage->nCell>0 ){
 | 
			
		||||
    assert( pPage->leaf );
 | 
			
		||||
    pCur->idx++;
 | 
			
		||||
    pCur->infoValid = 0;
 | 
			
		||||
  }else{
 | 
			
		||||
    assert( pPage->leaf );
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -1290,7 +1290,7 @@ int sqlite3VdbeSerialGet(const unsigned char *buf, u64 serial_type, Mem *pMem){
 | 
			
		||||
  len = sqlite3VdbeSerialTypeLen(serial_type);
 | 
			
		||||
  pMem->n = len;
 | 
			
		||||
  if( len>NBFS ){
 | 
			
		||||
    pMem->z = sqliteMalloc( len );
 | 
			
		||||
    pMem->z = sqliteMallocRaw( len );
 | 
			
		||||
    if( !pMem->z ){
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user