SQLite 学习之路 第四节 cache具体结构
PgHdr1在pcache1.c里定义,PgHdr在pcache.c里定义,MemPage在btree.c里定义。PgHdr1的头是sqlite3_pcache_page的子类pghdr1包含需要查找的页面的页号信息;PgHdr保存了哪些页面是脏页;MemPage包含了数据库页的一些信息,可以理解为MemPage结构体。 sqlite3_pcache_page中的pBuf指向数据库页内容的开始地方,pExtra指向PgHdr sqlite3_pcache_page结构体如下:
struct sqlite3_pcache_page {
void *pBuf;
void *pExtra;
};
新建一个page cache:
pPg = pcache1Alloc(pCache->szAlloc);
p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
p->page.pBuf = pPg;
p->page.pExtra = &p[1];
PCache 结构体如下:
struct PCache {
PgHdr *pDirty, *pDirtyTail;
PgHdr *pSynced;
int nRefSum;
int szCache;
int szSpill;
int szPage;
int szExtra;
u8 bPurgeable;
u8 eCreate;
int (*xStress)(void*,PgHdr*);
void *pStress;
sqlite3_pcache *pCache;
};
PCache 结构体如下:
struct PCache1 {
PGroup *pGroup;
unsigned int *pnPurgeable;
int szPage;
int szExtra;
int szAlloc;
int bPurgeable;
unsigned int nMin;
unsigned int nMax;
unsigned int n90pct;
unsigned int iMaxKey;
unsigned int nPurgeableDummy;
unsigned int nRecyclable;
unsigned int nPage;
unsigned int nHash;
PgHdr1 **apHash;
PgHdr1 *pFree;
void *pBulk;
};
PCache主要是对脏页面链表进行管理。并使用了LRU算法(近期最少使用算法),而PCache1是页面缓冲区的具体实现。这个缓冲区中有多个页,这些页存储在Hash表apHash中。apHash是一链接法解决地址冲突的Hash表,而apHash是PgHdr1结构中采用的指针数组,且有nHash个槽位,每个槽位上是一个页面链表。
PgHdr 结构体如下:
struct PgHdr {
sqlite3_pcache_page *pPage;
void *pData;
void *pExtra;
PCache *pCache;
PgHdr *pDirty;
Pager *pPager;
Pgno pgno;
#ifdef SQLITE_CHECK_PAGES
u32 pageHash;
#endif
u16 flags;
i16 nRef;
PgHdr *pDirtyNext;
PgHdr *pDirtyPrev;
};
PgHdr1结构体如下:
struct PgHdr1 {
sqlite3_pcache_page page;
unsigned int iKey;
u16 isBulkLocal;
u16 isAnchor;
PgHdr1 *pNext;
PCache1 *pCache;
PgHdr1 *pLruNext;
PgHdr1 *pLruPrev;
};
Struct PgHdr 是页面的头部,用来控制缓冲区中页面;Struct PgHdr1每个缓冲区入口,可以大致理解为:通过它,可以获得数据库页面的渠道。
|