现在的位置: 首页 > 综合 > 正文

/LGC设计模式/The Design of a cache buffer

2014年02月07日 ⁄ 综合 ⁄ 共 2200字 ⁄ 字号 评论关闭
The Design of a cache buffer
作者:
刘鹏
日期:

2008-11-26

在 GUI 系统中对资源进行高效管理是非常重要的问题。文本以图片管理为例,提出一个基于哈希表的 cache buffer。

背景

GUI 系统中往往会用到很多资源,如图片。若每次使用图片时都从磁盘装入内存,
由于磁盘读取速度很慢,效率会很低下。

我们可以设计一个 cache buffer,将读进来的图片缓存到 cache 里,当程序使
用图片时先去 cache 里找,若 cache 没有,再去磁盘读取。这跟 Linux
Kernel 针对磁盘块的 cache buffer 是一样的道理。

设计一个 cache ,需要考虑如下问题:

  • cache 采用什么样的数据结构;
  • 如何在 cache 中迅速找到需要的图片;
  • cache 满了之后如何处理,是否采用对换策略;若是,采用什么样的换出算
    法。

针对上述问题,本文提出一个采用哈希表加双向链表的 cache 设计策略。为了
简化问题,暂时没有考虑对换问题。

Buffer Cache 总体结构

使用哈希表组织和管理所有的数据,首先用哈希函数计算字符串在哪个链表,然
后根据 key 值顺序比较链表元素,查找对应的字符。

哈希队列结构示意图如下所示:

哈希队列示意图
哈希队列示意图

哈希链表结点如下图所示:

链表结点结构图
链表结点结构图

数据结构

数据结构代码如下所示:

typedef struct _RESCACHENODE {

unsigned char key[LENTH];
IMAGE* *image;
int ref_count;
int is_preload;

_RESCACHNODE* pre;
_RESCACHNODE* next;

} RESCACHENODE;


#define NR_HASH_ENTRIES 20

typedef struct _RESCACHE {

RECACHENODE* res_hash_table [NR_HASH_ENTRIES];

} RESCACHE;

RESCACHE res_cache = {0};

哈希函数

哈希函数的选择决定了查询速度,哈希函数需要满足以下要求:

  • 计算非常快;
  • 冲突均匀化。

下面是一个基于字符求和的哈希函数:

static int hash_string (const char* key)
{
int hval;
const char* ptr = (const char*) key;
char c;
int i;

hval = 0;
for (i = 1; (c = *ptr++); i++)
hval += c * i;

return (hval % NR_HASH_ENTRIES);
}

关于字符串哈希函数可见参考资源里的“字符串哈希函数研究”。

Buffer Cache 编程接口

/*
* Read images files top dir.
**/
static BOOL set_res_top_dir (void);

/* Init cache: set top dir and initialize lock **/
void init_cache (void);

/*
* Load the file to IMAGE object , add a new node to the cache and
* set is_preload to FALSE.
* If the node already exists, then ref_count ++; Otherwise, load
* the Bitmap.
*
* hdc: dc
* file: key value
* Return: If succeed, return TRUE; Otherwise return FALSE.
*/
BOOL insert_into_cache_from_file (HDC hdc, const char *file);


/*
* Load the memory data to IMAGE object, create a new node to the cache
* and set is_preload to FALSE.
* If the node already exists, then ref_count ++; Otherwise, load the
* image object.
*
* hdc: dc
* file: key value
* Return: If succeed, return TRUE; Otherwise return FALSE.
**/
BOOL insert_into_cache_from_mem (HDC hdc, const char* key,
const unsigned char* data, size_t data_size);


/*
* Find an IMAGE object in cache with the key value "file".
*
* file: key value
* If found, then return the pointer of the image; Otherwise, return NULL;
*/
IMAGE* retrieve_in_cache (const char *file);

/*
* Remove the IMAGE object from cache buffer.
* If ref_count > 1, then refcount --; Otherwise, unload the IMAGE object
* and detach the node from the cache.
* If is_preload == TRUE, then do not unload IMAGE object.
*
* file: key value
* image: image object.
*/
void remove_from_cache (const char *file);

SeeAlso

抱歉!评论已关闭.