📄 pager_bak.c
字号:
/**
* @brief create a page manager
* @param hm:mem pool handle
* @param file_name:file name
* @param page_release_cb:page release call back
* @param page_reload_cb:page reload call back
* @param extra_size:user extra data size for each page
* @param max_page:max pages count in cache
* @param page_size:the page size,if the page file existed,return the page size.it can be null.the default value is 1024
* @param used_rate:used rate, 0:means need not truncate,
* 1-9 means 10% - 90%,once the file's use rate was lower than int use rate,auto truncate occurs,
* >=10 means never truncate
*/
HPAGER PagerConstructor(HMYMEMPOOL hm,
const char * file_name,
PAGE_RELEASE page_release_cb,
PAGE_RELOAD page_reload_cb,
size_t extra_size,
size_t max_cache_pages,
size_t * page_size,
int used_rate)
{
pager_t * pager = NULL;
if(NULL == page_size || NULL == file_name)
{
LOG_WARN(("param err,page_size:%x, file_name:%x", page_size, file_name));
return NULL;
}
pager = MyMemPoolMalloc(hm, sizeof(*pager));
if(NULL == pager)
{
LOG_WARN(("fail malloc"));
return NULLL;
}
pager->hm = hm;
/* 保存日志文件名与外存文件名 */
pager->hb_file_name = MyBufferConstruct(hm, strlen(file_name) + 1);
pager->hb_journal_file_name = MyBufferConstruct(hm, strlen(file_name) + strlen(JOURNAL) + 1);
if(NULL == pager->hb_file_name || NULL == pager->hb_journal_file_name)
{
LOG_WARN(("fail malloc"));
goto PagerConstructor_err_;
}
MyBufferSet(pager->hb_file_name, file_name, strlen(file_name));
MyBufferAppend(pager->hb_file_name, "\0", 1);
MyBufferSet(pager->hb_journal_file_name, file_name, strlen(file_name));
MyBufferAppend(pager->hb_journal_file_name, JOURNAL, strlen(JOURNAL));
MyBufferAppend(pager->hb_journal_file_name, "\0", 1);
/* 打开外存文件 */
pager->hf = OsFileOpenReadWrite(file_name, hm);
if(NULL == pager->hf)
{
LOG_WARN(("fail open file : %s", file_name));
goto PagerConstructor_err_;
}
pager->pg_free_first = NULL;
pager->pg_free_last = NULL;
pager->pg_syncjf_first = NULL;
pager->pg_syncjf_last = NULL;
pager->bsync_journal = 0;
pager->in_journal_pages_count = 0;
pager->pg_all = NULL;
pager->pg_dirty = NULL;
/* 页缓存哈希表初始化 */
pager->hash_page = MyHashTableConstruct(hm, pg_hash_fun, pg_hash_keyequl_fun, 0);
if(NULL == pager->hash_page)
goto PagerConstructor_err_;
if(max_cache_pages)
pager->max_cache_pages = max_cache_pages;
else
pager->max_cache_pages = DEFAULT_CACHE_PAGES_COUNT;
/* 页是否处于journal状态的位着色表 */
bitvector_journal = mybitVectorConstruct(hm, pager->max_cache_pages, 0);
if(NULL == bitvector_journal)
goto PagerConstructor_err_;
pager->cached_page_count = 0;
pager->used_rate = used_rate;
pager->extra_size = extra_size;
/* 页的加载与取消引用时的回调函数 */
pager->page_release_cb = page_release_cb;
pager->page_reload_cb = page_reload_cb;
pager->page_move_cb = page_move_cb;
/* 每页大小 */
assert(page_size);
pager->page_size = *page_size;
if(pager->page_size < MIN_PAGE_SIZE)
pager->page_size = MIN_PAGE_SIZE;
else if(pager->page_size < MIN_PAGE_SIZE)
pager->page_size = MAX_PAGE_SIZE;
/* 获取页的大小,以及有多少页 */
if(-1 == pager_read_file_page_info())
goto PagerConstructor_err_;
/* 修正用户传进来的页大小 */
*page_size = pager->page_size;
return pager;
PagerConstructor_err_:
if(pager)
pager_destroy(pager);
return NULL;
}
/**
* @brief destroy a page management
*/
void PagerDestructor(HPAGER hpgr)
{
if(hpgr)
pager_destroy(hpgr);
}
/**
* @brief syn all the dirty page
*/
int PagerSyn(HPAGER hpgr)
{
if(NULL == hpgr)
return -1;
/*
* 先同步日志备份hjf,确保断电回滚
* 如果备份失败,同步也失败返回-1.
*/
if(0 != pager_sync_journal(hpgr))
return -1;
/* 将脏页写的hf */
if(0 != write_dirty_to_page_file(hpgr))
return -1;
/* 同步hf至外存 */
if(0 != OsFileSyn(hpgr->hf))
return -1;
/*关闭jf文件*/
if(hpgr->hjf)
OsFileClose(hpgr->hjf);
/* 删除jf文件 */
if(0 != OsFileDel((char *)MyBufferGet(hpgr->hb_journal_file_name, NULL)))
return -1;
return 0;
}
/**
* @brief 取消所有的页的更改
*/
extern int PagerRollBack(HPAGER hpgr);
/**
* @brief 申请一页
*/
void * PagerAllocPage(HPAGER hpgr)
{
if(NULL == hpgr)
return NULL;
/*
* 获取
*/
}
/**
* @brief 从页缓存管理中获取一页 与PagerReleasePage是对偶的操作
*/
extern void * PagerGetPage(HPAGER hpgr, size_t pgno)
{
pghd_t * pg = NULL;
if(NULL == hpgr)
return NULL;
/* 先在页缓存里查找相应的页 */
pg = page_hash_lookup(hpgr, pgno);
if(pg)
{
/* 引用计数加1,并根据需要从空闲链表里脱离 */
page_ref(hpgr, pg);
return pg;
}
/* 判断是否超出外存文件的最大页数 */
if(pgno > pager_get_pages_count(hpgr))
return NULL;
/* 如果找不到,从外存读入相应的缓存页 */
if(pager_get_cache_page_count(hpgr) > hpgr->max_cache_pages)
pager_recycle(hpgr, &pg);
else
{
????????????????
}
if(NULL == pg)
return NULL;
????
}
/**
* @brief 取消对当前页的引用 与PagerGetPage是对偶的操作
*/
extern int PagerReleasePage(void * page);
/**
* @brief write page
* @param page:the page to be written
*/
extern int PageHeadWrite(void * page);
/**
* @brief 将一个缓存页置成脏标志
*/
extern int PageHeadMakeDirty(void * page);
///**
// * @brief 判断是否空闲率是否达到上限
// */
//static __INLINE__ int pager_judge_need_truncate(pager_t * pager, int * need_truncate)
//{
// pghd_t * first_pg = NULL;
// pghd_t * pg_first_free = NULL;
// unsigned int first_free_no = 0;
// unsigned int total_free = 0;
// unsigned int total_pages_count = 0;
// int ret = 0;
//
// assert(pager && pager->hf && need_truncate);
// *need_truncate = 0;
//
// first_pg = pager_get_page(pager, PAGER_FIRST_PAGE_NO);
// if(NULL == first_pg)
// return -1;
//
// array_to_uint_as_big_endian(first_pg->pg_buf_start + PAGER_HDR_FIRST_FREE_OFFSET,
// sizeof(unsigned int),
// first_free_no);
//
// pg_first_free = pager_get_page(pager, first_free_no);
// if(NULL == pg_first_free)
// {
// ret = -1;
// goto pager_judge_need_truncate_end_;
// }
//
// array_to_uint_as_big_endian(pager_get_page_bufdata(pg_first_free) + PAGER_FREE_TOTAL_FREE_COUNT_OFFSET,
// sizeof(unsigned int),
// total_free);
//
// total_pages_count = pager_get_total_pages_count(pager);
//
// *need_truncate = (total_free * 10 / total_pages_count) > pager->used_rate ? 1 : 0;
//
//pager_judge_need_truncate_end_:
//
// if(first_pg)
// pager_release_page(first_pg);
// if(pg_first_free)
// pager_release_page(pg_first_free);
//
// return ret;
//}
///**
// * @brief 将一个数组按递增排序
// * > 0 表示 key1 大于 key2
// * == 0 表示 key1 等于 key2
// * < 0 表示 key1 小于 key2
// *
// * @param context:用户自定义的上下文数据
// */
//static int pager_sort_pgno_compare(const void * data1, const void * data2, const void * context)
//{
// unsigned int pgno1 = *((unsigned int *)data1);
// unsigned int pgno2 = *((unsigned int *)data2);
//
// if(pgno1 >= pgno2)
// return pgno1 - pgno2;
// else
// return -1;
//}
///**
// * @brief 将某一页移动到指定位置
// */
//static __INLINE__ int pager_move_page(pager_t * pager, pghd_t * src_pg, unsigned int dst_pgno)
//{
// pghd_t * dst_pg = NULL;
//
// assert(pager && pager->hf && src_pg && dst_pgno && pager == src_pg->pager);
// assert(src_pg->page_num != PAGER_FIRST_PAGE_NO);
//
// dst_pg = pager_get_page(pager, dst_pgno);
// if(NULL == dst_pg)
// return -1;
//
// /* 只允移向空闲的页中 */
// assert(!*(dst_pg->pg_buf_start + PAGER_PAGE_IN_USE_OFFSET));
//
// if(NULL == pager_make_page_writable(src_pg))
// {
// pager_release_page(dst_pg);
// return -1;
// }
//
// /* 将源页的内容拷贝至目标页,并且要通知用户程序此页被移动了 */
// memcpy(dst_pg->pg_buf_start, src_pg->pg_buf_start, pager->page_size);
// if(pager->page_move_cb)
// pager->page_move_cb(dst_pg, src_pg->page_num, dst_pgno);
//
// pager_release_page(dst_pg);
// return 0;
//}
///**
// * @brief 栽减空闲页
// */
//static __INLINE__ int pager_truncate_free_page(pager_t * pager)
//{
// /*
// * 计算出栽减后的大小(页文件总页数 - 空闲页总数)
// * 将空闲页表按页号递增排序
// * 从未尾开始,依次搬动每一个非空闲页至最小的空闲页中,并要调用回调通知用户程序
// * 判断当前页文件大小是否已达到栽减后的大小,如果是,则完成了栽减工作
// */
//
// pghd_t * first_page = NULL;
// pghd_t * pg_free = NULL;
// int ret = 0;
// unsigned int free_num = 0;
// unsigned int total_free = 0;
// unsigned int * pgno_array = NULL;
// unsigned int next_free = 0;
// unsigned int current_index = 0;
// int need_rollback = 0;
//
// assert(pager && pager->hf);
//
// if(!pager->page_file_is_integrity || pager->pg_dirty || pager->hjf || pager->ref_count)
// {
// /*
// * 如果当前页文件处于dirty状态,不做truncate操作
// * 如果当前有页缓存被引用,也不做truncate操作
// */
// return 0;
// }
//
// first_page = pager_get_page(pager, PAGER_FIRST_PAGE_NO);
// if(NULL == first_page)
// return -1;
//
// /* 首先完成排序,并且要把排序后的空闲页号写回 */
// array_to_uint_as_big_endian(first_page->pg_buf_start + PAGER_HDR_FIRST_FREE_OFFSET,
// sizeof(unsigned int),
// free_num);
//
// pg_free = pager_get_page(pager, free_num);
// if(NULL == pg_free)
// {
// ret = 0;
// goto pager_truncate_free_page_end_;
// }
//
// array_to_uint_as_big_endian(pager_get_page_bufdata(pg_free) + PAGER_FREE_TOTAL_FREE_COUNT_OFFSET,
// sizeof(unsigned int),
// total_free);
//
// pgno_array = MyMemPoolMalloc(pager->hm, total_free * sizeof(pgno_array[0]));
//
// /* 将所有的空闲页读入pgno_array内存数组 */
// while(1)
// {
// unsigned int current_free_count = 0;
// unsigned int i = 0;
//
// array_to_uint_as_big_endian(pager_get_page_bufdata(pg_free) + PAGER_FREE_FREE_PGNO_ARRAY_OFFSET,
// sizeof(unsigned int),
// current_free_count);
//
// /* 因为是以大码的方式存储,直接拷贝即可 */
// assert(current_index < total_free);
// pgno_array[current_index] = free_num;
// current_index ++;
//
// assert(current_index + current_free_count < total_free);
// memcpy(&pgno_array[current_index],
// pager_get_page_bufdata(pg_free) + PAGER_FREE_FREE_PGNO_ARRAY_OFFSET,
// current_free_count * sizeof(pgno_array[0]));
// current_index += current_free_count;
//
// array_to_uint_as_big_endian(pager_get_page_bufdata(pg_free) + PAGER_FREE_NEXT_FREE_LINK_OFFSET,
// sizeof(unsigned int),
// next_free);
//
// pager_release_page(pg_free);
// if(0 == next_free)
// break;
//
// pg_free = pager_get_page(pager, next_free);
// if(NULL == pg_free)
// {
// ret = -1;
// goto pager_truncate_free_page_end_;
// }
// }
//
// assert(current_index == total_free);
//
// /* 对数组进行排序 */
// {
// unsigned int swaper = 0;
// MyAlgQuickSort(pgno_array, total_free, sizeof(pgno_array[0]), pager_sort_pgno_compare,
// NULL, NULL, NULL, NULL, &swaper, sizeof(swaper));
// }
//
// /* 将第一个空闲页置成空 */
// if(NULL == pager_make_page_writable(first_page))
// {
// ret = -1;
// goto pager_truncate_free_page_end_;
// }
//
// uint_to_big_endian(0,
// first_page->pg_buf_start + PAGER_HDR_FIRST_FREE_OFFSET,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -