/ Check-in [9ab53605]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Try to make pcache1TruncateUnsafe() run faster for the case where iLimit is very close to iMaxKey.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | debug
Files: files | file ages | folders
SHA1:9ab53605d562a926c5620cba9dc96a3b812a432f
User & Date: drh 2016-08-10 03:35:50
Context
2016-08-10
11:50
Fix pcache1TruncateUnsafe() run faster for the case where iLimit is very close to iMaxKey. check-in: b07a26df user: drh tags: trunk
03:35
Try to make pcache1TruncateUnsafe() run faster for the case where iLimit is very close to iMaxKey. Leaf check-in: 9ab53605 user: drh tags: debug
02:54
Remove all timers and other debugging logs except for the one timer on pcache1TruncateUnsafe(). check-in: 5980e625 user: drh tags: debug
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to src/pcache1.c.

494
495
496
497
498
499
500
501
502
503
504
505














506


507
508


509
510
511
512
513
514
515
516
517
518
519
520


521
522
523
524
525
526
527
528
529
...
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
**
** The PCache mutex must be held when this function is called.
*/
static void pcache1TruncateUnsafe(
  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;
  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]; 
    PgHdr1 *pPage;


    while( (pPage = *pp)!=0 ){
      if( pPage->iKey>=iLimit ){
        pCache->nPage--;
        nFree++;
        *pp = pPage->pNext;
        if( !pPage->isPinned ) pcache1PinPage(pPage);
        pcache1FreePage(pPage);
      }else{
        pp = &pPage->pNext;
        TESTONLY( nPage++; )
      }
    }


  }
  assert( pCache->nPage==nPage );
  END_DEBUG_TIMER( DEBUG_TIMER_BIG_TIMEOUT ){
    sqlite3_log(SQLITE_NOTICE, 
       "slow pcache1TruncateUnsafe() %lld "
       " nFree=%d nHash=%d nPage=%d iLimit=%d iMaxKey=%d",
       iDebugTimer,
       nFree, pCache->nHash, pCache->nPage, iLimit, pCache->iMaxKey);
  }
................................................................................
** Destroy a cache allocated using pcache1Create().
*/
static void pcache1Destroy(sqlite3_pcache *p){
  PCache1 *pCache = (PCache1 *)p;
  PGroup *pGroup = pCache->pGroup;
  assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) );
  pcache1EnterMutex(pGroup);
  pcache1TruncateUnsafe(pCache, 0);
  assert( pGroup->nMaxPage >= pCache->nMax );
  pGroup->nMaxPage -= pCache->nMax;
  assert( pGroup->nMinPage >= pCache->nMin );
  pGroup->nMinPage -= pCache->nMin;
  pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
  pcache1EnforceMaxPage(pGroup);
  pcache1LeaveMutex(pGroup);







|
|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|

>
>









|


>
>

|







 







|







494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
...
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
**
** The PCache mutex must be held when this function is called.
*/
static void pcache1TruncateUnsafe(
  PCache1 *pCache,             /* The cache to truncate */
  unsigned int iLimit          /* Drop pages with this pgno or larger */
){
  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) );
  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--;
        nFree++;
        *pp = pPage->pNext;
        if( !pPage->isPinned ) pcache1PinPage(pPage);
        pcache1FreePage(pPage);
      }else{
        pp = &pPage->pNext;
        TESTONLY( if( nPage>=0 ) nPage++; )
      }
    }
    if( h==iStop ) break;
    h = h ? h-1 : pCache->nHash - 1;
  }
  assert( nPage<0 || pCache->nPage==(unsigned)nPage );
  END_DEBUG_TIMER( DEBUG_TIMER_BIG_TIMEOUT ){
    sqlite3_log(SQLITE_NOTICE, 
       "slow pcache1TruncateUnsafe() %lld "
       " nFree=%d nHash=%d nPage=%d iLimit=%d iMaxKey=%d",
       iDebugTimer,
       nFree, pCache->nHash, pCache->nPage, iLimit, pCache->iMaxKey);
  }
................................................................................
** Destroy a cache allocated using pcache1Create().
*/
static void pcache1Destroy(sqlite3_pcache *p){
  PCache1 *pCache = (PCache1 *)p;
  PGroup *pGroup = pCache->pGroup;
  assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) );
  pcache1EnterMutex(pGroup);
  if( pCache->nPage ) pcache1TruncateUnsafe(pCache, 0);
  assert( pGroup->nMaxPage >= pCache->nMax );
  pGroup->nMaxPage -= pCache->nMax;
  assert( pGroup->nMinPage >= pCache->nMin );
  pGroup->nMinPage -= pCache->nMin;
  pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
  pcache1EnforceMaxPage(pGroup);
  pcache1LeaveMutex(pGroup);