国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

Apache中的表格實(shí)現(xiàn)剖析(1)

2019-11-17 04:50:09
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
3.2表格(TABLE)
3.2.1表格概述
    盡管aPR_array_header_t數(shù)組已經(jīng)可以完成大部分的任務(wù),但是對(duì)于Apache而言,apr_array_header_t更傾向于內(nèi)部數(shù)據(jù)結(jié)構(gòu),它通常作為其余的線性數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)基礎(chǔ),比如表格、隊(duì)列以及哈希表。表格是Apache中用的最頻繁的數(shù)據(jù)結(jié)構(gòu),比如HTTP請(qǐng)求中的域以及配置文件中的命令都是通過表格進(jìn)行保存的。不過與通常的表格的含義不太相似,Apache表格更加與perl中的哈希表相似,唯一的區(qū)別就是在Apache表格中同樣的鍵值你可以存在兩次,而且表格是大小寫字母敏感的。
    Apache中表格的數(shù)據(jù)結(jié)構(gòu)是apr_table_t結(jié)構(gòu),該結(jié)構(gòu)在apache的apr_table.h中定義如下:
strUCt apr_table_t {
apr_array_header_t a;
#ifdef MAKE_TABLE_PROFILE
void *creator;
#endif
apr_uint32_t index_initialized;
int index_first[TABLE_HASH_SIZE];
int index_last[TABLE_HASH_SIZE];
};
    從表格的結(jié)構(gòu)可以看出,表格的內(nèi)部還是數(shù)組結(jié)構(gòu),表格的各種操作實(shí)質(zhì)上無(wú)非就是對(duì)數(shù)組元素操作的一種封裝而已。為了保持向下兼容,apr_array_header_t必須位于表格結(jié)構(gòu)的首部。由于表格結(jié)構(gòu)是Apache中新的數(shù)據(jù)結(jié)構(gòu),因此假如需要某些舊的只支持?jǐn)?shù)組的版本假如需要使用表格,只要使用將apr_table_t強(qiáng)制轉(zhuǎn)換為apr_array_header_t結(jié)構(gòu)就可以了。
    creator用來(lái)跟蹤表格的創(chuàng)建者。另外為了能夠加快對(duì)表格的訪問,結(jié)構(gòu)中增加了三個(gè)輔助的成員變量,即index_initialized,index_first,index_last。index_intialized是一個(gè)32位的無(wú)符號(hào)整數(shù),共對(duì)應(yīng)了32 Í 8個(gè)bit,系統(tǒng)中用256位中的第n位來(lái)記錄當(dāng)前分配空間的第n個(gè)元素是否已經(jīng)被初始化,假如初始化,該位為1,否則0。因此我們可以看到表格中的元素最多也只能為256個(gè)。
    表格中的一個(gè)元素要被使用之前必須對(duì)其所在的區(qū)域進(jìn)行初始化,初始化非常的簡(jiǎn)單,只是將index_initialized中對(duì)應(yīng)的bit位置為1即可。可以通過宏TABLE_SET_INDEX_INITIALIZED實(shí)現(xiàn)初始化。
    #define TABLE_SET_INDEX_INITIALIZED(t, i) ((t)->index_initialized = (1 << (i)))
    而判定一個(gè)對(duì)應(yīng)的元素是否被初始化,則用宏TABLE_INDEX_IS_INITIALIZED實(shí)現(xiàn):
    #define TABLE_INDEX_IS_INITIALIZED(t, i) ((t)->index_initialized & (1 << (i)))
    index_last和index_first數(shù)組的用法我們?cè)诤竺娴牟糠謺?huì)具體描述。
    表格中存放的每一個(gè)元素用結(jié)構(gòu)apr_table_entry_t描述:
    struct apr_table_entry_t {
char *key;
char *val;
apr_uint32_t key_checksum;
    };
    結(jié)構(gòu)中,key是鍵值,目前用來(lái)標(biāo)記表格中的每個(gè)元素,通常只有在對(duì)表格中的元素進(jìn)行迭代的時(shí)候才能對(duì)該值進(jìn)行檢查。在以后的版本中,該值可能被設(shè)置為NULL。val則是當(dāng)前元素的值。Key_checksum則是對(duì)鍵值key的校驗(yàn)值,一般在表格內(nèi)部使用。
    由于表格的核心數(shù)據(jù)結(jié)構(gòu)還是apr_array_header_t結(jié)構(gòu),因此對(duì)表格的大部分操作實(shí)際上還是對(duì)數(shù)組類型的操作。只不過此時(shí)數(shù)組的每個(gè)元素結(jié)構(gòu)變成了apr_table_entry_t而已。下面我們來(lái)看看表格是如何進(jìn)行操作的。
3.2.2創(chuàng)建表格
    為了創(chuàng)建一個(gè)表格,我們可以使用函數(shù)ap_make_table和apr_make_table,前者適用于Apache1.3,后者適用于2.0版本。函數(shù)定義生命如下:

APR_DECLARE(apr_table_t *) apr_table_make(apr_pool_t *p, int nelts)
{
    apr_table_t *t = apr_palloc(p, sizeof(apr_table_t));
    make_array_core(&t->a, p, nelts, sizeof(apr_table_entry_t), 0);
#ifdef MAKE_TABLE_PROFILE
    t->creator = __builtin_return_address(0);
#endif
    t->index_initialized = 0;
    return t;
}
    函數(shù)首先從內(nèi)存池p中分配處apr_table_t結(jié)構(gòu)大小的內(nèi)存塊,然后調(diào)用make_array_core(&t->a, p, nelts, sizeof(apr_table_entry_t), 0)為創(chuàng)建apr_table_t的內(nèi)部數(shù)組a,數(shù)組個(gè)數(shù)為nelts個(gè),每個(gè)元素的大小為sizeof(apr_table_entry_t)。假如nelts為零,函數(shù)將推遲內(nèi)存分配直到表格第一次使用為止。正如在數(shù)組部分看到的,表格會(huì)自動(dòng)的分配其需要的內(nèi)存空間,而不需要手工干涉。另外數(shù)組創(chuàng)建之后index_initialized被初始化為0,此時(shí)沒有任何數(shù)據(jù)被使用。
    下面的代碼演示了表格的創(chuàng)建操作:
    apr_table_t *my_table;
    my_table = apr_table_make(r->pool,10);
    至此函數(shù)將創(chuàng)建了一個(gè)空空如也的表格,下面要做的就是往里面不斷的放入apr_table_entry_t結(jié)構(gòu)的數(shù)據(jù)了。
    除了可以從頭開始創(chuàng)建一個(gè)新的表格,Apache中還答應(yīng)從一個(gè)原有的表格創(chuàng)建一個(gè)相同的表格,我們稱之為表格復(fù)制。表格復(fù)制實(shí)現(xiàn)如下:
APR_DECLARE(apr_table_t *) apr_table_copy(apr_pool_t *p, const apr_table_t *t)
{
    apr_table_t *new = apr_palloc(p, sizeof(apr_table_t));
 
    make_array_core(&new->a, p, t->a.nalloc, sizeof(apr_table_entry_t), 0);
    memcpy(new->a.elts, t->a.elts, t->a.nelts * sizeof(apr_table_entry_t));
    new->a.nelts = t->a.nelts;
    memcpy(new->index_first, t->index_first, sizeof(int) * TABLE_HASH_SIZE);
    memcpy(new->index_last, t->index_last, sizeof(int) * TABLE_HASH_SIZE);
    new->index_initialized = t->index_initialized;
    return new;
}
關(guān)于作者
張中慶,目前主要的研究方向是嵌入式瀏覽器,移動(dòng)中間件以及大規(guī)模服務(wù)器設(shè)計(jì)。目前正在進(jìn)行Apache的源代碼分析,計(jì)劃出版《Apache源代碼全景分析》上下冊(cè)。Apache系列文章為本書的草案部分,對(duì)Apache感愛好的朋友可以通過flydish1234 at sina.com.cn與之聯(lián)系!

假如你覺得本文不錯(cuò),請(qǐng)點(diǎn)擊文后的“推薦本文”鏈接!!


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 桐柏县| 广平县| 南昌市| 铜陵市| 邵东县| 胶州市| 韶山市| 柳河县| 石楼县| 河北省| 介休市| 宁晋县| 崇义县| 颍上县| 吉林省| 峨山| 横峰县| 洛隆县| 团风县| 晋宁县| 辽阳市| 乃东县| 蓝田县| 肃北| 定兴县| 安图县| 城固县| 美姑县| 易门县| 安徽省| 玉门市| 乐亭县| 子长县| 和龙市| 波密县| 杨浦区| 于都县| 南安市| 樟树市| 鄂托克前旗| 霍州市|