Dear SQLIte developers,

Here is a small patch for the linked-list merge sorter in SQLite
to sort N items, 
It will save  about 2*N CPU instructions  by eliminate  unnecessary null 
pointer check,
Regards

make test passed.
fossil diff

Index: src/pcache.c
==================================================================
--- src/pcache.c
+++ src/pcache.c
@@ -690,21 +690,22 @@
** Do not both fixing the pDirtyPrev pointers.
*/
static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){
   PgHdr result, *pTail;
   pTail = &result;
-  while( pA && pB ){
+  assert( pA && pB );
+  do{
     if( pA->pgno<pB->pgno ){
       pTail->pDirty = pA;
       pTail = pA;
       pA = pA->pDirty;
     }else{
       pTail->pDirty = pB;
       pTail = pB;
       pB = pB->pDirty;
     }
-  }
+  }while( pA && pB );
   if( pA ){
     pTail->pDirty = pA;
   }else if( pB ){
     pTail->pDirty = pB;
   }else{
@@ -748,11 +749,14 @@
       a[i] = pcacheMergeDirtyList(a[i], p);
     }
   }
   p = a[0];
   for(i=1; i<N_SORT_BUCKET; i++){
-    p = pcacheMergeDirtyList(p, a[i]);
+    if( !p )
+      p = a[i];
+    else if ( a[i] )
+      p = pcacheMergeDirtyList(p, a[i]);
   }
   return p;
}

 /*

Index: src/rowset.c
==================================================================
--- src/rowset.c
+++ src/rowset.c
@@ -240,11 +240,12 @@
){
   struct RowSetEntry head;
   struct RowSetEntry *pTail;

   pTail = &head;
-  while( pA && pB ){
+  assert( pA && pB );
+  do{
     assert( pA->pRight==0 || pA->v<=pA->pRight->v );
     assert( pB->pRight==0 || pB->v<=pB->pRight->v );
     if( pA->v<pB->v ){
       pTail->pRight = pA;
       pA = pA->pRight;
@@ -254,11 +255,11 @@
       pB = pB->pRight;
       pTail = pTail->pRight;
     }else{
       pA = pA->pRight;
     }
-  }
+  }while( pA && pB );
   if( pA ){
     assert( pA->pRight==0 || pA->v<=pA->pRight->v );
     pTail->pRight = pA;
   }else{
     assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v );
@@ -286,11 +287,14 @@
     aBucket[i] = pIn;
     pIn = pNext;
   }
   pIn = 0;
   for(i=0; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){
-    pIn = rowSetEntryMerge(pIn, aBucket[i]);
+    if( !pIn )
+      pIn = aBucket[i];
+    else if ( aBucket[i] )
+      pIn = rowSetEntryMerge(pIn, aBucket[i]);
   }
   return pIn;
}



Index: src/vdbesort.c
==================================================================
--- src/vdbesort.c
+++ src/vdbesort.c
@@ -1352,11 +1352,12 @@
){
   SorterRecord *pFinal = 0;
   SorterRecord **pp = &pFinal;
   int bCached = 0;

-  while( p1 && p2 ){
+  assert( p1 && p2 );
+  do{
     int res;
     res = pTask->xCompare(
         pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), p2->nVal
     );

@@ -1368,11 +1369,11 @@
       *pp = p2;
       pp = &p2->u.pNext;
       p2 = p2->u.pNext;
       bCached = 0;
     }
-  }
+  }while( p1 && p2 );
   *pp = p1 ? p1 : p2;
   *ppOut = pFinal;
}

 /*
@@ -1432,11 +1433,14 @@
     p = pNext;
   }

   p = 0;
   for(i=0; i<64; i++){
-    vdbeSorterMerge(pTask, p, aSlot[i], &p);
+    if( !p )
+      p = aSlot[i];
+    else if( aSlot[i] )
+      vdbeSorterMerge(pTask, p, aSlot[i], &p);
   }
   pList->pList = p;

   sqlite3_free(aSlot);
   assert( pTask->pUnpacked->errCode==SQLITE_OK

Reply via email to