Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
9e90dcc5
T
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
9e90dcc5
编写于
2月 22, 2022
作者:
H
Hongze Cheng
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
more
上级
ead430b4
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
59 addition
and
576 deletion
+59
-576
source/libs/tdb/CMakeLists.txt
source/libs/tdb/CMakeLists.txt
+10
-6
source/libs/tdb/src/db/tdbPgCache.c
source/libs/tdb/src/db/tdbPgCache.c
+37
-544
source/libs/tdb/src/inc/tdbInt.h
source/libs/tdb/src/inc/tdbInt.h
+7
-7
source/libs/tdb/src/inc/tdbPgCache.h
source/libs/tdb/src/inc/tdbPgCache.h
+5
-19
未找到文件。
source/libs/tdb/CMakeLists.txt
浏览文件 @
9e90dcc5
# for tdb
set
(
TDB_SUBDIRS
"db"
)
foreach
(
TDB_SUBDIR
${
TDB_SUBDIRS
}
)
aux_source_directory
(
"src/
${
TDB_SUBDIR
}
"
TDB_SRC
)
endforeach
()
#
set(TDB_SUBDIRS "db")
#
foreach(TDB_SUBDIR ${TDB_SUBDIRS})
#
aux_source_directory("src/${TDB_SUBDIR}" TDB_SRC)
#
endforeach()
add_library
(
tdb STATIC
${
TDB_SRC
}
)
add_library
(
tdb
""
)
target_sources
(
tdb
PRIVATE
"src/db/tdbPgCache.c"
)
target_include_directories
(
tdb
...
...
@@ -29,5 +33,5 @@ target_include_directories(tdb_sqlite PUBLIC "src/sqliteinc")
# for test
if
(
${
BUILD_TEST
}
)
add_subdirectory
(
test
)
#
add_subdirectory(test)
endif
(
${
BUILD_TEST
}
)
source/libs/tdb/src/db/tdbPgCache.c
浏览文件 @
9e90dcc5
...
...
@@ -14,567 +14,60 @@
*/
#include "tdbInt.h"
typedef
TD_DLIST
(
SPage
)
SPgList
;
struct
SPgCache
{
TENV
*
pEnv
;
// TENV containing this page cache
pgsz_t
pgsize
;
int32_t
npage
;
SPage
**
pages
;
SPgList
freeList
;
SPgList
lru
;
struct
{
int32_t
nbucket
;
SPgList
*
buckets
;
}
pght
;
// page hash table
struct
SPCache
{
int
pageSize
;
int
cacheSize
;
int
extraSize
;
int
nRef
;
pthread_mutex_t
mutex
;
int
nPage
;
SPgHdr
*
lru
;
int
nRecyclable
;
int
nHash
;
SPgHdr
*
pgHash
;
int
nFree
;
SPgHdr
*
pFree
;
};
static
void
pgCachePinPage
(
SPage
*
pPage
);
static
void
pgCacheUnpinPage
(
SPage
*
pPage
);
int
pgCacheOpen
(
SPgCache
**
ppPgCache
,
TENV
*
pEnv
)
{
SPgCache
*
pPgCache
;
SPage
*
pPage
;
void
*
pData
;
pgsz_t
pgSize
;
cachesz_t
cacheSize
;
int32_t
npage
;
int32_t
nbucket
;
size_t
msize
;
*
ppPgCache
=
NULL
;
pgSize
=
tdbEnvGetPageSize
(
pEnv
);
cacheSize
=
tdbEnvGetCacheSize
(
pEnv
);
npage
=
cacheSize
/
pgSize
;
nbucket
=
npage
;
msize
=
sizeof
(
*
pPgCache
)
+
sizeof
(
SPage
*
)
*
npage
+
sizeof
(
SPgList
)
*
nbucket
;
// Allocate the handle
pPgCache
=
(
SPgCache
*
)
calloc
(
1
,
msize
);
if
(
pPgCache
==
NULL
)
{
return
-
1
;
}
// Init the handle
pPgCache
->
pEnv
=
pEnv
;
pPgCache
->
pgsize
=
pgSize
;
pPgCache
->
npage
=
npage
;
pPgCache
->
pages
=
(
SPage
**
)(
&
pPgCache
[
1
]);
pPgCache
->
pght
.
nbucket
=
nbucket
;
pPgCache
->
pght
.
buckets
=
(
SPgList
*
)(
&
(
pPgCache
->
pages
[
npage
]));
TD_DLIST_INIT
(
&
(
pPgCache
->
freeList
));
for
(
int32_t
i
=
0
;
i
<
npage
;
i
++
)
{
pData
=
malloc
(
pgSize
+
sizeof
(
SPage
));
if
(
pData
==
NULL
)
{
return
-
1
;
// TODO: handle error
}
pPage
=
POINTER_SHIFT
(
pData
,
pgSize
);
pPage
->
pgid
=
TDB_IVLD_PGID
;
pPage
->
frameid
=
i
;
pPage
->
pData
=
pData
;
// add current page to the page cache
pPgCache
->
pages
[
i
]
=
pPage
;
TD_DLIST_APPEND_WITH_FIELD
(
&
(
pPgCache
->
freeList
),
pPage
,
freeNode
);
}
#if 0
for (int32_t i = 0; i < nbucket; i++) {
TD_DLIST_INIT(pPgCache->pght.buckets + i);
}
#endif
*
ppPgCache
=
pPgCache
;
return
0
;
}
int
pgCacheClose
(
SPgCache
*
pPgCache
)
{
SPage
*
pPage
;
if
(
pPgCache
)
{
for
(
int32_t
i
=
0
;
i
<
pPgCache
->
npage
;
i
++
)
{
pPage
=
pPgCache
->
pages
[
i
];
tfree
(
pPage
->
pData
);
}
free
(
pPgCache
);
}
return
0
;
}
#define PG_CACHE_HASH(fileid, pgno) \
({ \
uint64_t *tmp = (uint64_t *)(fileid); \
(tmp[0] + tmp[1] + tmp[2] + (pgno)); \
})
SPage
*
pgCacheFetch
(
SPgCache
*
pPgCache
,
pgid_t
pgid
)
{
SPage
*
pPage
;
SPgFile
*
pPgFile
;
SPgList
*
pBucket
;
// 1. Search the page hash table SPgCache.pght
pBucket
=
pPgCache
->
pght
.
buckets
+
(
PG_CACHE_HASH
(
pgid
.
fileid
,
pgid
.
pgno
)
%
pPgCache
->
pght
.
nbucket
);
pPage
=
TD_DLIST_HEAD
(
pBucket
);
while
(
pPage
&&
tdbCmprPgId
(
&
(
pPage
->
pgid
),
&
pgid
))
{
pPage
=
TD_DLIST_NODE_NEXT_WITH_FIELD
(
pPage
,
pghtNode
);
}
if
(
pPage
)
{
// Page is found, pin the page and return the page
pgCachePinPage
(
pPage
);
return
pPage
;
}
// 2. Check the free list
pPage
=
TD_DLIST_HEAD
(
&
(
pPgCache
->
freeList
));
if
(
pPage
)
{
TD_DLIST_POP_WITH_FIELD
(
&
(
pPgCache
->
freeList
),
pPage
,
freeNode
);
pgCachePinPage
(
pPage
);
return
pPage
;
}
// 3. Try to recycle a page from the LRU list
pPage
=
TD_DLIST_HEAD
(
&
(
pPgCache
->
lru
));
if
(
pPage
)
{
TD_DLIST_POP_WITH_FIELD
(
&
(
pPgCache
->
lru
),
pPage
,
lruNode
);
// TODO: remove from the hash table
pgCachePinPage
(
pPage
);
return
pPage
;
}
// 4. If a memory allocator is set, try to allocate from the allocator (TODO)
return
NULL
;
}
int
pgCacheRelease
(
SPage
*
pPage
)
{
// TODO
return
0
;
}
static
void
pgCachePinPage
(
SPage
*
pPage
)
{
// TODO
}
static
void
pgCacheUnpinPage
(
SPage
*
pPage
)
{
// TODO
}
#if 0
// Exposed handle
typedef struct TDB_MPOOL TDB_MPOOL;
typedef struct TDB_MPFILE TDB_MPFILE;
typedef TD_DLIST_NODE(pg_t) pg_free_dlist_node_t, pg_hash_dlist_node_t;
typedef struct pg_t {
SRWLatch rwLatch;
frame_id_t frameid;
pgid_t pgid;
uint8_t dirty;
uint8_t rbit;
int32_t pinRef;
pg_free_dlist_node_t free;
pg_hash_dlist_node_t hash;
void * p;
} pg_t;
typedef TD_DLIST(pg_t) pg_list_t;
typedef struct {
SRWLatch latch;
TD_DLIST(TDB_MPFILE);
} mpf_bucket_t;
struct TDB_MPOOL {
int64_t cachesize;
pgsz_t pgsize;
int32_t npages;
pg_t * pages;
pg_list_t freeList;
frame_id_t clockHand;
struct {
int32_t nbucket;
pg_list_t *hashtab;
} pgtab; // page table, hash<pgid_t, pg_t>
struct {
#define MPF_HASH_BUCKETS 16
mpf_bucket_t buckets[MPF_HASH_BUCKETS];
} mpfht; // MPF hash table. MPFs using this MP will be put in this hash table
};
#define MP_PAGE_AT(mp, idx) (mp)->pages[idx]
typedef TD_DLIST_NODE(TDB_MPFILE) td_mpf_dlist_node_t;
struct TDB_MPFILE {
char * fname; // file name
int fd; // fd
uint8_t fileid[TDB_FILE_ID_LEN]; // file ID
TDB_MPOOL * mp; // underlying memory pool
td_mpf_dlist_node_t node;
struct
SPgHdr
{
void
*
pData
;
SPgid
pgid
;
SPgHdr
*
pFreeNext
;
};
/*=================================================== Exposed apis ==================================================*/
// TDB_MPOOL
int tdbMPoolOpen(TDB_MPOOL **mpp, uint64_t cachesize, pgsz_t pgsize);
int tdbMPoolClose(TDB_MPOOL *mp);
int tdbMPoolSync(TDB_MPOOL *mp);
// TDB_MPFILE
int tdbMPoolFileOpen(TDB_MPFILE **mpfp, const char *fname, TDB_MPOOL *mp);
int tdbMPoolFileClose(TDB_MPFILE *mpf);
int tdbMPoolFileNewPage(TDB_MPFILE *mpf, pgno_t *pgno, void *addr);
int tdbMPoolFileFreePage(TDB_MPOOL *mpf, pgno_t *pgno, void *addr);
int tdbMPoolFileGetPage(TDB_MPFILE *mpf, pgno_t pgno, void *addr);
int tdbMPoolFilePutPage(TDB_MPFILE *mpf, pgno_t pgno, void *addr);
int tdbMPoolFileSync(TDB_MPFILE *mpf);
static void tdbMPoolRegFile(TDB_MPOOL *mp, TDB_MPFILE *mpf);
static void tdbMPoolUnregFile(TDB_MPOOL *mp, TDB_MPFILE *mpf);
static TDB_MPFILE *tdbMPoolGetFile(TDB_MPOOL *mp, uint8_t *fileid);
static int tdbMPoolFileReadPage(TDB_MPFILE *mpf, pgno_t pgno, void *p);
static int tdbMPoolFileWritePage(TDB_MPFILE *mpf, pgno_t pgno, const void *p);
static void tdbMPoolClockEvictPage(TDB_MPOOL *mp, pg_t **pagepp);
int
tdbOpenPCache
(
int
pageSize
,
int
cacheSize
,
int
extraSize
,
SPCache
**
ppCache
)
{
SPCache
*
pCache
;
void
*
pPtr
;
SPgHdr
*
pPgHdr
;
int tdbMPoolOpen(TDB_MPOOL **mpp, uint64_t cachesize, pgsz_t pgsize) {
TDB_MPOOL *mp = NULL;
size_t tsize;
pg_t * pagep;
// check parameters
if (!TDB_IS_PGSIZE_VLD(pgsize)) {
tdbError("invalid page size");
pCache
=
(
SPCache
*
)
calloc
(
1
,
sizeof
(
*
pCache
));
if
(
pCache
==
NULL
)
{
return
-
1
;
}
// allocate handle
mp = (TDB_MPOOL *)calloc(1, sizeof(*mp));
if (mp == NULL) {
tdbError("failed to malloc memory pool handle");
goto _err;
}
// initialize the handle
mp->cachesize = cachesize;
mp->pgsize = pgsize;
mp->npages = cachesize / pgsize;
mp->clockHand = 0;
TD_DLIST_INIT(&mp->freeList);
mp->pages = (pg_t *)calloc(mp->npages, sizeof(pg_t));
if (mp->pages == NULL) {
tdbError("failed to malloc memory pool pages");
goto _err;
}
for (frame_id_t i = 0; i < mp->npages; i++) {
mp->pages[i].p = malloc(pgsize);
if (mp->pages[i].p == NULL) {
goto _err;
}
taosInitRWLatch(&mp->pages[i].rwLatch);
mp->pages[i].frameid = i;
mp->pages[i].pgid = TDB_IVLD_PGID;
// add new page to the free list
TD_DLIST_APPEND_WITH_FIELD(&(mp->freeList), &(mp->pages[i]), free);
}
#define PGTAB_FACTOR 1.0
mp->pgtab.nbucket = mp->npages / PGTAB_FACTOR;
mp->pgtab.hashtab = (pg_list_t *)calloc(mp->pgtab.nbucket, sizeof(pg_list_t));
if (mp->pgtab.hashtab == NULL) {
tdbError("failed to malloc memory pool hash table");
goto _err;
}
// return
*mpp = mp;
return 0;
_err:
tdbMPoolClose(mp);
*mpp = NULL;
return -1;
}
int tdbMPoolClose(TDB_MPOOL *mp) {
if (mp) {
tfree(mp->pgtab.hashtab);
if (mp->pages) {
for (int i = 0; i < mp->npages; i++) {
tfree(mp->pages[i].p);
}
free(mp->pages);
}
free(mp);
}
return 0;
}
int tdbMPoolFileOpen(TDB_MPFILE **mpfp, const char *fname, TDB_MPOOL *mp) {
TDB_MPFILE *mpf;
if ((mpf = (TDB_MPFILE *)calloc(1, sizeof(*mpf))) == NULL) {
return -1;
}
mpf->fd = -1;
if ((mpf->fname = strdup(fname)) == NULL) {
goto _err;
}
if ((mpf->fd = open(fname, O_CREAT | O_RDWR, 0755)) < 0) {
goto _err;
}
if (tdbGnrtFileID(fname, mpf->fileid, false) < 0) {
goto _err;
}
// Register current MPF to MP
tdbMPoolRegFile(mp, mpf);
*mpfp = mpf;
return 0;
_err:
tdbMPoolFileClose(mpf);
*mpfp = NULL;
return -1;
}
int tdbMPoolFileClose(TDB_MPFILE *mpf) {
if (mpf) {
if (mpf->fd > 0) {
close(mpf->fd);
}
tfree(mpf->fname);
free(mpf);
}
return 0;
}
pCache
->
pageSize
=
pageSize
;
pCache
->
cacheSize
=
cacheSize
;
pCache
->
extraSize
=
extraSize
;
#define MPF_GET_PAGE_BUCKETID(fileid, pgno, nbuckets) \
({ \
uint64_t *tmp = (uint64_t *)fileid; \
(tmp[0] + tmp[1] + tmp[2] + (pgno)) % (nbuckets); \
})
pthread_mutex_init
(
&
pCache
->
mutex
,
NULL
);
int tdbMPoolFileNewPage(TDB_MPFILE *mpf, pgno_t *pgno, void *addr) {
// TODO
return 0;
}
int tdbMPoolFileFreePage(TDB_MPOOL *mpf, pgno_t *pgno, void *addr) {
// TODO
return 0;
}
int tdbMPoolFileGetPage(TDB_MPFILE *mpf, pgno_t pgno, void *addr) {
pg_t * pagep;
TDB_MPOOL *mp;
pg_list_t *pglist;
mp = mpf->mp;
// check if the page already in pool
pglist = mp->pgtab.hashtab + MPF_GET_PAGE_BUCKETID(mpf->fileid, pgno, mp->pgtab.nbucket);
pagep = TD_DLIST_HEAD(pglist);
while (pagep) {
if (memcmp(mpf->fileid, pagep->pgid.fileid, TDB_FILE_ID_LEN) == 0 && pgno == pagep->pgid.pgno) {
break;
}
pagep = TD_DLIST_NODE_NEXT_WITH_FIELD(pagep, hash);
}
if (pagep) {
// page is found
// todo: pin the page and return
*(void **)addr = pagep->p;
return 0;
}
// page not found
pagep = TD_DLIST_HEAD(&mp->freeList);
if (pagep) {
// has free page
TD_DLIST_POP_WITH_FIELD(&(mp->freeList), pagep, free);
} else {
// no free page available
tdbMPoolClockEvictPage(mp, &pagep);
if (pagep) {
if (pagep->dirty) {
// TODO: Handle dirty page eviction
}
for
(
int
i
=
0
;
i
<
cacheSize
;
i
++
)
{
pPtr
=
calloc
(
1
,
pageSize
+
extraSize
+
sizeof
(
SPgHdr
));
if
(
pPtr
==
NULL
)
{
return
-
1
;
}
}
if (pagep == NULL) {
// no available container page
return -1;
}
pPgHdr
=
(
SPgHdr
*
)
&
((
char
*
)
pPtr
)[
pageSize
+
extraSize
];
pPgHdr
->
pFreeNext
=
pCache
->
pFree
;
pCache
->
pFree
=
pPgHdr
;
// load page from the disk if a container page is available
// TODO: load the page from the disk
if (tdbMPoolFileReadPage(mpf, pgno, pagep->p) < 0) {
return -1;
pCache
->
nFree
++
;
}
memcpy(pagep->pgid.fileid, mpf->fileid, TDB_FILE_ID_LEN);
pagep->pgid.pgno = pgno;
pagep->dirty = 0;
pagep->pinRef = 1;
// add current page to page table
TD_DLIST_APPEND_WITH_FIELD(pglist, pagep, hash);
return
0
;
}
int tdb
MPoolFilePutPage(TDB_MPFILE *mpf, pgno_t pgno, void *addr
) {
int
tdb
ClosePCache
(
SPCache
*
pCache
)
{
// TODO
return
0
;
}
#define MPF_GET_BUCKETID(fileid) \
({ \
uint64_t *tmp = (uint64_t *)fileid; \
(tmp[0] + tmp[1] + tmp[2]) % MPF_HASH_BUCKETS; \
})
static void tdbMPoolRegFile(TDB_MPOOL *mp, TDB_MPFILE *mpf) {
mpf_bucket_t *bktp;
bktp = mp->mpfht.buckets + MPF_GET_BUCKETID(mpf->fileid);
taosWLockLatch(&(bktp->latch));
TD_DLIST_APPEND_WITH_FIELD(bktp, mpf, node);
taosWUnLockLatch(&(bktp->latch));
mpf->mp = mp;
}
static TDB_MPFILE *tdbMPoolGetFile(TDB_MPOOL *mp, uint8_t *fileid) {
TDB_MPFILE * mpf = NULL;
mpf_bucket_t *bktp;
bktp = mp->mpfht.buckets + MPF_GET_BUCKETID(fileid);
taosRLockLatch(&(bktp->latch));
mpf = TD_DLIST_HEAD(bktp);
while (mpf) {
if (memcmp(fileid, mpf->fileid, TDB_FILE_ID_LEN) == 0) {
break;
}
mpf = TD_DLIST_NODE_NEXT_WITH_FIELD(mpf, node);
}
taosRUnLockLatch(&(bktp->latch));
return mpf;
}
static void tdbMPoolUnregFile(TDB_MPOOL *mp, TDB_MPFILE *mpf) {
mpf_bucket_t *bktp;
TDB_MPFILE * tmpf;
if (mpf->mp == NULL) return;
ASSERT(mpf->mp == mp);
bktp = mp->mpfht.buckets + MPF_GET_BUCKETID(mpf->fileid);
taosWLockLatch(&(bktp->latch));
tmpf = TD_DLIST_HEAD(bktp);
while (tmpf) {
if (memcmp(mpf->fileid, tmpf->fileid, TDB_FILE_ID_LEN) == 0) {
TD_DLIST_POP_WITH_FIELD(bktp, tmpf, node);
break;
}
tmpf = TD_DLIST_NODE_NEXT_WITH_FIELD(tmpf, node);
}
taosWUnLockLatch(&(bktp->latch));
ASSERT(tmpf == mpf);
}
static int tdbMPoolFileReadPage(TDB_MPFILE *mpf, pgno_t pgno, void *p) {
pgsz_t pgsize;
TDB_MPOOL *mp;
off_t offset;
size_t rsize;
mp = mpf->mp;
pgsize = mp->pgsize;
offset = pgno * pgsize;
// TODO: use loop to read all data
rsize = pread(mpf->fd, p, pgsize, offset);
// TODO: error handle
return 0;
}
static int tdbMPoolFileWritePage(TDB_MPFILE *mpf, pgno_t pgno, const void *p) {
pgsz_t pgsize;
TDB_MPOOL *mp;
off_t offset;
mp = mpf->mp;
pgsize = mp->pgsize;
offset = pgno * pgsize;
lseek(mpf->fd, offset, SEEK_SET);
// TODO: handle error
write(mpf->fd, p, pgsize);
// TODO: handle error
return 0;
}
static void tdbMPoolClockEvictPage(TDB_MPOOL *mp, pg_t **pagepp) {
pg_t * pagep;
frame_id_t och;
*pagepp = NULL;
och = mp->clockHand;
do {
pagep = mp->pages + mp->clockHand;
mp->clockHand = (mp->clockHand + 1) % mp->npages;
if (pagep->pinRef == 0) {
if (pagep->rbit == 1) {
pagep->rbit = 0;
} else {
break;
}
}
if (mp->clockHand == och) {
return;
}
} while (1);
*pagepp = pagep;
}
#endif
\ No newline at end of file
}
\ No newline at end of file
source/libs/tdb/src/inc/tdbInt.h
浏览文件 @
9e90dcc5
...
...
@@ -38,7 +38,7 @@ typedef int32_t pgno_t;
typedef
struct
{
uint8_t
fileid
[
TDB_FILE_ID_LEN
];
pgno_t
pgno
;
}
pgid_t
;
}
pgid_t
,
SPgid
;
#define TDB_IVLD_PGID (pgid_t){0, TDB_IVLD_PGNO};
...
...
@@ -65,9 +65,9 @@ static FORCE_INLINE int tdbCmprPgId(const void *p1, const void *p2) {
typedef
int32_t
frame_id_t
;
// pgsz_t
#define TDB_MIN_PGSIZE 512
#define TDB_MAX_PGSIZE 65536
#define TDB_DEFAULT_PGSIZE 4096
#define TDB_MIN_PGSIZE
512
#define TDB_MAX_PGSIZE
65536
#define TDB_DEFAULT_PGSIZE
4096
#define TDB_IS_PGSIZE_VLD(s) (((s) >= TDB_MIN_PGSIZE) && ((s) <= TDB_MAX_PGSIZE))
// pgoff_t
...
...
@@ -119,13 +119,13 @@ typedef TD_DLIST_NODE(SPgFile) SPgFileListNode;
#include "tdbUtil.h"
#include "tdbBtree.h"
//
#include "tdbBtree.h"
#include "tdbPgCache.h"
#include "tdbPgFile.h"
//
#include "tdbPgFile.h"
#include "tdbEnv.h"
//
#include "tdbEnv.h"
#ifdef __cplusplus
}
...
...
source/libs/tdb/src/inc/tdbPgCache.h
浏览文件 @
9e90dcc5
...
...
@@ -20,26 +20,12 @@
extern
"C"
{
#endif
typedef
struct
SP
gCache
SPg
Cache
;
typedef
struct
SP
age
SPage
;
typedef
struct
SP
Cache
SP
Cache
;
typedef
struct
SP
gHdr
SPgHdr
;
// SPgCache
int
pgCacheOpen
(
SPgCache
**
ppPgCache
,
TENV
*
pEnv
);
int
pgCacheClose
(
SPgCache
*
pPgCache
);
SPage
*
pgCacheFetch
(
SPgCache
*
pPgCache
,
pgid_t
pgid
);
int
pgCacheRelease
(
SPage
*
pPage
);
// SPage
typedef
TD_DLIST_NODE
(
SPage
)
SPgListNode
;
struct
SPage
{
pgid_t
pgid
;
// page id
frame_id_t
frameid
;
// frame id
uint8_t
*
pData
;
// real data
SPgListNode
freeNode
;
// for SPgCache.freeList
SPgListNode
pghtNode
;
// for pght
SPgListNode
lruNode
;
// for LRU
};
int
tdbOpenPCache
(
int
pageSize
,
int
cacheSize
,
int
extraSize
,
SPCache
**
ppCache
);
int
tdbPCacheClose
(
SPCache
*
pCache
);
void
*
tdbPCacheFetch
(
SPCache
*
pCache
);
#ifdef __cplusplus
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录