Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add a fast-path implementation of pcache1Fetch() for the common case of separate caches that do not use a mutex. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | faster-pcache1-fetch |
Files: | files | file ages | folders |
SHA1: |
760700edb3ff1f5d6bf3058f874cc8e2 |
User & Date: | drh 2015-06-12 13:49:26.780 |
Context
2015-06-13
| ||
11:10 | Avoid unnecessary mutex usage in pcache1, for a significant speedup. (Closed-Leaf check-in: dcf4fb8d76 user: drh tags: faster-pcache1-fetch) | |
2015-06-12
| ||
13:49 | Add a fast-path implementation of pcache1Fetch() for the common case of separate caches that do not use a mutex. (check-in: 760700edb3 user: drh tags: faster-pcache1-fetch) | |
13:04 | Minor performance optimization in pcache1.c. (check-in: 2e8ad2ead9 user: drh tags: trunk) | |
Changes
Changes to src/pcache1.c.
︙ | ︙ | |||
421 422 423 424 425 426 427 | /* ** This function is used internally to remove the page pPage from the ** PGroup LRU list, if is part of it. If pPage is not part of the PGroup ** LRU list, then this function is a no-op. ** ** The PGroup mutex must be held when this function is called. */ | | | 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 | /* ** This function is used internally to remove the page pPage from the ** PGroup LRU list, if is part of it. If pPage is not part of the PGroup ** LRU list, then this function is a no-op. ** ** The PGroup mutex must be held when this function is called. */ static PgHdr1 *pcache1PinPage(PgHdr1 *pPage){ PCache1 *pCache; assert( pPage!=0 ); assert( pPage->isPinned==0 ); pCache = pPage->pCache; assert( pPage->pLruNext || pPage==pCache->pGroup->pLruTail ); assert( pPage->pLruPrev || pPage==pCache->pGroup->pLruHead ); |
︙ | ︙ | |||
444 445 446 447 448 449 450 451 452 453 454 455 456 457 | }else{ pCache->pGroup->pLruTail = pPage->pLruPrev; } pPage->pLruNext = 0; pPage->pLruPrev = 0; pPage->isPinned = 1; pCache->nRecyclable--; } /* ** Remove the page supplied as an argument from the hash table ** (PCache1.apHash structure) that it is currently stored in. ** | > | 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 | }else{ pCache->pGroup->pLruTail = pPage->pLruPrev; } pPage->pLruNext = 0; pPage->pLruPrev = 0; pPage->isPinned = 1; pCache->nRecyclable--; return pPage; } /* ** Remove the page supplied as an argument from the hash table ** (PCache1.apHash structure) that it is currently stored in. ** |
︙ | ︙ | |||
799 800 801 802 803 804 805 806 | ** unnecessary pages cache entry allocations ** ** then attempt to recycle a page from the LRU list. If it is the right ** size, return the recycled buffer. Otherwise, free the buffer and ** proceed to step 5. ** ** 5. Otherwise, allocate and return a new page buffer. */ | > > > > > | < < < < < < < < | > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 | ** unnecessary pages cache entry allocations ** ** then attempt to recycle a page from the LRU list. If it is the right ** size, return the recycled buffer. Otherwise, free the buffer and ** proceed to step 5. ** ** 5. Otherwise, allocate and return a new page buffer. ** ** There are two versions of this routine. pcache1FetchWithMutex() is ** the general case. pcache1FetchNoMutex() is a faster implementation for ** the common case where pGroup->mutex is NULL. The pcache1Fetch() wrapper ** invokes the appropriate routine. */ static PgHdr1 *pcache1FetchNoMutex( sqlite3_pcache *p, unsigned int iKey, int createFlag ){ PCache1 *pCache = (PCache1 *)p; PgHdr1 *pPage = 0; /* Step 1: Search the hash table for an existing entry. */ pPage = pCache->apHash[iKey % pCache->nHash]; while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; } /* Step 2: Abort if no existing page is found and createFlag is 0 */ if( pPage ){ if( !pPage->isPinned ){ return pcache1PinPage(pPage); }else{ return pPage; } }else if( createFlag ){ /* Steps 3, 4, and 5 implemented by this subroutine */ return pcache1FetchStage2(pCache, iKey, createFlag); }else{ return 0; } } static PgHdr1 *pcache1FetchWithMutex( sqlite3_pcache *p, unsigned int iKey, int createFlag ){ PCache1 *pCache = (PCache1 *)p; PgHdr1 *pPage; pcache1EnterMutex(pCache->pGroup); pPage = pcache1FetchNoMutex(p, iKey, createFlag); assert( pPage==0 || pCache->iMaxKey>=iKey ); pcache1LeaveMutex(pCache->pGroup); return pPage; } static sqlite3_pcache_page *pcache1Fetch( sqlite3_pcache *p, unsigned int iKey, int createFlag ){ PCache1 *pCache = (PCache1 *)p; assert( offsetof(PgHdr1,page)==0 ); assert( pCache->bPurgeable || createFlag!=1 ); assert( pCache->bPurgeable || pCache->nMin==0 ); assert( pCache->bPurgeable==0 || pCache->nMin==10 ); assert( pCache->nMin==0 || pCache->bPurgeable ); assert( pCache->nHash>0 ); if( pCache->pGroup->mutex ){ return (sqlite3_pcache_page*)pcache1FetchWithMutex(p, iKey, createFlag); }else{ return (sqlite3_pcache_page*)pcache1FetchNoMutex(p, iKey, createFlag); } } /* ** Implementation of the sqlite3_pcache.xUnpin method. ** ** Mark a page as unpinned (eligible for asynchronous recycling). |
︙ | ︙ |