]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Write database pages in sorted order to reduce file fragmentation.
authordrh <drh@noemail.net>
Thu, 15 Jun 2006 14:31:06 +0000 (14:31 +0000)
committerdrh <drh@noemail.net>
Thu, 15 Jun 2006 14:31:06 +0000 (14:31 +0000)
This is an experimental change.  It is not clear if it will help any.
It may well be removed in the future. (CVS 3255)

FossilOrigin-Name: fe3e70a7275d68acb6fb8ea5d62bed3e9d8d2766

manifest
manifest.uuid
src/pager.c

index 3b10a0afc711271fd38ac9c5aee22588960d0103..91b1cfce5efa2d4eab9d4fa8bda26b12e9e1f2fa 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Asserts\sadded\sthat\sverify\sthat\sthe\scode\sworks\scorrectly\nthat\sticket\s#1849\sclaims\sis\swrong.\s(CVS\s3254)
-D 2006-06-15T13:22:23
+C Write\sdatabase\spages\sin\ssorted\sorder\sto\sreduce\sfile\sfragmentation.\nThis\sis\san\sexperimental\schange.\s\sIt\sis\snot\sclear\sif\sit\swill\shelp\sany.\nIt\smay\swell\sbe\sremoved\sin\sthe\sfuture.\s(CVS\s3255)
+D 2006-06-15T14:31:07
 F Makefile.in 200f6dc376ecfd9b01e5359c4e0c10c02f649b34
 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -62,7 +62,7 @@ F src/os_unix.c 17d91581a0ab478a06cb6f257b707a4c4a93e5a7
 F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
 F src/os_win.c c6976ae50b61fb5b7dce399e578aa1865f02b84f
 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
-F src/pager.c ddd05666bb89808a516baef2c186d6a75887ae90
+F src/pager.c 7ef4c5098b378d81d3687919d9de99ea99bbb6bb
 F src/pager.h 43f32f3847421f7502cfbb66f4eb2302b8033818
 F src/parse.y 14ce6fb228b5a06fd5c10999aed2cbbfafe630a7
 F src/pragma.c 27d5e395c5d950931c7ac4fe610e7c2993e2fa55
@@ -366,7 +366,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P 6380a9b118cf972c3c7d4886ecdb62c44f2208ca
-R 7c8c83f41ad732828e19404b0580f1d2
+P d145dc1c4bce403ec967bfd0024002d4de57f833
+R 2239e05327023592b50f3f9abbe32c42
 U drh
-Z 7d97f3dfe7f27a791bb719d9b2679d1a
+Z 91f8e7798ae68e6bd7062239e69b6453
index e40ade1c3ca02c4b35ab764e7926ec7a12ad19d7..fc78647d91d4e0537bf78d69cf6eb4f9ccdc12f5 100644 (file)
@@ -1 +1 @@
-d145dc1c4bce403ec967bfd0024002d4de57f833
\ No newline at end of file
+fe3e70a7275d68acb6fb8ea5d62bed3e9d8d2766
\ No newline at end of file
index 2e9982d710dacbe653c34e7a2cde87701936dc57..d68c11bce21339d2becf5099408c154969c8516c 100644 (file)
@@ -18,7 +18,7 @@
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 **
-** @(#) $Id: pager.c,v 1.268 2006/05/07 17:49:39 drh Exp $
+** @(#) $Id: pager.c,v 1.269 2006/06/15 14:31:07 drh Exp $
 */
 #ifndef SQLITE_OMIT_DISKIO
 #include "sqliteInt.h"
@@ -161,7 +161,7 @@ struct PgHdr {
   u8 needSync;                   /* Sync journal before writing this page */
   u8 alwaysRollback;             /* Disable dont_rollback() for this page */
   short int nRef;                /* Number of users of this page */
-  PgHdr *pDirty, *pPrevDirty;    /* Dirty pages sorted by PgHdr.pgno */
+  PgHdr *pDirty, *pPrevDirty;    /* Dirty pages */
   u32 notUsed;                   /* Buffer space */
 #ifdef SQLITE_CHECK_PAGES
   u32 pageHash;
@@ -2260,6 +2260,68 @@ static int syncJournal(Pager *pPager){
   return rc;
 }
 
+/*
+** Merge two lists of pages connected by pDirty and in pgno order.
+** Do not both fixing the pPrevDirty pointers.
+*/
+static PgHdr *merge_pagelist(PgHdr *pA, PgHdr *pB){
+  PgHdr result, *pTail;
+  pTail = &result;
+  while( pA && pB ){
+    if( pA->pgno<pB->pgno ){
+      pTail->pDirty = pA;
+      pTail = pA;
+      pA = pA->pDirty;
+    }else{
+      pTail->pDirty = pB;
+      pTail = pB;
+      pB = pB->pDirty;
+    }
+  }
+  if( pA ){
+    pTail->pDirty = pA;
+  }else if( pB ){
+    pTail->pDirty = pB;
+  }else{
+    pTail->pDirty = 0;
+  }
+  return result.pDirty;
+}
+
+/*
+** Sort the list of pages in accending order by pgno.  Pages are
+** connected by pDirty pointers.  The pPrevDirty pointers are
+** corrupted by this sort.
+*/
+#define N_SORT_BUCKET 25
+static PgHdr *sort_pagelist(PgHdr *pIn){
+  PgHdr *a[N_SORT_BUCKET], *p;
+  int i;
+  memset(a, 0, sizeof(a));
+  while( pIn ){
+    p = pIn;
+    pIn = p->pDirty;
+    p->pDirty = 0;
+    for(i=0; i<N_SORT_BUCKET-1; i++){
+      if( a[i]==0 ){
+        a[i] = p;
+        break;
+      }else{
+        p = merge_pagelist(a[i], p);
+        a[i] = 0;
+      }
+    }
+    if( i==N_SORT_BUCKET-1 ){
+      a[i] = merge_pagelist(a[i], p);
+    }
+  }
+  p = a[0];
+  for(i=1; i<N_SORT_BUCKET; i++){
+    p = merge_pagelist(p, a[i]);
+  }
+  return p;
+}
+
 /*
 ** Given a list of pages (connected by the PgHdr.pDirty pointer) write
 ** every one of those pages out to the database file and mark them all
@@ -2293,6 +2355,7 @@ static int pager_write_pagelist(PgHdr *pList){
     return rc;
   }
 
+  pList = sort_pagelist(pList);
   while( pList ){
     assert( pList->dirty );
     rc = sqlite3OsSeek(pPager->fd, (pList->pgno-1)*(i64)pPager->pageSize);