📄 pcache.c
字号:
if( (p->flags&PGHDR_DIRTY)==0 ){ pcacheUnpin(p); }else{ /* Move the page to the head of the dirty list. */ pcacheRemoveFromDirtyList(p); pcacheAddToDirtyList(p); } }}/*** Increase the reference count of a supplied page by 1.*/void sqlite3PcacheRef(PgHdr *p){ assert(p->nRef>0); p->nRef++;}/*** Drop a page from the cache. There must be exactly one reference to the** page. This function deletes that reference, so after it returns the** page pointed to by p is invalid.*/void sqlite3PcacheDrop(PgHdr *p){ PCache *pCache; assert( p->nRef==1 ); if( p->flags&PGHDR_DIRTY ){ pcacheRemoveFromDirtyList(p); } pCache = p->pCache; pCache->nRef--; if( p->pgno==1 ){ pCache->pPage1 = 0; } sqlite3GlobalConfig.pcache.xUnpin(pCache->pCache, p, 1);}/*** Make sure the page is marked as dirty. If it isn't dirty already,** make it so.*/void sqlite3PcacheMakeDirty(PgHdr *p){ PCache *pCache; p->flags &= ~PGHDR_DONT_WRITE; assert( p->nRef>0 ); if( 0==(p->flags & PGHDR_DIRTY) ){ pCache = p->pCache; p->flags |= PGHDR_DIRTY; pcacheAddToDirtyList( p); }}/*** Make sure the page is marked as clean. If it isn't clean already,** make it so.*/void sqlite3PcacheMakeClean(PgHdr *p){ if( (p->flags & PGHDR_DIRTY) ){ pcacheRemoveFromDirtyList(p); p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC); if( p->nRef==0 ){ pcacheUnpin(p); } }}/*** Make every page in the cache clean.*/void sqlite3PcacheCleanAll(PCache *pCache){ PgHdr *p; while( (p = pCache->pDirty)!=0 ){ sqlite3PcacheMakeClean(p); }}/*** Clear the PGHDR_NEED_SYNC flag from all dirty pages.*/void sqlite3PcacheClearSyncFlags(PCache *pCache){ PgHdr *p; for(p=pCache->pDirty; p; p=p->pDirtyNext){ p->flags &= ~PGHDR_NEED_SYNC; } pCache->pSynced = pCache->pDirtyTail;}/*** Change the page number of page p to newPgno. */void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ PCache *pCache = p->pCache; assert( p->nRef>0 ); assert( newPgno>0 ); sqlite3GlobalConfig.pcache.xRekey(pCache->pCache, p, p->pgno, newPgno); p->pgno = newPgno; if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){ pcacheRemoveFromDirtyList(p); pcacheAddToDirtyList(p); }}/*** Drop every cache entry whose page number is greater than "pgno". The** caller must ensure that there are no outstanding references to any pages** other than page 1 with a page number greater than pgno.**** If there is a reference to page 1 and the pgno parameter passed to this** function is 0, then the data area associated with page 1 is zeroed, but** the page object is not dropped.*/void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ if( pCache->pCache ){ PgHdr *p; PgHdr *pNext; for(p=pCache->pDirty; p; p=pNext){ pNext = p->pDirtyNext; if( p->pgno>pgno ){ assert( p->flags&PGHDR_DIRTY ); sqlite3PcacheMakeClean(p); } } if( pgno==0 && pCache->pPage1 ){ memset(pCache->pPage1->pData, 0, pCache->szPage); pgno = 1; } sqlite3GlobalConfig.pcache.xTruncate(pCache->pCache, pgno+1); }}/*** Close a cache.*/void sqlite3PcacheClose(PCache *pCache){ if( pCache->pCache ){ sqlite3GlobalConfig.pcache.xDestroy(pCache->pCache); }}/* ** Discard the contents of the cache.*/int sqlite3PcacheClear(PCache *pCache){ sqlite3PcacheTruncate(pCache, 0); return SQLITE_OK;}/*** Merge two lists of pages connected by pDirty and in pgno order.** Do not both fixing the pDirtyPrev pointers.*/static PgHdr *pcacheMergeDirtyList(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 pDirtyPrev pointers are** corrupted by this sort.*/#define N_SORT_BUCKET_ALLOC 25#define N_SORT_BUCKET 25#ifdef SQLITE_TEST int sqlite3_pager_n_sort_bucket = 0; #undef N_SORT_BUCKET #define N_SORT_BUCKET \ (sqlite3_pager_n_sort_bucket?sqlite3_pager_n_sort_bucket:N_SORT_BUCKET_ALLOC)#endifstatic PgHdr *pcacheSortDirtyList(PgHdr *pIn){ PgHdr *a[N_SORT_BUCKET_ALLOC], *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 = pcacheMergeDirtyList(a[i], p); a[i] = 0; } } if( i==N_SORT_BUCKET-1 ){ /* Coverage: To get here, there need to be 2^(N_SORT_BUCKET) ** elements in the input list. This is possible, but impractical. ** Testing this line is the point of global variable ** sqlite3_pager_n_sort_bucket. */ a[i] = pcacheMergeDirtyList(a[i], p); } } p = a[0]; for(i=1; i<N_SORT_BUCKET; i++){ p = pcacheMergeDirtyList(p, a[i]); } return p;}/*** Return a list of all dirty pages in the cache, sorted by page number.*/PgHdr *sqlite3PcacheDirtyList(PCache *pCache){ PgHdr *p; for(p=pCache->pDirty; p; p=p->pDirtyNext){ p->pDirty = p->pDirtyNext; } return pcacheSortDirtyList(pCache->pDirty);}/* ** Return the total number of referenced pages held by the cache.*/int sqlite3PcacheRefCount(PCache *pCache){ return pCache->nRef;}/*** Return the number of references to the page supplied as an argument.*/int sqlite3PcachePageRefcount(PgHdr *p){ return p->nRef;}/* ** Return the total number of pages in the cache.*/int sqlite3PcachePagecount(PCache *pCache){ int nPage = 0; if( pCache->pCache ){ nPage = sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache); } return nPage;}#ifdef SQLITE_TEST/*** Get the suggested cache-size value.*/int sqlite3PcacheGetCachesize(PCache *pCache){ return pCache->nMax;}#endif/*** Set the suggested cache-size value.*/void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ pCache->nMax = mxPage; if( pCache->pCache ){ sqlite3GlobalConfig.pcache.xCachesize(pCache->pCache, mxPage); }}#ifdef SQLITE_CHECK_PAGES/*** For all dirty pages currently in the cache, invoke the specified** callback. This is only used if the SQLITE_CHECK_PAGES macro is** defined.*/void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){ PgHdr *pDirty; for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext){ xIter(pDirty); }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -