Attempt to further reduce memcpy() in balance_nonroot().
FossilOrigin-Name: fec849dcca3aead2bc2d4ecffeda750684d32fb0
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
C Change\sthe\sbalance_nonroot()\sroutine\sto\sreduce\sthe\samount\sof\smemcpy\swork\sthat\stakes\splace.\sThis\sis\sa\swork\sin\sprogress.
|
||||
D 2014-10-09T19:35:37.452
|
||||
C Attempt\sto\sfurther\sreduce\smemcpy()\sin\sbalance_nonroot().
|
||||
D 2014-10-11T20:00:24.552
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@@ -172,7 +172,7 @@ F src/auth.c d8abcde53426275dab6243b441256fcd8ccbebb2
|
||||
F src/backup.c a31809c65623cc41849b94d368917f8bb66e6a7e
|
||||
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
|
||||
F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5
|
||||
F src/btree.c 7b89fde3bffa5b7300e94c4aeb69ccff926ef513
|
||||
F src/btree.c d5f4f74e309f79ace4b4025c433874ead635bed2
|
||||
F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8
|
||||
F src/btreeInt.h 1bd7957161a1346a914f1f09231610e777a8e58d
|
||||
F src/build.c bde83dd5cf812e310a7e5ad2846790a14745bef4
|
||||
@@ -1200,7 +1200,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 3edab9957cc7bb90b52fd40b02613c2cb03fc166
|
||||
R 5fca1836b5a4d862df24682ecb47d048
|
||||
P 29304499ea4b72dbb6701e10cc19b5d41f7e5ac9
|
||||
R 3235ac37769ff059d7c714947e8a11dd
|
||||
U dan
|
||||
Z 8527330c8f275358262176fc962502e2
|
||||
Z 17fdfd7faf788bbb79d2ec9941c17025
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
29304499ea4b72dbb6701e10cc19b5d41f7e5ac9
|
||||
fec849dcca3aead2bc2d4ecffeda750684d32fb0
|
||||
+172
-13
@@ -5980,10 +5980,9 @@ static void assemblePage(
|
||||
|
||||
static void rebuildPage(
|
||||
MemPage *pPg, /* Edit this page */
|
||||
int nRemove, /* Cells to remove from start of page */
|
||||
int nCell, /* Final number of cells on page */
|
||||
u8 **apCell, /* Array of nCell final cells */
|
||||
u16 *szCell /* Array of nCell cell sizes */
|
||||
u8 **apCell, /* Array of cells */
|
||||
u16 *szCell /* Array of cell sizes */
|
||||
){
|
||||
const int hdr = pPg->hdrOffset; /* Offset of header on pPg */
|
||||
u8 * const aData = pPg->aData; /* Pointer to data for pPg */
|
||||
@@ -6020,6 +6019,129 @@ static void rebuildPage(
|
||||
aData[hdr+7] = 0x00;
|
||||
}
|
||||
|
||||
static void editPage(
|
||||
MemPage *pPg, /* Edit this page */
|
||||
int iOld, /* Index of first cell currently on page */
|
||||
int iNew, /* Index of new first cell on page */
|
||||
int nNew, /* Final number of cells on page */
|
||||
u8 **apCell, /* Array of cells */
|
||||
u16 *szCell /* Array of cell sizes */
|
||||
){
|
||||
|
||||
if( 1 ){
|
||||
u8 * const aData = pPg->aData;
|
||||
const int hdr = pPg->hdrOffset;
|
||||
u8 *pBegin = &pPg->aCellIdx[nNew * 2];
|
||||
int nFree = pPg->nFree; /* Free bytes on pPg */
|
||||
int nCell = pPg->nCell; /* Cells stored on pPg */
|
||||
u8 *pData;
|
||||
u8 *pCellptr;
|
||||
int i;
|
||||
int iOldEnd = iOld + pPg->nCell + pPg->nOverflow;
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager);
|
||||
memcpy(pTmp, aData, pPg->pBt->usableSize);
|
||||
#endif
|
||||
|
||||
/* Remove cells from the start and end of the page */
|
||||
if( iOld<iNew ){
|
||||
int nShift = 0;
|
||||
for(i=iOld; i<iNew; i++){
|
||||
if( apCell[i]>aData && apCell[i]<&aData[pPg->pBt->usableSize] ){
|
||||
freeSpace(pPg, apCell[i] - aData, szCell[i]);
|
||||
nFree += szCell[i] + 2;
|
||||
nShift++;
|
||||
}
|
||||
}
|
||||
nCell -= nShift;
|
||||
memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
|
||||
}
|
||||
for(i=iNew+nNew; i<iOldEnd; i++){
|
||||
if( apCell[i]>aData && apCell[i]<&aData[pPg->pBt->usableSize] ){
|
||||
freeSpace(pPg, apCell[i] - aData, szCell[i]);
|
||||
nFree += szCell[i] + 2;
|
||||
nCell--;
|
||||
}
|
||||
}
|
||||
pData = &aData[get2byte(&aData[hdr+5])];
|
||||
if( pData<pBegin ) goto editpage_fail;
|
||||
|
||||
/* Add cells to the start of the page */
|
||||
if( iNew<iOld ){
|
||||
pCellptr = pPg->aCellIdx;
|
||||
memmove(&pCellptr[(iOld-iNew)*2], pCellptr, nCell*2);
|
||||
for(i=iNew; i<iOld; i++){
|
||||
pData -= szCell[i];
|
||||
if( pData<pBegin ) goto editpage_fail;
|
||||
memcpy(pData, apCell[i], szCell[i]);
|
||||
put2byte(pCellptr, (pData - aData));
|
||||
pCellptr += 2;
|
||||
nFree -= (szCell[i] + 2);
|
||||
nCell++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add any overflow cells */
|
||||
for(i=0; i<pPg->nOverflow; i++){
|
||||
int iCell = (iOld + pPg->aiOvfl[i]) - iNew;
|
||||
if( iCell>=0 && iCell<nNew ){
|
||||
u8 *pCellptr = &pPg->aCellIdx[iCell * 2];
|
||||
int sz = szCell[iCell+iNew];
|
||||
memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2);
|
||||
pData -= sz;
|
||||
if( pData<pBegin ) goto editpage_fail;
|
||||
memcpy(pData, apCell[iCell+iNew], sz);
|
||||
put2byte(pCellptr, (pData - aData));
|
||||
nFree -= (sz + 2);
|
||||
nCell++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Append cells to the end of the page */
|
||||
pCellptr = &pPg->aCellIdx[nCell*2];
|
||||
for(i=iNew+nCell; i<(iNew+nNew); i++){
|
||||
pData -= szCell[i];
|
||||
if( pData<pBegin ) goto editpage_fail;
|
||||
memcpy(pData, apCell[i], szCell[i]);
|
||||
put2byte(pCellptr, (pData - aData));
|
||||
pCellptr += 2;
|
||||
nFree -= (szCell[i] + 2);
|
||||
}
|
||||
|
||||
pPg->nFree = nFree;
|
||||
pPg->nCell = nNew;
|
||||
pPg->nOverflow = 0;
|
||||
|
||||
put2byte(&aData[hdr+3], pPg->nCell);
|
||||
put2byte(&aData[hdr+5], pData - aData);
|
||||
|
||||
#ifdef SQLITE_DEBUG
|
||||
for(i=0; i<nNew; i++){
|
||||
u8 *pCell = apCell[i+iNew];
|
||||
int iOff = get2byte(&pPg->aCellIdx[i*2]);
|
||||
if( pCell>=aData && pCell<&aData[pPg->pBt->usableSize] ){
|
||||
pCell = &pTmp[pCell - aData];
|
||||
}
|
||||
assert( 0==memcmp(pCell, &aData[iOff], szCell[i+iNew]) );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
printf("EDIT\n");
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
editpage_fail:
|
||||
#if 0
|
||||
printf("REBUILD\n");
|
||||
#endif
|
||||
/* Unable to edit this page. Rebuild it from scratch instead. */
|
||||
rebuildPage(pPg, nNew, &apCell[iNew], &szCell[iNew]);
|
||||
}
|
||||
|
||||
/*
|
||||
** The following parameters determine how many adjacent pages get involved
|
||||
** in a balancing operation. NN is the number of neighbors on either side
|
||||
@@ -6312,6 +6434,7 @@ static int balance_nonroot(
|
||||
u8 *pRight; /* Location in parent of right-sibling pointer */
|
||||
u8 *apDiv[NB-1]; /* Divider cells in pParent */
|
||||
int cntNew[NB+2]; /* Index in aCell[] of cell after i-th page */
|
||||
int cntOld[NB+2]; /* Old index in aCell[] after i-th page */
|
||||
int szNew[NB+2]; /* Combined size of cells place on i-th page */
|
||||
u8 **apCell = 0; /* All cells begin balanced */
|
||||
u16 *szCell; /* Local size of all cells in apCell[] */
|
||||
@@ -6487,6 +6610,7 @@ static int balance_nonroot(
|
||||
nCell++;
|
||||
}
|
||||
}
|
||||
cntOld[i] = nCell;
|
||||
if( i<nOld-1 && !leafData){
|
||||
u16 sz = (u16)szNew[i];
|
||||
u8 *pTemp;
|
||||
@@ -6624,6 +6748,7 @@ static int balance_nonroot(
|
||||
zeroPage(pNew, pageFlags);
|
||||
apNew[i] = pNew;
|
||||
nNew++;
|
||||
cntOld[i] = nCell;
|
||||
|
||||
/* Set the pointer-map entry for the new sibling page. */
|
||||
if( ISAUTOVACUUM ){
|
||||
@@ -6693,6 +6818,33 @@ static int balance_nonroot(
|
||||
** to the apCell[] index of the first cell that will appear on the
|
||||
** page following this balancing operation. */
|
||||
int iFirst = (i==0 ? 0 : cntNew[i-1] + !leafData); /* new first cell */
|
||||
|
||||
#if 0
|
||||
MemPage *pNew = apNew[i];
|
||||
int iCell;
|
||||
int nCta = 0;
|
||||
int nFree;
|
||||
|
||||
printf("REBUILD %d: %d@%d -> %d@%d", apNew[i]->pgno,
|
||||
pNew->nCell+pNew->nOverflow, j,
|
||||
cntNew[i] - iFirst, iFirst
|
||||
);
|
||||
for(iCell=iFirst; iCell<cntNew[i]; iCell++){
|
||||
if( apCell[iCell]<pNew->aData
|
||||
|| apCell[iCell]>=&pNew->aData[pBt->usableSize]
|
||||
){
|
||||
nCta += szCell[iCell];
|
||||
}
|
||||
}
|
||||
nFree = get2byte(&pNew->aData[pNew->hdrOffset+5]);
|
||||
nFree -= (pNew->cellOffset + (cntNew[i] - iFirst) * 2);
|
||||
printf(" cta=%d free=%d\n", nCta, nFree);
|
||||
if( i==(nNew-1) ){
|
||||
printf("-----\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
|
||||
assert( i<nOld || j==nCell );
|
||||
aShiftLeft[i] = j - iFirst;
|
||||
j += apNew[i]->nCell + apNew[i]->nOverflow;
|
||||
@@ -6835,17 +6987,23 @@ static int balance_nonroot(
|
||||
&& (aShiftLeft[iPg]>=0 || abDone[iPg-1])
|
||||
&& (aShiftRight[iPg]>=0 || abDone[iPg+1])
|
||||
){
|
||||
MemPage *pNew = apNew[iPg];
|
||||
int iLeft = ((iPg==0) ? 0 : cntNew[iPg-1] + !leafData);
|
||||
rebuildPage(pNew,
|
||||
aShiftLeft[iPg] < 0 ? (aShiftLeft[iPg]*-1) : 0,
|
||||
cntNew[iPg] - iLeft,
|
||||
&apCell[iLeft],
|
||||
&szCell[iLeft]
|
||||
);
|
||||
int iNew;
|
||||
int iOld;
|
||||
int nNewCell;
|
||||
|
||||
if( iPg==0 ){
|
||||
iNew = iOld = 0;
|
||||
nNewCell = cntNew[0];
|
||||
}else{
|
||||
iOld = iPg<nOld ? (cntOld[iPg-1] + !leafData) : nCell;
|
||||
iNew = cntNew[iPg-1] + !leafData;
|
||||
nNewCell = cntNew[iPg] - iNew;
|
||||
}
|
||||
|
||||
editPage(apNew[iPg], iOld, iNew, nNewCell, apCell, szCell);
|
||||
abDone[iPg] = 1;
|
||||
assert( pNew->nOverflow==0 );
|
||||
assert( pNew->nCell==(cntNew[iPg] - (iPg==0?0:cntNew[iPg-1]+!leafData)) );
|
||||
assert( apNew[iPg]->nOverflow==0 );
|
||||
assert( apNew[iPg]->nCell==nNewCell );
|
||||
}
|
||||
}
|
||||
assert( memcmp(abDone, "\01\01\01\01\01", nNew)==0 );
|
||||
@@ -6869,6 +7027,7 @@ static int balance_nonroot(
|
||||
** 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)
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user