jabberd2: string pool
时间:2010-08-05 来源:fytzzh
spool利用pool来方便处理动态增长的字符串,spool维护一个单向链表,每追加一个字符串对应链表一个节点,这样的好处是可以很快速的追加新的字符串,而不需要使用realloc来动态扩展内存空间。只有当需要使用完整的字符串的时候,才动态分配一个大的内存空间,来合并链表中的所有节点。
传统的动态增长字符串的处理中一般都是预先分配比较大的内存空间,每次追加新字符串的时候,判断剩余内存是否够用,如果不够,需要使用realloc重新分配或者扩展内存大小。realloc如果是需要重新分配新的内存地址的时候,这时需要将”旧内存地址“里的数据拷贝到”新内存地址“。虽然使用预先分配比较大内存的做法可以减少reallloc的次数,但也会浪费一些内存空间。
spool每次追加新字符串的时候并不是真正插入到原字符串中,而是使用一个链表将每次追加的数据以链表一个节点形式插入,这样可以避免使用realloc来扩展内存空间。仅仅在使用该字符串的时候才将链表中的所有节点合并成一个大的字符串。可以看到spool这个特性,在需要频繁的追加新字符串的场合比传统需要realloc扩展空间的方法要高效的多。
下面我们来分析一下spool的数据结构和API:
/* --------------------------------------------------------- */
//链表中的节点数据结构 //用来保存追加的字符串指针 char *c;
//指向下一个节点的指针
typedef struct spool_struct
//spool_new传进来的参数,spool维护的内存都是从这里分配的
//所有字符串的总长度
//链表最后一个节点指针,新节点都是插入到尾部
//链表中第一个节点指针 |
API:
spool spool_new(pool_t p) |
void spool_add(spool s, char *str) |
void spool_escape(spool s, char *raw, int len) |
char *spool_print(spool s) |
void spooler(spool s, ...) |
char *spools(pool_t p, ...) |