]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
If a free-slot is found within a page, but using that free-slot would fragment the... defrag-opt
authordan <dan@noemail.net>
Mon, 27 Oct 2014 08:02:16 +0000 (08:02 +0000)
committerdan <dan@noemail.net>
Mon, 27 Oct 2014 08:02:16 +0000 (08:02 +0000)
FossilOrigin-Name: 1f80f8c136ac970dcc7fb2337263dc5922e348c3

manifest
manifest.uuid
src/btree.c

index bafcf0fb91ed155b49962b339e3a871b90d14fb3..a088218356d0a6689371f46cfa00efb6c1e74d96 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\strunk\swith\sthis\sbranch.
-D 2014-10-27T07:01:04.796
+C If\sa\sfree-slot\sis\sfound\swithin\sa\spage,\sbut\susing\sthat\sfree-slot\swould\sfragment\sthe\spage\sfurther\sand\sthere\sare\salready\sat\sleast\s60\sfragmented\sbytes,\sdegragment\sthe\spage.\sThis\smatches\sthe\sbehaviour\sof\sthe\strunk.
+D 2014-10-27T08:02:16.531
 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 2639b89f6728f5775044704c7757c0226e071bd1
+F src/btree.c 9790fb4df51d36861bcbb8cd0a9b41586cbae699
 F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8
 F src/btreeInt.h 026d0129724e8f265fdc60d44ec240cf5a4e6179
 F src/build.c 9dc2bd94347b878c89627000c92b0c8d97ec2919
@@ -1206,7 +1206,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 1a8cf0a043347772ac54d150d634c32845beee8b 0f08924fe0c52a85a103f67bee9809e0f8f884b0
-R 9858b90cbf912e211c65716d59c94e8a
+P a13df3013bbac4a0d4fce5cef1376c857508c1c5
+R 05f44d14ab419727640258148977021c
 U dan
-Z daf2b363c619dfc32da3ad287a4e25ec
+Z 95c7c43e9818bc003f29ce4926da458f
index 962b2e06bb4fe1e08655ad4a06d51e073f2a0277..92680eaebb326e27776ca3c06516e751364158de 100644 (file)
@@ -1 +1 @@
-a13df3013bbac4a0d4fce5cef1376c857508c1c5
\ No newline at end of file
+1f80f8c136ac970dcc7fb2337263dc5922e348c3
\ No newline at end of file
index 46ce39abc7ed994e3246337debaf83c8ef2380d2..9b14dc2b6e0cff1ad3496fc1cacb6244f41d99ff 100644 (file)
@@ -1235,8 +1235,12 @@ static int defragmentPage(MemPage *pPage){
 ** pRc is non-NULL, then *pRc is set to SQLITE_CORRUPT and NULL is returned.
 ** Or, if corruption is detected and pRc is NULL, NULL is returned and the
 ** corruption goes unreported.
+**
+** If a slot of at least nByte bytes is found but cannot be used because 
+** there are already at least 60 fragmented bytes on the page, return NULL.
+** In this case, if pbDefrag parameter is not NULL, set *pbDefrag to true.
 */
-static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
+static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc, int *pbDefrag){
   const int hdr = pPg->hdrOffset;
   u8 * const aData = pPg->aData;
   int iAddr;
@@ -1255,7 +1259,10 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
       testcase( x==4 );
       testcase( x==3 );
       if( x<4 ){
-        if( aData[hdr+7]>=60 ) return 0;
+        if( aData[hdr+7]>=60 ){
+          if( pbDefrag ) *pbDefrag = 1;
+          return 0;
+        }
         /* Remove the slot from the free-list. Update the number of
         ** fragmented bytes within the page. */
         memcpy(&aData[iAddr], &aData[pc], 2);
@@ -1326,8 +1333,10 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
   testcase( gap==top );
   if( gap+2<=top && (data[hdr+1] || data[hdr+2]) ){
     int rc = SQLITE_OK;
-    u8 *pSpace = pageFindSlot(pPage, nByte, &rc);
+    int bDefrag = 0;
+    u8 *pSpace = pageFindSlot(pPage, nByte, &rc, &bDefrag);
     if( rc ) return rc;
+    if( bDefrag ) goto defragment_page;
     if( pSpace ){
       *pIdx = pSpace - data;
       return SQLITE_OK;
@@ -1339,6 +1348,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
   */
   testcase( gap+2+nByte==top );
   if( gap+2+nByte>top ){
+ defragment_page:
     testcase( pPage->nCell==0 );
     rc = defragmentPage(pPage);
     if( rc ) return rc;
@@ -6069,7 +6079,7 @@ static int pageInsertArray(
   for(i=0; i<nCell; i++){
     int sz = szCell[i];
     u8 *pSlot;
-    if( bFreelist==0 || (pSlot = pageFindSlot(pPg, sz, 0))==0 ){
+    if( bFreelist==0 || (pSlot = pageFindSlot(pPg, sz, 0, 0))==0 ){
       pData -= sz;
       if( pData<pBegin ) return 1;
       pSlot = pData;