Search This Blog

Labels

Saturday, December 18, 2010

GHashTutorial

什么是ghash?

有时候你需要简单的查找列表,即便查询的数据链的大小未知,但是又要快速的存取(非线形搜索)。一个很好的办法就是使用hash表。在对未知任务没有线索的时候就可以设置自己的hash表。但是为什么要重复造轮子呢?在blender代码中已经有一个完整的一般性hash数据结构存在了。ZR编写的ghash让你可以使用最少的代码来设置一个hash。它可以为你提供一些选项。

一个可以索引的hash表
一个元素集

hash 表:一个hash表是一个让key和value配对的存储结构。让你可以通过key来找到value。ghash使用了指针来指定key 和 value。因为是用空指针来设置的,所以他们可以指向任何的类型和对象。一个应用的场合就是,你可能会用一个数据结构来存储一个editedge的临时 变更数据。每一个editedge,你可以使用editedge来作为你的key,然后动态分配一定的内存给你的更改数据结构再付value给他们,你就可以在需要这些改变数据的时候传一个key给hash,它就会返回指针指向的value。

一个元素集:假设,你只是想创建一个元素的动态链表。只要将key都给成null值。然后你就可以检查key是否在hash中,或者设置一个迭代器来遍列你hash的key。

使用ghash

最简单的ghash。我们从头文件开始。

代码:

#include "BLI_ghash.h"

声明我们的ghash,然后创建我们的新数据结构,通过整型函数指针传递hash,和hash需要用到的比较函数。函数的参数可以确定key和value如何匹配或者被hash,也可以用到更特殊的hash表中。

代码:

GHash *gh;

gh = BLI_ghash_new(BLI_ghashutil_ptrhash,BLI_ghashutil_ptrcmp);

当需要在hash中添加项目的时候,我们调用BLI_ghash_insert传递key和value给hash,这里key和value都是指针。

代码:

BLI_ghash_insert(gh, key, value);

当我们给函数 BLI_ghash_lookup一个key值,我们就可以返回一个value值。

代码:

value = BLI_ghash_lookup(gh, key);

创建一个动态对象集的办法就是放一个key和一个以null为值的value到hash,然后,使用 BLI_ghash_haskey 来看这个元素是否在hash中,返回的是1代表存在,0代表不存在。

代码:

BLI_ghash_haskey(gh,key)

使用下面函数来检查大小

代码:

BLI_ghash_size(gh)

如果所有的过程都完了,你也玩累了请记住要用下面的语句来清空。

代码:

BLI_ghash_free(gh, NULL, NULL);

Using An Iterator使用迭代器

创建了hash以后,我们还得逐个的遍历它,这样的话就得使用iterator。记住在使用iterator的同时不要向hash中插入元素,也不要将它释放清空。

我们先得声明我们的迭代器

代码:

GHashIterator* ghi;

然后再这样将它初始化,

代码:

ghi = BLI_ghashIterator_new(gh);

使用下面这个函数,它就会从第一个key开始完全逐个遍历所有key

代码:

BLI_ghashIterator_step(ghi);

下面这两个帮我们把key或者value获取,他们会返回key或者value,如果iterator正常的跑完了整个hash,你会从他们两得到相同的null。

代码:

BLI_ghashIterator_getKey(ghi);

代码:

BLI_ghashIterator_getValue(ghi);

iterator是否完成工作可以用它来测试,1为完成,0为没有。

代码:

BLI_ghashIterator_isDone(ghi);

然后释放整个iterator。

代码:

BLI_ghashIterator_free(ghi);

这里有一个例子,用来打印hash中的所有元素。

代码:

void print_hash(GHash *gh)
{
    GHashIterator *ghi = BLI_ghashIterator_new(gh);

    for (; BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi))
        printf("Key(%p) : Value(%p)\n", BLI_ghashIterator_getKey(ghi), BLI_ghashIterator_getValue(ghi));

    BLI_ghashIterator_free(ghi);
}

No comments:

Post a Comment