APR源码都是一些高人不断持续的开发,很多算法做得非常巧妙,现在把这些精髓慢慢记录,以便将来能用上。
1. 块内存索引
APR 内存采取的则是“规则块”分配原则。支持的分配的最小空间是 8K,如果分配的空间达不到 8K 的大小,则按照 8K 去分配;如果需要的空间超过 8K,则将分配的空间往上调整为 4K 的倍数。这样内存就可以用索引来决定内存块的大小,索引和实际大小的转换关系为:index = (size >> BOUNDARY_INDEX) - 1;
2. 用二维指针记录上一个节点的next指针
APR在制作链表结构时,并不是用一个指针分别指向下一个节点和上一个节点。而是采用二维指针变量记录上一个节点的next指针。因为链表插入或删除操作时只是改变next指针而已。
例如:
struct apr_memnode_t的apr_memnode_t **ref;
apr_pool_cleanup_kill函数中的 lastp = &c->next;
3. 所有和链表插入或获取时有关的,都是采用更换链表头节点
APR对链表中的节点操作时,总是使用到头节点,这样操作时效率是最高的。所以很多链表操作时,最好能转换为这种模式。
例如:
allocator_free函数的freelist链表
node->next = freelist;freelist = node; 这样node就成为 freelist的头节点了。
apr_pool_cleanup_register函数中p->free_cleanups链表
c = p->free_cleanups;p->free_cleanups = c->next; 这样就从free_cleanups获取头节点
c->next = p->cleanups;p->cleanups = c; 这样c就成为p->cleanups的头节点了
apr_pool_cleanup_kill函数的p->free_cleanups
c->next = p->free_cleanups;p->free_cleanups = c;
这些例子很多.....