diff --git a/source/libs/tdb/src/db/tdbPCache.c b/source/libs/tdb/src/db/tdbPCache.c index 07c267a15c7aebe48b8d1efa75cd0119f7c721cc..d886cfd8898b7bdb65d254c195de1a788b7a0c39 100644 --- a/source/libs/tdb/src/db/tdbPCache.c +++ b/source/libs/tdb/src/db/tdbPCache.c @@ -34,18 +34,6 @@ struct SPCache { }) #define PAGE_IS_PINNED(pPage) ((pPage)->pLruNext == NULL) -// For page ref -#define TDB_INIT_PAGE_REF(pPage) ((pPage)->nRef = 0) -#if 0 -#define TDB_REF_PAGE(pPage) (++(pPage)->nRef) -#define TDB_UNREF_PAGE(pPage) (--(pPage)->nRef) -#define TDB_GET_PAGE_REF(pPage) ((pPage)->nRef) -#else -#define TDB_REF_PAGE(pPage) atomic_add_fetch_32(&((pPage)->nRef), 1) -#define TDB_UNREF_PAGE(pPage) atomic_sub_fetch_32(&((pPage)->nRef), 1) -#define TDB_GET_PAGE_REF(pPage) atomic_load_32(&((pPage)->nRef)) -#endif - static int tdbPCacheOpenImpl(SPCache *pCache); static void tdbPCacheInitLock(SPCache *pCache); static void tdbPCacheClearLock(SPCache *pCache); @@ -107,12 +95,7 @@ void tdbPCacheRelease(SPCache *pCache, SPage *pPage) { ASSERT(nRef >= 0); if (nRef == 0) { - if (1 /*TODO: page still clean*/) { - tdbPCacheUnpinPage(pCache, pPage); - } else { - // TODO - ASSERT(0); - } + tdbPCacheUnpinPage(pCache, pPage); } } @@ -192,6 +175,8 @@ static void tdbPCacheUnpinPage(SPCache *pCache, SPage *pPage) { tdbPCacheLock(pCache); + ASSERT(!pPage->isDirty); + nRef = TDB_GET_PAGE_REF(pPage); ASSERT(nRef >= 0); if (nRef == 0) { diff --git a/source/libs/tdb/src/db/tdbPager.c b/source/libs/tdb/src/db/tdbPager.c index a37309f032156cb4bd56c6e68cd81d34a5fd98d3..90496e126310984ff3aa2e3ae0a418638b68e3a2 100644 --- a/source/libs/tdb/src/db/tdbPager.c +++ b/source/libs/tdb/src/db/tdbPager.c @@ -132,6 +132,9 @@ int tdbPagerWrite(SPager *pPager, SPage *pPage) { if (pPage->isDirty) return 0; + // ref page one more time so the page will not be release + TDB_REF_PAGE(pPage); + // Set page as dirty pPage->isDirty = 1; @@ -187,6 +190,7 @@ int tdbPagerCommit(SPager *pPager) { // loop to write the dirty pages to file for (pPage = pPager->pDirty; pPage; pPage = pPage->pDirtyNext) { + // TODO: update the page footer ret = tdbPagerWritePageToDB(pPager, pPage); if (ret < 0) { ASSERT(0); @@ -194,7 +198,15 @@ int tdbPagerCommit(SPager *pPager) { } } - // TODO: loop to release the dirty pages + // release the page + for (pPage = pPager->pDirty; pPage; pPage = pPage->pDirtyNext) { + pPager->pDirty = pPage->pDirtyNext; + pPage->pDirtyNext = NULL; + + pPage->isDirty = 0; + + tdbPCacheRelease(pPager->pCache, pPage); + } // sync the db file tdbOsFSync(pPager->fd); @@ -202,6 +214,7 @@ int tdbPagerCommit(SPager *pPager) { // remote the journal file tdbOsClose(pPager->jfd); tdbOsRemove(pPager->jFileName); + pPager->dbOrigSize = pPager->dbFileSize; return 0; } diff --git a/source/libs/tdb/src/inc/tdbPCache.h b/source/libs/tdb/src/inc/tdbPCache.h index c7fa1556159ceeb98aa692ba27d8ea684b0aab9e..f71d34ab533ba82d7a6c158f548eb2702ce560f4 100644 --- a/source/libs/tdb/src/inc/tdbPCache.h +++ b/source/libs/tdb/src/inc/tdbPCache.h @@ -33,6 +33,18 @@ extern "C" { SPager *pPager; \ SPgid pgid; +// For page ref +#define TDB_INIT_PAGE_REF(pPage) ((pPage)->nRef = 0) +#if 0 +#define TDB_REF_PAGE(pPage) (++(pPage)->nRef) +#define TDB_UNREF_PAGE(pPage) (--(pPage)->nRef) +#define TDB_GET_PAGE_REF(pPage) ((pPage)->nRef) +#else +#define TDB_REF_PAGE(pPage) atomic_add_fetch_32(&((pPage)->nRef), 1) +#define TDB_UNREF_PAGE(pPage) atomic_sub_fetch_32(&((pPage)->nRef), 1) +#define TDB_GET_PAGE_REF(pPage) atomic_load_32(&((pPage)->nRef)) +#endif + int tdbPCacheOpen(int pageSize, int cacheSize, SPCache **ppCache); int tdbPCacheClose(SPCache *pCache); SPage *tdbPCacheFetch(SPCache *pCache, const SPgid *pPgid, bool alcNewPage);