]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
An improved technique for ensuring that the Rekey() operation does not
authordrh <>
Wed, 7 Sep 2022 19:28:18 +0000 (19:28 +0000)
committerdrh <>
Wed, 7 Sep 2022 19:28:18 +0000 (19:28 +0000)
overwrite an existing page number.  This approach does not change the
semantics of the underlying pluggable pcache and it is easier to prove
correct.  This replaces the changes at
[aadd38f99a3e5abc] and [81cff9f1955874aa].

FossilOrigin-Name: 7dbddde79e3ca1b81e00288616fc27434698ce6dcb47714728fce8602ae91f45

manifest
manifest.uuid
src/pcache.c
src/pcache1.c

index e6d926c22b083383c388413e2942897d0f7f4509..13721a29d5930d46086d23794509c2f6cf658456 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sthe\stool/omittest-msvc.tcl\sscript\sthat\swill\stry\sto\sbuild\susing\sMSVC\nusing\svarious\scompile-time\soptions,\sto\sensure\sthat\sthe\scompile-time\soptions\nall\sbuild\swithout\serrors.
-D 2022-09-05T22:54:36.015
+C An\simproved\stechnique\sfor\sensuring\sthat\sthe\sRekey()\soperation\sdoes\snot\noverwrite\san\sexisting\spage\snumber.\s\sThis\sapproach\sdoes\snot\schange\sthe\nsemantics\sof\sthe\sunderlying\spluggable\spcache\sand\sit\sis\seasier\sto\sprove\ncorrect.\s\sThis\sreplaces\sthe\schanges\sat\n[aadd38f99a3e5abc]\sand\s[81cff9f1955874aa].
+D 2022-09-07T19:28:18.399
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -578,9 +578,9 @@ F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
 F src/pager.c 6176d9752eb580419e8fef4592dc417a6b00ddfd43ee22f818819bf8840ceee8
 F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3
 F src/parse.y 8e67d820030d2655b9942ffe61c1e7e6b96cea2f2f72183533299393907d0564
-F src/pcache.c 22a6ebe498d1d26c85fd1e3bcb246d97b882c060027c1e1688fbea905f5ac3cf
+F src/pcache.c f4268f7f73c6a3db12ce22fd25bc68dc42315d19599414ab1207d7cf32f79197
 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
-F src/pcache1.c 849a26ea9dc1e6a176b75dc576672a598170b0b46aeef87a981dd25e0af0ccf9
+F src/pcache1.c 5996285f0a1873b1c7925568d1145865105581d588c1671df0c79b43d507174e
 F src/pragma.c 9bf7d8a2a9ad3bc36df3ec0d61817a44c38a1da527d59c26c203047f906e334a
 F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
 F src/prepare.c 971d5819a4bda88038c2283d71fc0a2974ffc3dd480f9bd941341017abacfd1b
@@ -2000,9 +2000,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P f74a5ea8c986dc33d3afcda169c38abbe55728c56716cf9991a5e2ef7fc4917a 82b89f8a074858a81d841dfc26436e8d39ce4907b8f989eba4d848db16758303
-R 6ca49c20c002174082011fae5352b9a2
-T +closed 82b89f8a074858a81d841dfc26436e8d39ce4907b8f989eba4d848db16758303
+P 6b00ecb59fd303f7985902c35a46db9e729201d4beaedea46596b728d9e4b1c8
+R 8bc604264e2fc000e1d53debee8fb293
 U drh
-Z 072f191f34018bff25742e9863a6762e
+Z 8b6d452122c12811257b08bbb3024121
 # Remove this line to create a well-formed Fossil manifest.
index 1a48ad440733cf8003236348ae2c4e8856aacd93..15ae82f961f1fad318d45a298df2ba292e4189d5 100644 (file)
@@ -1 +1 @@
-6b00ecb59fd303f7985902c35a46db9e729201d4beaedea46596b728d9e4b1c8
\ No newline at end of file
+7dbddde79e3ca1b81e00288616fc27434698ce6dcb47714728fce8602ae91f45
\ No newline at end of file
index 8c57f5b1eb2633ec32911d99c10c14e3c4eb255e..0407e06b2fafa14c4390fdbd6011f978926592e9 100644 (file)
@@ -655,14 +655,14 @@ void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
   assert( sqlite3PcachePageSanity(p) );
   pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno));
   pOther = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, newPgno, 0);
-  sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
   if( pOther ){
-    PgHdr *pPg = (PgHdr*)pOther->pExtra;
-    pPg->pgno = p->pgno;
-    if( pPg->pPage==0 ){
-      sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pOther, 0);
-    }
+    PgHdr *pXPage = (PgHdr*)pOther->pExtra;
+    assert( pXPage->nRef==0 );
+    pXPage->nRef++;
+    pCache->nRefSum++;
+    sqlite3PcacheDrop(pXPage);
   }
+  sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
   p->pgno = newPgno;
   if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
     pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
index a47087fa1134df2b2d63721c9f996d7f8d50f5e6..551f1b896bccd71177b991900ae280f8e2a15d67 100644 (file)
@@ -1125,7 +1125,7 @@ static void pcache1Rekey(
   assert( iOld!=iNew );               /* The page number really is changing */
 
   pcache1EnterMutex(pCache->pGroup);
-  
+
   assert( pcache1FetchNoMutex(p, iOld, 0)==pPage ); /* pPg really is iOld */
   hOld = iOld%pCache->nHash;
   pp = &pCache->apHash[hOld];
@@ -1134,23 +1134,8 @@ static void pcache1Rekey(
   }
   *pp = pPage->pNext;
 
+  assert( pcache1FetchNoMutex(p, iOld, 0)==0 ); /* iOld not in cache */
   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[hNew];
   pCache->apHash[hNew] = pPage;