Try to make pcache1TruncateUnsafe() run faster for the case where iLimit is
very close to iMaxKey.

FossilOrigin-Name: 9ab53605d562a926c5620cba9dc96a3b812a432f
diff --git a/manifest b/manifest
index 5b8d528..2365986 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Remove\sall\stimers\sand\sother\sdebugging\slogs\sexcept\sfor\sthe\sone\stimer\son\npcache1TruncateUnsafe().
-D 2016-08-10T02:54:15.340
+C Try\sto\smake\spcache1TruncateUnsafe()\srun\sfaster\sfor\sthe\scase\swhere\siLimit\sis\nvery\sclose\sto\siMaxKey.
+D 2016-08-10T03:35:50.389
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -220,7 +220,7 @@
 F src/parse.y 5dfead8aed90cb0c7c1115898ee2266804daff45
 F src/pcache.c 4121a0571c18581ee9f82f086d5e2030051ebd6a
 F src/pcache.h 9b559127b83f84ff76d735c8262f04853be0c59a
-F src/pcache1.c 938bc830177ccd5198ab07a7522338c8598a00f7
+F src/pcache1.c 04279e6cf595ba3520707886e1f4e3a0b6312cad
 F src/pragma.c 3f3e959390a10c0131676f0e307acce372777e0f
 F src/prepare.c 6ef0cf2f9274982988ed6b7cab1be23147e94196
 F src/printf.c 090fac0f779c93c8a95089a125339686648835e4
@@ -1207,7 +1207,7 @@
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 42ce53f648a506d0a5d9c1231eb28c11b4e6b124
-R e064622bb758d47c8c7ad1ed3f41c26c
+P 5980e625dbb694dc3b0535e71fd986a6d211e245
+R 2aecde0e663e22b28208114fb4e83a67
 U drh
-Z 49509f85b3a161b812f3ddad4852a442
+Z 9f57a23eafe4610b0bd9a6ac18d687c6
diff --git a/manifest.uuid b/manifest.uuid
index 032f706..49eb0ae 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-5980e625dbb694dc3b0535e71fd986a6d211e245
\ No newline at end of file
+9ab53605d562a926c5620cba9dc96a3b812a432f
\ No newline at end of file
diff --git a/src/pcache1.c b/src/pcache1.c
index 5ae4ad0..29fbd11 100644
--- a/src/pcache1.c
+++ b/src/pcache1.c
@@ -498,14 +498,32 @@
   PCache1 *pCache,             /* The cache to truncate */
   unsigned int iLimit          /* Drop pages with this pgno or larger */
 ){
-  TESTONLY( unsigned int nPage = 0; )  /* To assert pCache->nPage is correct */
-  unsigned int h;
+  TESTONLY( int nPage = 0; )  /* To assert pCache->nPage is correct */
+  unsigned int h, iStop;
   START_DEBUG_TIMER;
   int nFree = 0;
   assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
-  for(h=0; h<pCache->nHash; h++){
-    PgHdr1 **pp = &pCache->apHash[h]; 
+  assert( pCache->iMaxKey >= iLimit );
+  assert( pCache->nHash > 0 );
+  if( pCache->iMaxKey - iLimit < pCache->nHash/2 ){
+    /* If we are just shaving the last few pages off the end of the
+    ** cache, then there is no point in scanning the entire hash table.
+    ** Only scan those hash slots that might contain pages that need to
+    ** be removed. */
+    iStop = iLimit % pCache->nHash;
+    h = pCache->iMaxKey % pCache->nHash;
+    TESTONLY( nPage = -10; )  /* Disable the pCache->nPage validity check */
+  }else{
+    /* This is the general case where many pages are being removed.
+    ** It is necessary to scan the entire hash table */
+    iStop = 0;
+    h = pCache->nHash - 1;
+  }
+  for(;;){
+    PgHdr1 **pp;
     PgHdr1 *pPage;
+    assert( h<pCache->nHash );
+    pp = &pCache->apHash[h]; 
     while( (pPage = *pp)!=0 ){
       if( pPage->iKey>=iLimit ){
         pCache->nPage--;
@@ -515,11 +533,13 @@
         pcache1FreePage(pPage);
       }else{
         pp = &pPage->pNext;
-        TESTONLY( nPage++; )
+        TESTONLY( if( nPage>=0 ) nPage++; )
       }
     }
+    if( h==iStop ) break;
+    h = h ? h-1 : pCache->nHash - 1;
   }
-  assert( pCache->nPage==nPage );
+  assert( nPage<0 || pCache->nPage==(unsigned)nPage );
   END_DEBUG_TIMER( DEBUG_TIMER_BIG_TIMEOUT ){
     sqlite3_log(SQLITE_NOTICE, 
        "slow pcache1TruncateUnsafe() %lld "
@@ -955,7 +975,7 @@
   PGroup *pGroup = pCache->pGroup;
   assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) );
   pcache1EnterMutex(pGroup);
-  pcache1TruncateUnsafe(pCache, 0);
+  if( pCache->nPage ) pcache1TruncateUnsafe(pCache, 0);
   assert( pGroup->nMaxPage >= pCache->nMax );
   pGroup->nMaxPage -= pCache->nMax;
   assert( pGroup->nMinPage >= pCache->nMin );