aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2022-09-02 14:29:54 +0000
committerdrh <>2022-09-02 14:29:54 +0000
commit4e9bf5ace34a29d04386bfa9bcdda1861750b744 (patch)
tree64ea7cf89d49069128e37b78bb09061fac2e2a64 /src
parente04c9f4b33521a99388ce27eb46a0947fda44a26 (diff)
downloadsqlite-4e9bf5ace34a29d04386bfa9bcdda1861750b744.tar.gz
sqlite-4e9bf5ace34a29d04386bfa9bcdda1861750b744.zip
Enhance the pcache1 implementation so that during an xRekey operation if
another page already exists at the destination, that other page gets moved to the source key. FossilOrigin-Name: aadd38f99a3e5abcf9bef49f4367752f163cc79500a28f812bb71969d7de419c
Diffstat (limited to 'src')
-rw-r--r--src/pcache1.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/src/pcache1.c b/src/pcache1.c
index 3e406a7a8..a47087fa1 100644
--- a/src/pcache1.c
+++ b/src/pcache1.c
@@ -1119,7 +1119,7 @@ static void pcache1Rekey(
PCache1 *pCache = (PCache1 *)p;
PgHdr1 *pPage = (PgHdr1 *)pPg;
PgHdr1 **pp;
- unsigned int h;
+ unsigned int hOld, hNew;
assert( pPage->iKey==iOld );
assert( pPage->pCache==pCache );
assert( iOld!=iNew ); /* The page number really is changing */
@@ -1127,18 +1127,33 @@ static void pcache1Rekey(
pcache1EnterMutex(pCache->pGroup);
assert( pcache1FetchNoMutex(p, iOld, 0)==pPage ); /* pPg really is iOld */
- h = iOld%pCache->nHash;
- pp = &pCache->apHash[h];
+ hOld = iOld%pCache->nHash;
+ pp = &pCache->apHash[hOld];
while( (*pp)!=pPage ){
pp = &(*pp)->pNext;
}
*pp = pPage->pNext;
- assert( pcache1FetchNoMutex(p, iNew, 0)==0 ); /* iNew not previously used */
- h = iNew%pCache->nHash;
+ hNew = iNew%pCache->nHash;
+ pp = &pCache->apHash[hNew];
+ while( *pp ){
+ if( (*pp)->iKey==iNew ){
+ /* If there is already another pcache entry at iNew, change it to iOld,
+ ** thus swapping the positions of iNew and iOld */
+ PgHdr1 *pOld = *pp;
+ *pp = pOld->pNext;
+ pOld->pNext = pCache->apHash[hOld];
+ pCache->apHash[hOld] = pOld;
+ pOld->iKey = iOld;
+ break;
+ }else{
+ pp = &(*pp)->pNext;
+ }
+ }
+
pPage->iKey = iNew;
- pPage->pNext = pCache->apHash[h];
- pCache->apHash[h] = pPage;
+ pPage->pNext = pCache->apHash[hNew];
+ pCache->apHash[hNew] = pPage;
if( iNew>pCache->iMaxKey ){
pCache->iMaxKey = iNew;
}