Pine Blog

GLIB用户指南-关系

1.概念

GRelation 类似一张简单的数据库表;它包含一系列记录,或者 元组(tuples),每一个包含某干个域。 每个元组必须拥有相同数目的域,可以为任意的域指定索引,以支持对那个域进行查找。
作为示例,可以使用一系列元组来保存名字,一个域中保存名,第二个域中保存姓。两个域都可以被索引,以使得使用名或者姓都 可以进行快速查找。
GRelation 有一个缺点,那就是每个元组最多只能包含两个域。因此,不能将它作为内存中的数据库表缓存,除非表中列非常少。 我在 gtk-app-devel-list 邮件列表中搜索关于此问题的注解,发现早在 2000 年 2 月讨论到了一个补丁, 它可以将此扩展到四个域,但好像它从来没有加入到发行版本中。
GRelation 好像是一个鲜为人知的结构体;本教程中研究的开放源代码的应用程序当前都没有使用它。在 Web 上浏览时发现了一个开放源代码的 电子邮件客户机(Sylpheed-claws),出于各种不同目的使用了它,包括追踪 IMAP 文件夹和消息线程。所有它需要的可能只是一些宣传!
glib

2.基本操作

这里是一个示例,创建一个具有两个索引域的新的 GRelation,然后插入一些记录并执行一些基本的信息查询:

//ex-grelation-1.c
#include <glib.h>
int main(int argc, char** argv) {
 GRelation* r = g_relation_new(2);
 g_relation_index(r, 0, g_str_hash, g_str_equal);
 g_relation_index(r, 1, g_str_hash, g_str_equal);
 g_relation_insert(r, "Virginia", "Richmond");
 g_relation_insert(r, "New Jersey", "Trenton");
 g_relation_insert(r, "New York", "Albany");
 g_relation_insert(r, "Virginia", "Farmville");
 g_relation_insert(r, "Wisconsin", "Madison");
 g_relation_insert(r, "Virginia", "Keysville");
 gboolean found = g_relation_exists(r, "New York", "Albany");
 printf("New York %s found in the relation\n", found ? "was" : "was not");
 gint count = g_relation_count(r, "Virginia", 0);
 printf("Virginia appears in the relation %d times\n", count);
 g_relation_destroy(r);
 return 0;
}

***** Output *****

New York was found in the relation
Virginia appears in the relation 3 times

注意,索引恰好是在调用 g_relation_new 之后而在调用 g_relation_insert 之前 添加的。这是因为 g_relation_count 等其他 GRelation 函数要依赖现有的索引,如果索引不存在,则在运行时 会出错。
上面的代码中包括一个 g_relation_exists,用来查看“New York”是否在 GRelation 中。 这个请求会精确匹配关系中的每一个域;可以在任意一个索引的域上使用 g_relation_count 进行匹配。
在前面的 GHashTable 部分已经接触过 g_str_hash 和 g_str_equal; 在这里使用它们来对 GRelation 中的索引域进行快速查找。

3.选择元组

数据存入 GRelation 中后,可以使用 g_relation_select 函数来取出它。 结果是一个指向 GTuples 结构体的指针,通过它进一步查询可以获得实际的数据。 这里是它的使用方法:

//ex-grelation-2.c
#include <glib.h>
int main(int argc, char** argv) {
 GRelation* r = g_relation_new(2);
 g_relation_index(r, 0, g_str_hash, g_str_equal);
 g_relation_index(r, 1, g_str_hash, g_str_equal);
 g_relation_insert(r, "Virginia", "Richmond");
 g_relation_insert(r, "New Jersey", "Trenton");
 g_relation_insert(r, "New York", "Albany");
 g_relation_insert(r, "Virginia", "Farmville");
 g_relation_insert(r, "Wisconsin", "Madison");
 g_relation_insert(r, "Virginia", "Keysville");
 GTuples* t = g_relation_select(r, "Virginia", 0);
 printf("Some cities in Virginia:\n");
 int i;
 for (i=0; i < t->len; i++) {
     printf("%d) %s\n", i, g_tuples_index(t, i, 1));
 }
 g_tuples_destroy(t);
 t = g_relation_select(r, "Vermont", 0);
 printf("Number of Vermont cities in the GRelation: %d\n", t->len);
 g_tuples_destroy(t);
 g_relation_destroy(r);
 return 0;
}

***** Output *****

Some cities in Virginia:
0) Farmville
1) Keysville
2) Richmond
Number of Vermont cities in the GRelation: 0

关于选择和遍历元组的一些注解:

  • g_relation_select 返回的 GTuples 结构体中的记录没有特定的次序。 要找出返回了多少记录,请使用 GTuple
    结构体中的 len 成员。
  • g_tuples_index 接受三个参数:
  • GTuple 结构体
  • 正在查询的记录的索引
  • 希望获得的域的索引
  • 注意,需要调用 g_tuples_destroy 来正确地释放在 g_relation_select 期间所分配的内存。就算是记录实际上并没有被 GTuples 对象引用,这也是有效的。

文章转载自:https://blog.csdn.net/l197803/article/details/138244885?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EYuanLiJiHua%7EPosition-2-138244885-blog-52932358.235%5Ev43%5Epc_blog_bottom_relevance_base2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EYuanLiJiHua%7EPosition-2-138244885-blog-52932358.235%5Ev43%5Epc_blog_bottom_relevance_base2&utm_relevant_index=5,如有问题请联系删除。

未经允许不得转载:Pine Blog » GLIB用户指南-关系

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

Pine Blog
Anywhere, Anytime
E-mail:59054872@qq.com
苏ICP备15059480号-1