⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pager.c

📁 sourceforge历史版本完整下载: http://sourceforge.net/project/showfiles.php?group_id=202044 提供了基于b树索引算法的文件数据数据
💻 C
📖 第 1 页 / 共 5 页
字号:
/** * @brief 计算jf日志记录的长度 */#define pager_get_journal_rec_len(__pgr) (__pgr->page_size + sizeof(unsigned int) + sizeof(unsigned int))/** * @brief 写一个无符号整理数至文件 */static __INLINE__ int pager_write_uint_to_file(HOSFILE hf, unsigned int uint_val){	unsigned char acVal[sizeof(unsigned int)];	assert(hf);	uint_to_big_endian(uint_val, acVal, sizeof(acVal));	if(0 != OsFileWrite(hf, acVal, sizeof(acVal), NULL))		return -1;	return 0;}/** * @brief 从文件中读出一个整形数 */static __INLINE__ int pager_read_uint_from_file(HOSFILE hf, unsigned int * uint_val){	unsigned char acVal[sizeof(unsigned int)];	assert(hf && uint_val);	if(0 != OsFileRead(hf, acVal, sizeof(acVal), NULL))		return -1;	array_to_uint_as_big_endian(acVal, sizeof(acVal), *uint_val);	return 0;}/** * @brief 在页缓存哈希表中查找 */static __INLINE__ pghd_t * pager_hash_lookup(pager_t * pager, unsigned int pgno){	HMYHASHTABLE_ITER it = NULL;	assert(pager && pager->hash_page);	it = MyHashTableSearch(pager->hash_page, (void *)pgno);	if(NULL == it)		return NULL;	assert(MyHashTableGetIterData(it));	assert(((pghd_t *)MyHashTableGetIterData(it))->pager == pager);	return (pghd_t *)MyHashTableGetIterData(it);}/** * @brief 判断某一个是否处于free_list */#define pager_page_is_in_free_list(__pg) (__pg->pg_free_prev || __pg->pg_free_next || __pg == __pg->pager->pg_free_first)/** * @brief 判断某一个是否处于sync_jf list */#define pager_page_is_in_syncjf_list(__pg) (__pg->pg_syncjf_next || __pg->pg_syncjf_prev || __pg == __pg->pager->pg_syncjf_first)/** * @brief 判断某一个是否处于dirty list中 */#define pager_page_is_in_dirty_list(__pg) (__pg->pg_dirty_next || __pg->pg_dirty_prev || __pg == __pg->pager->pg_dirty)/** * @brief 判断某一个是否处于所有的页缓存链表中 */#define pager_page_is_in_all_list(__pg) (__pg->pg_all_next || __pg->pg_all_prev || __pg == __pg->pager->pg_all)/** * @brief 将某一个页缓存置成非dirty状态,并从dirty链表中脱离 */static __INLINE__ int pager_page_out_of_dirty_list(pager_t * pager, pghd_t * pg){	assert(pager && pg && pager == pg->pager);	assert(pager_page_is_in_dirty_list(pg));	if(pg == pager->pg_dirty)		pager->pg_dirty = pg->pg_dirty_next;	if(pg->pg_dirty_prev)		pg->pg_dirty_prev->pg_dirty_next = pg->pg_dirty_next;	if(pg->pg_dirty_next)		pg->pg_dirty_next->pg_dirty_prev = pg->pg_dirty_prev;	pg->pg_dirty_prev = NULL;	pg->pg_dirty_next = NULL;	return 0;}/** * @brief 将某个页缓存加入dirty list */static __INLINE__ int pager_add_page_to_dirty_list(pager_t * pager, pghd_t * pg){	assert(pager && pg && pager == pg->pager);	assert(!pager_page_is_in_dirty_list(pg));	assert(pager_page_is_dirty(pg));	pg->pg_dirty_prev = NULL;	pg->pg_dirty_next = pager->pg_dirty;	if(pager->pg_dirty)		pager->pg_dirty->pg_dirty_prev = pg;	pager->pg_dirty = pg;	return 0;}/** * @brief 将某一个页缓存置成dirty,并加入dirty链表 */static __INLINE__ int pager_make_page_dirty(pager_t * pager, pghd_t * pg, PAGE_EVENT evt){	assert(!pager_page_is_dirty(pg));	/* 修改页状态 */	pager_change_page_state(pg, evt);	pager_add_page_to_dirty_list(pager, pg);	return 0;}/** * @brief 从sync jf list里脱链 */static __INLINE__ int pager_out_syncjf_list(pager_t * pager, pghd_t * pg){	assert(pager && pg && pager == pg->pager);	assert(0 == pg->ref_count);	if(pg == pager->pg_syncjf_first)		pager->pg_syncjf_first = pg->pg_syncjf_next;	if(pg == pager->pg_syncjf_last)		pager->pg_syncjf_last = pg->pg_syncjf_prev;	/* 从已同步过日志的链表中脱链 */	if(pg->pg_syncjf_prev)		pg->pg_syncjf_prev->pg_syncjf_next = pg->pg_syncjf_next;	if(pg->pg_syncjf_next)		pg->pg_syncjf_next->pg_syncjf_prev = pg->pg_syncjf_prev;	pg->pg_syncjf_prev = NULL;	pg->pg_syncjf_next = NULL;	return 0;}/** * @brief 从free list里脱链,并从已同步jf页缓存链表中脱链 */static __INLINE__ int pager_out_free_list(pager_t * pager, pghd_t * pg){	assert(pager && pg && pager == pg->pager);	assert(0 == pg->ref_count);	if(pg == pager->pg_free_first)		pager->pg_free_first = pg->pg_free_next;	if(pg == pager->pg_free_last)		pager->pg_free_last = pg->pg_free_prev;	/* 从空闲页缓存链表中脱链 */	if(pg->pg_free_prev)		pg->pg_free_prev->pg_free_next = pg->pg_free_next;	if(pg->pg_free_next)		pg->pg_free_next->pg_free_prev = pg->pg_free_prev;	pg->pg_free_prev = NULL;	pg->pg_free_next = NULL;	pager_out_syncjf_list(pager, pg);	return 0;}/** * @brief 加入到空闲页缓存链表未尾 */static __INLINE__ int pager_add_to_free_list(pager_t * pager, pghd_t * pg){	assert(pager && pg && pager == pg->pager);	assert((NULL == pg->pg_free_next && NULL == pg->pg_free_prev) || (pg->pg_free_next && pg->pg_free_prev));	assert(0 == pg->ref_count);	pg->pg_free_prev = pager->pg_free_last;	if(pager->pg_free_last)		pager->pg_free_last->pg_free_next = pg;	pager->pg_free_last = pg;	if(NULL == pager->pg_free_first)		pager->pg_free_first = pg;	return 0;}/** * @brief 将某个页缓存加入到已同步的jf的链表未尾,并加入到空闲页缓存链表未尾 */static __INLINE__ int pager_add_to_syncjf_list(pager_t * pager, pghd_t * pg){	assert(pager && pg && pager == pg->pager);	assert(NULL == pg->pg_syncjf_next && NULL == pg->pg_syncjf_prev);	assert(0 == pg->ref_count);	pg->pg_syncjf_prev = pager->pg_syncjf_last;	if(pager->pg_syncjf_last)		pager->pg_syncjf_last->pg_syncjf_next = pg;	if(NULL == pager->pg_syncjf_first)		pager->pg_syncjf_first = pg;	pager->pg_syncjf_last = pg;	/* 加入到空闲页缓存链表 */	if(!pager_page_is_in_free_list(pg))		pager_add_to_free_list(pager, pg);	assert(pager_page_is_in_free_list(pg));	return 0;}/** * @brief 将某个页缓存加入页缓存哈希表和总的页缓存链表 */static __INLINE__ int pager_add_page_to_hash_and_list(pager_t * pager, pghd_t * pg){	assert(pager && pg && pg->pager == pager && pg->page_num);	if(NULL == MyHashTableInsertUnique(pager->hash_page, (void *)pg->page_num, pg))		return -1;	pg->pg_all_next = pager->pg_all;	if(pager->pg_all)		pager->pg_all->pg_all_prev = pg;	pager->pg_all = pg;	return 0;}/** * @brief 将某个页缓存从页缓存哈希表和总的页缓存链表脱离 */static __INLINE__ int pager_outof_page_from_hash_and_list(pager_t * pager, pghd_t * pg){	assert(pager && pg && pg->pager == pager && pg->page_num);	MyHashTableDelKey(pager->hash_page, (void *)(pg->page_num), NULL, NULL);	if(pg == pager->pg_all)		pager->pg_all = pg->pg_all_next;	if(pg->pg_all_prev)		pg->pg_all_prev->pg_all_next = pg->pg_all_next;	if(pg->pg_all_next)		pg->pg_all_next->pg_all_prev = pg->pg_all_prev;	pg->pg_all_prev = NULL;	pg->pg_all_next = NULL;	return 0;}/** * @brief 增加指定页的引用计数 */static __INLINE__ int pager_ref_page(pager_t * pager, pghd_t * pg){	assert(pager && pg);	assert(pg->pager == pager);	/* 如果引用计数零,则从空闲链表中除去,引用计数加1 */	if(0 == pg->ref_count)	{		//assert(pager_page_is_in_free_list(pg));		pager_out_free_list(pager, pg);		assert(!pager_page_is_in_free_list(pg));		assert(!pager_page_is_in_syncjf_list(pg));	}	pg->ref_count ++;	pager->ref_count ++;	return 0;}/** * @brief 初始化页缓存 */static __INLINE__ int pager_init_page(pager_t * pager, pghd_t * pg, unsigned int pgno){	assert(pager && pg && pgno != 0);	memset(pg, 0, sizeof(*pg));	/* 根据injournal着色图初始化相关标识 */	if(pager_page_in_journal(pager, pgno))		pg->pg_state = PAGE_CLEAN_SYNC;	else		pg->pg_state = PAGE_CLEAN;	pg->pager = pager;	pg->page_num = pgno;	memset(pg->pg_buf_start + pager_get_journal_rec_len(pg->pager), 0, pager->extra_size);	return 0;}/** * @brief 分配一个页缓存 */static __INLINE__ pghd_t * pager_allocate_page(pager_t * pager, unsigned int pgno){	/* 页头信息存储空间 + 页缓存空间 + 用户数据空间 + 页号与校验和存储空间 */	pghd_t * pg = (pghd_t *)MyMemPoolMalloc(pager->hm, sizeof(pghd_t) + pager->extra_size +		pager_get_journal_rec_len(pager));	if(NULL == pg)		return NULL;	pager_init_page(pager, pg, pgno);	return pg;}/** * @brief 释放一个页缓存 */static __INLINE__ int pager_free_page(pager_t * pager, pghd_t * pg){	assert(pager && pg && pager == pg->pager);	assert(0 == pg->ref_count);	assert(!pager_page_is_in_free_list(pg));	assert(!pager_page_is_in_syncjf_list(pg));	assert(!pager_page_is_in_dirty_list(pg));	pager_outof_page_from_hash_and_list(pager, pg);	MyMemPoolFree(pager->hm, pg);	return 0;}/** * @brief 同步备份日志至外存 */static __INLINE__ int pager_sync_journal(pager_t * pager){	pghd_t * pg = NULL;	assert(pager && pager->hjf);	/* 如果不需要同步,直接返回 */	if(!pager->need_sync_journal)		return 0;	/* 将日志头写入,主要为备份了多少页 */	if(0 != OsFileSeek(pager->hjf, pager->jouranl_prev_hdr + PAGER_JOURNAL_REC_COUNT_OFFSET))		return -1;	if(0 != pager_write_uint_to_file(pager->hjf, pager->in_journal_pages_count))		return -1;	if(0 != OsFileSeek(pager->hjf, pager->journal_end))		return -1;	/* 调用os的file sync接口同步至外存 */	if(0 != OsFileSyn(pager->hjf))		return -1;	pager->need_sync_journal = 0;	pager->bsync_journal_has_done = 1;	if(NULL == pager->pg_dirty)		return 0;	/* 将所有dirty页的need_sync_journal置成0 */	pg = pager->pg_dirty;	for(; pg; pg = pg->pg_dirty_next)	{		assert(pager_page_is_dirty(pg));		if(!pager_page_is_sync_journal(pg))			pager_change_page_state(pg, PAGE_EVT_SYNC_JOURNAL);		if(pg->ref_count)		{			assert(!pager_page_is_in_free_list(pg));			continue;		}		assert(pager_page_is_in_free_list(pg) && 0 == pg->ref_count);			if(!pager_page_is_in_syncjf_list(pg))			pager_add_to_syncjf_list(pager, pg);	}	return 0;}/** * @brief 获取外存文件包含有多少页 */static __INLINE__ unsigned int pager_get_total_pages_count(pager_t * pager){	int64 file_size = 0;	assert(pager && pager->hf);	if(pager->total_page_count != (unsigned int)-1)		return pager->total_page_count;	if(0 != OsFileSize(pager->hf, &file_size))		return -1;	pager->total_page_count = (unsigned int)(file_size / pager->page_size);	return pager->total_page_count;}/** * @brief 设置页文件的总页数 */#define pager_set_total_pages_count(__pgr, __pgno) do{ \	unsigned int total_pages_count = pager_get_total_pages_count(__pgr);\	assert(__pgno <= total_pages_count + 1);\	if(total_pages_count < __pgno) \		__pgr->total_page_count = __pgno;\	}while(0)/** * @brief 获取页缓冲的用户区首地址 */#define pager_get_page_bufdata(_pg) ((unsigned char *)(&(_pg[1])))/** * @brief 计算指定页号的页首在页文件中的偏移 */#define pager_cal_page_hdr_offset(__pgr, __pgno) (__pgr->page_size * (__pgno - 1))/** * @brief 根据页号,获取某一页的内容 */static __INLINE__ int pager_read_page_data(pager_t * pager, unsigned int pgno, unsigned char * buf, unsigned int buf_len){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -