apache常用的数据结构及使用方法

3.5.4  数据结构

Apache提供了4个数据结构模块。

·apr_table:提供表和数组

·apr_hash:提供了哈希表

·apr_queue:提供了先进先出队列(FIFO)

·apr_ring:提供了一个环结构,该结构也是APR的Bucket brigade的基础

3.5.4.1  数组

APR数组类型由apr_array_header_t类型提供,可以通过对象和指针两种方式进行访问。数组数据类型也可以作为堆栈。一个数组拥有一个默认的大小,并在数组创建时被设置。尽管数组在其默认大小范围内工作效率最高,但它还是可以根据需要增长。数组最常用的操作就是增加(压栈)和迭代。

/* 分配一个my_type 类型的数组 */
apr_array_header_t* arr = apr_array_make(pool, sz, sizeof(my_type)

/* 在数组中分配一个未初始化的元素 */
my_type* newelt = apr_array_push(arr) ;

/* 为elt进行赋值 */
newelt->foo = abc ;
newelt->bar = "foo" ;

/* 弹出最后面的元素 */
my_type* oldelt = apr_array_pop(arr) ;

/* 迭代所有的元素 */
for (i = 0; i < arr->nelts; i++) {
/* 一个 C++引用最能清晰地体现这个操作 */
my_type& elt = arr->elts[i] ;
}

其他的数组操作,包括pop出栈操作、复制(shallow copy,浅拷贝)、懒复制(lazy copy)、连接(concatenation)、增加(append)和转换为一个字符串变量(这个只有在数组的内容都是字符串变量时才比较有意义)。

3.5.4.2  表

apr_table_t是一个建立在数组之上的、直观的高层数据结构,用来存贮键/值(key/value)对。它支持增加元素(几个变种)、删除元素(效率不高)、查找、迭代以及清除整个表的操作。它也支持融合和覆盖操作,对数据进行融合或者清除冗余的元素。
表的键一般都是不分大小写的(这和APR哈希表的键不同)。

/* 新建一个表 */
apr_table_t* table = apr_table_make(pool, sz) ;

/* 设置键/值对 */
apr_table_setn(table, key, val) ;

apr_table_set的几个变种包括:apr_table_setn、apr_table_add、apr_table_addn、apr_table_merge、apr_table_mergen。

·apr_table_setn:设置一个值,为这个键覆盖任何已经存在的值。

·apr_table_addn:增加一个值,如果该键已经有值则留下复制的键。

·apr_table_mergen:增加一个新的值,将这个值和该键的任何一个已经有的值进行融合。

·apr_table_set:拷贝进入表中的数据。

·apr_table_setn:不拷贝进入表中的数据(因此如果表中的值是持久的,或者分配在同一个池上,这样做效率更高)。同样应用在其他函数上。

/* 取出一个数据项 */
val = apr_table_get(table, key) ;

/* 对表进行迭代(参见第5章)*/
apr_table_do(func, rec, table, NULL) ;

/* 清除这个表 */
apr_table_clear(table) ;

/* 融合两个表 */
newtable = apr_table_overlay(pool, table1, table2) ;

/* 删除冗余项 */
apr_table_compress(table, flags) ;

高层的API以及一些可用的函数如apr_table_merge和apr_table_overlap为处理HTTP头和Apache的环境变量打下了坚实的基础。

3.5.4.3  哈希表

apr_hash_t也是用来存贮键/值的,不过相对于apr_table_t它只是一个低层的数据类型。它有两个优点。

1. 键和值可以是任何的数据类型(并且,和表不同的是,键和值是大小写敏感的)。

2. 哈希表在元素数目增长时可以更加有效地扩大规模。

和数组、表不同的是,哈希表没有初始的大小。最常用的操作是插入和查找。哈希表支持的其他操作包括迭代、复制、覆盖和融合。

apr_hash_t* hash = apr_hash_make(pool) ;

/* 键和值是任何数据类型的指针 */
apr_hash_set(hash, key, sizeof(*key), value) ;
value = apr_hash_get(hash, key, sizeof(*key)) ;

我们通常会遇到的一个特殊情况是:键是一个字符串。为了保证使用正确的语义上的字符串比较,我们在size参数的位置使用APR_HASH_KEY_STRING宏。

3.5.4.4  队列

apr_queue_t是一个线程安全的、先进先出绑定的队列。它只能在使用线程的APR构建版本上使用。它用来保证多个线程在处理任务时的协作。队列具有固定大小的容量,该容量使用apr_queue_create设定。队列的主要操作是阻塞和非阻塞(blocking and nonblocking)的压入与弹出操作。

3.5.4.5  环

APR_RING实际上并不是一个数据类型,而有些类似于C++模板的一些宏的集合,这些宏实现了环状的双向链表。Apache中最主要的环状示例为Bucket brigade,我们将在3.5.5节进行介绍,并在第8章进行详细讨论。Bucket是环中的一个元素,而Brigade是这个环结构本身。下面是实现环结构的声明。

struct apr_Bucket {
/** 和Brigade的其他部分链接 */
APR_RING_ENTRY(apr_Bucket) link;
/** Bucket的数据区域 */
};

/** Bucket数据列表 */
struct apr_Bucket_brigade {
/** 和Brigade相关的池,数据没有在池之外进行分配,
*  但是在池中注册了一个清除操作。
*  如果这个Brigade 使用其他的机制进行清理,而不是使用池的方式,
*  那么这个清理函数需要负责注销这个清理操作。
*/
apr_pool_t *p;
/** 在Brigade中的Bucket都在这个链表上 */
/*
* apr_Bucket_list结构实际上不需要一个命名标签。
* 因为它不是脱离apr_Bucket_brigade结构而存在的。
* 设计了环的宏,在这种情况下你可以将命名标签置为空。
* 不过显然Windows的编译器不喜欢这么做。
*/
APR_RING_HEAD(apr_Bucket_list, apr_Bucket) list;
/** 从Bucket分配得到的freelist */
apr_Bucket_alloc_t *Bucket_alloc;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值