青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

無我

讓內心永遠燃燒著偉大的光明的精神之火!
靈活的思考,嚴謹的實現
豪邁的氣魄、頑強的意志和周全的思考

剖析eSNACC哈希結構的設計和實現

本文剖析hash.h/c,從源代碼來剖析eSNACC哈希結構的設計和實現。 

為什么要在這里剖析hash呢?一個順理成章的理由是:我們準備剖析eSNACC對ANY(s)類型的編碼和解碼,可是ANY的實現依賴于hash,所以我們就需要先把這條路打通了。O(∩_∩)O哈哈~是不是很有說服力呀?

 

好,閑話少述,言規正傳。我們知道hash對一個系統而言,一般都是一個很有價值的底層基礎設施。從作用上來說,他實現的優劣極大的影響著整個系統的性能。從技術上來說,也是很能體現含金量的一個模塊。所以,對eSNACC實現的這個寶藏,我們下定決心要刨根問底、直搗黃龍!

 

友情說明:本文不討論eSNACC用的hash函數,因為我們用了另外獨立的一篇文章來研究:剖析eSNACC的hash函數。本文研究的是eSNACC哈希結構的設計和實現。

 

先看頭文件:

#ifndef _asn_hash_h_
#define _asn_hash_h_

#ifdef __cplusplus
extern "C" {
#endif


#define TABLESIZE 256
#define INDEXMASK 0xFF
#define INDEXSHIFT 8

typedef 
void *Table[TABLESIZE];

typedef unsigned 
int Hash;

typedef 
struct HashSlot
{
  
int    leaf;
  Hash   hash;
  
void  *value;
  Table 
*table;
}
 HashSlot;

Hash MakeHash PROTO ((
char *str, unsigned long  len));

Table 
*InitHash();

int Insert PROTO ((Table *table, void *element, Hash hash));

int CheckFor PROTO ((Table *table, Hash hash));

int CheckForAndReturnValue PROTO ((Table *table, Hash hash, void **value));

#ifdef __cplusplus
}

#endif

#endif /* conditional include */

在這里,就利用這個頭文件,我想先和大家講清楚eSNACC的hash表的設計結構。

首先,eSNACC的每一個hash值用unsigned int來定義:typedef unsigned int Hash。

然后,定義的hash表結構——Table:typedef void *Table[TABLESIZE],是一個256維的指針數組。

那這個數組每個元素的內容是什么呢?是指向HashSlot結構的指針,也就是這個hash表的每一維是一個HashSlot。但是如果這樣,只能存放256個值呀,怎樣實現hash的呢?這個我們就要理解HashSlot的各個變量的意義了:

int    leaf : 當前HashSlot是不是樹的葉子。
Hash   hash :當前HashSlot元素的hash值。
void  *value :對應當前hash值元素內容,也就是實際值。
Table *table :如果當前HashSlot不是葉子,也就是說在當前hash有多個共用的元素,那么本字段就不為空,而是指向再次hash的表。

我做了一張簡單的示意圖來描述:

雖然不美觀,但還是希望你能從中看明白這個hash表的結構哦。

 

 

/******************************休息一下************************************

好了,有了對整個hash表設計的理解,我們就來研究具體的hash表操作函數

/* Creates and clears a new hash slot */
static HashSlot * NewHashSlot()
{
  HashSlot 
*foo;

  foo 
=  new HashSlot;
  
if (foo == NULL)
      
return NULL;
  memset (foo, 
0sizeof (HashSlot));
  
return foo;
}


/* Create a new cleared hash table */
static Table *NewTable()
{
  Table 
*new_table;

//  new_table = new Table;
// whose bug is it that gcc won't compile the above line?
  new_table = (Table *new Table;
  
if (new_table == NULL)
      
return NULL;
  memset (new_table, 
0sizeof (Table));
  
return new_table;
}


/* This routine is used to initialize the hash tables. When it is called
 * it returns a value which is used to identify which hash table
 * a particular request is to operate on.
 
*/

Table 
* InitHash()
{
  Table 
*table;
  table 
= NewTable();
  
if (table == NULL)
      
return 0;
  
else
      
return table;
}

上面三個很簡單,前兩個調用new創建HashSlot和Table,第三個就是用來初始最上層hash表的函數。

 

下面我們來看看將一個hash值為hash_value的元素element插入到哈希表table的具體實現:

/* This routine takes a hash table identifier, an element (value) and the
 * coresponding hash value for that element and enters it into the table
 * assuming it isn't already there.
 
*/

int Insert (Table *table, void *element, Hash hash_value)
{
  HashSlot 
*entry;

  entry 
= (HashSlot *) (*table)[hash_value & INDEXMASK];

  
if (entry == NULL) {
    
/* Need to add this element here */
    entry 
= NewHashSlot();
    
if (entry == NULL)
        
return false;
    entry
->leaf = true;
    entry
->value = element;
    entry
->hash = hash_value;
    (
*table)[hash_value & INDEXMASK] = entry;
    
return true;
  }


  
if (hash_value == entry->hash)
      
return false;

  
if (entry->leaf)
      
return SplitAndInsert (entry, element, hash_value);

  
return Insert (entry->table, element, hash_value >> INDEXSHIFT);
}

函數利用hash_value的最后一個字節來判斷該元素應該放在table中的維數,并且取出該維對應的HashSlot entry。

如果entry為空,那么也就是對應該hash_value還沒有元素,可以直接創建HashSlot,設定entry的value為element,hash為hash_value,因為當前只有這一個值,所以本HashSlot就是葉子,其table成員也為空。然后將該新的entry連到table的對應維上,完成。

如果entry不為空,依次判斷以下三種情況:

1、如果當前entry的hash等于hash_value,那就是hash值沖突,直接返回false。

2、如果當前entry是葉子,那么就得拆分當前HashSlot,使得他用table來存放多個值。

3、如果entry不是葉子了,那么就將本元素插到entry->table里面。

我們看一下SplitAndInsert:

/* When a hash collision occurs at a leaf slot this routine is called to
 * split the entry and add a new level to the tree at this point.
 
*/

static int SplitAndInsert (HashSlot *entry, void *element, Hash hash_value)
{

  
if (((entry->table = NewTable()) == NULL) ||
      
!Insert (entry->table, entry->value, entry->hash >> INDEXSHIFT) ||
      
!Insert (entry->table, element, hash_value >> INDEXSHIFT))
    
return false;

  entry
->leaf = false;
  
return true;
}

恩,很清楚,首先為entry的table分配一個Table,接著再將entry中原來存的值(entry->vlaue,entry->hash)插到表里,然后還將新加入的值(element,hash_value)插入表里。最后將entry的葉子屬性改為非葉子。

注意:在級聯的hash表里存的不是原來的hash值,而是依次將hash>>8.也就是出了最高層的哈希表,其他的都依次去掉最末尾的一個字節!!!

 

我們模擬插入兩個元素,假設其值和hash分別為A("tim",0xAA02),B("eSNACC",0xBB02).只是為了說明,我們假設原始table為空:

1,插入A:hash_value=0xAA02,所以應當插入到table的第三維,插入以后應當為:

2.插入B:hash_value=0xBB02,hash_value & 0xFF=2,所以又找到第三位,然后此時有HashSlot葉子,所以需要拆分,在插入后應當為:

利用這兩個圖,應該說得很清楚了吧,還是圖最清楚了!O(∩_∩)O哈哈~

 

好了,讓我們來看最后兩個函數:

/* This routine looks to see if a particular hash value is already stored in
 * the table. It returns true if it is and false otherwise.
 
*/

int CheckFor (Table *table, Hash hash)
{
  HashSlot 
*entry;

  entry 
= (HashSlot *) table[hash & INDEXMASK];

  
if (entry == NULL)
      
return false;
  
if (entry->leaf)
      
return entry->hash == hash;
  
return CheckFor (entry->table, hash >> INDEXSHIFT);
}


/* In addition to checking for a hash value in the tree this function also
 * returns the coresponding element value into the space pointed to by
 * the value parameter. If the hash value isn't found false is returned
 * the the space pointed to by value is not changed.
 
*/

int CheckForAndReturnValue (Table *table, Hash hash, void **value)
{
  HashSlot 
*entry;
  
if (table)
  
{
      entry 
= (HashSlot *) (*table)[hash & INDEXMASK];

      
if (entry == NULL)
          
return false;

      
if (entry->leaf)
      
{
          
if (entry->hash == hash)
          
{
              
*value = entry->value;
              
return true;
          }

          
else
              
return false;
      }

      
return CheckForAndReturnValue (entry->table, hash >> INDEXSHIFT, value);
  }

  
else
     
return false;
}

這兩個函數功能很清晰,就是在給定的哈希表table查找對應哈希值為hash的元素。只是CheckFor只是檢查table存在此hash否。而CheckForAndReturnValue則在存在時,將元素值存在value中返回。

 

好了,到此,eSNACC哈希結構的設計就已經全部分析完成了!祝大家學習愉快~

posted on 2012-04-26 15:36 Tim 閱讀(1781) 評論(1)  編輯 收藏 引用 所屬分類: eSNACC學習

評論

# re: 剖析eSNACC哈希結構的設計和實現[未登錄] 2012-04-27 09:31 Tina

寫的很好,圖的增加讓人很好理解。等待你的新作品!  回復  更多評論   

<2017年7月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

導航

統計

公告

本博客原創文章,歡迎轉載和交流。不過請注明以下信息:
作者:TimWu
郵箱:timfly@yeah.net
來源:m.shnenglu.com/Tim
感謝您對我的支持!

留言簿(9)

隨筆分類(173)

IT

Life

搜索

積分與排名

最新隨筆

最新評論

閱讀排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲一区二区视频在线观看| 中文成人激情娱乐网| 好吊色欧美一区二区三区四区| 欧美成人免费大片| 久久嫩草精品久久久精品| 香蕉亚洲视频| 久久se精品一区精品二区| 亚洲自啪免费| 久久精品国语| 久久综合给合久久狠狠色| 久久国产手机看片| 狼人天天伊人久久| 欧美另类综合| 精品91视频| 亚洲视频香蕉人妖| 久久女同互慰一区二区三区| 浪潮色综合久久天堂| 欧美韩日亚洲| 午夜精品偷拍| 亚洲欧美自拍偷拍| 久久综合国产精品台湾中文娱乐网| 亚洲国产精选| 亚洲午夜一区二区| 欧美大成色www永久网站婷| 国产精品jizz在线观看美国 | 伊人男人综合视频网| 亚洲美女诱惑| 亚洲第一在线综合网站| 久久精品在线免费观看| 国产精品毛片大码女人| 99国产精品一区| 欧美激情中文字幕一区二区| 欧美亚洲一区二区三区| 国产日韩欧美亚洲| 久久久国产精彩视频美女艺术照福利| 亚洲人体1000| 欧美日韩国产欧| 一本久久青青| 国产精品视频一| 久久精品1区| 久久久高清一区二区三区| 韩国欧美国产1区| 欧美成人黄色小视频| 欧美精品在欧美一区二区少妇| 亚洲福利视频一区二区| 亚洲日本免费电影| 国产精品一区二区三区久久| 久久亚洲国产精品日日av夜夜| 久久精品中文| 亚洲一级黄色| 麻豆精品网站| 欧美新色视频| 开心色5月久久精品| 欧美刺激午夜性久久久久久久| 中日韩视频在线观看| 性欧美暴力猛交另类hd| 亚洲日本激情| 久久久久久9| 欧美一区二区免费观在线| 狼人天天伊人久久| 亚洲午夜激情在线| 欧美精品免费播放| 欧美激情亚洲| 99成人免费视频| 欧美国产一区二区| 亚洲国产欧美在线人成| 国自产拍偷拍福利精品免费一| 99精品视频一区| 亚洲午夜在线视频| 欧美区日韩区| 欧美成人精品福利| 黑人操亚洲美女惩罚| 欧美伊久线香蕉线新在线| 亚洲欧美在线网| 国产视频久久久久| 欧美一区免费| 美女主播一区| 一区二区三区免费看| 欧美国产精品一区| 亚洲精品日产精品乱码不卡| 亚洲午夜小视频| 国内精品久久久久国产盗摄免费观看完整版 | 午夜日韩福利| 欧美性感一类影片在线播放 | 欧美激情一区二区三区成人 | 亚洲精品一区在线观看| 亚洲国产精品传媒在线观看| 农村妇女精品| 亚洲欧洲日产国产综合网| 亚洲在线一区二区| 亚洲精品一区二区三区福利| 欧美日韩精品免费观看| 亚洲美女视频在线观看| 亚洲最快最全在线视频| 国产亚洲毛片在线| 欧美日韩一区二区三区四区在线观看 | 亚洲免费在线精品一区| 精品99一区二区| 欧美日韩亚洲在线| 另类av一区二区| 亚洲一区欧美| 亚洲精品久久嫩草网站秘色| 久久免费视频观看| 欧美一区二区三区精品| 一区二区三区四区五区精品视频| 国产欧美一区二区三区视频| 欧美日韩视频在线一区二区 | 国产视频亚洲| 欧美视频中文字幕在线| 欧美黄色影院| 麻豆9191精品国产| 久久久久久欧美| 久久综合伊人77777蜜臀| 欧美一区91| 亚洲专区一区二区三区| 香蕉免费一区二区三区在线观看 | 久久久久久久久久久久久女国产乱 | 亚洲午夜激情免费视频| 亚洲午夜小视频| 亚洲——在线| 久久色中文字幕| 欧美高清一区二区| 日韩午夜av在线| 亚洲一区二区三区精品在线观看 | 午夜国产精品视频免费体验区| 日韩一本二本av| 亚洲欧美国产精品桃花| 久久综合影音| 欧美黄色免费网站| 亚洲精品偷拍| 久久精品人人爽| 欧美日本免费| 国产在线乱码一区二区三区| 亚洲国产欧美日韩精品| 亚洲一区二区三区涩| 麻豆成人在线播放| 日韩视频在线观看免费| 久久精品国产亚洲a| 亚洲第一在线综合在线| 久久精品亚洲国产奇米99| 欧美日韩在线第一页| 最新中文字幕亚洲| 久久伊人亚洲| 羞羞漫画18久久大片| 国产乱码精品一区二区三区忘忧草 | 国产一级久久| 午夜日韩在线观看| 一区二区三区成人| 欧美风情在线观看| 亚洲国内高清视频| 欧美二区在线播放| 美女视频黄免费的久久| 亚洲国产精品999| 亚洲高清不卡在线观看| 免费观看成人网| 日韩一级片网址| 一本一本久久a久久精品综合妖精| 欧美不卡视频一区| 亚洲视频欧美视频| 亚洲欧美日韩在线综合| 国产日韩欧美精品一区| 久久久久久91香蕉国产| 蜜臀久久久99精品久久久久久| 国内精品写真在线观看| 免费观看成人网| 欧美黑人国产人伦爽爽爽| 亚洲视频第一页| 亚洲欧洲99久久| 亚洲三级电影在线观看| 亚洲最新视频在线播放| 国产亚洲欧美一区在线观看| 亚洲成人在线免费| 欧美一区二区三区啪啪| 久久精品免费| 亚洲欧美成人一区二区在线电影 | 激情欧美日韩一区| 亚洲激情网站| 国内一区二区在线视频观看| 亚洲国产小视频| 激情久久久久久久久久久久久久久久| 亚洲第一福利在线观看| 国产精品一区二区视频| 亚洲国产精品t66y| 亚洲电影免费观看高清完整版在线观看| 亚洲一区二区精品在线| 国产精品国产三级国产专播品爱网| 在线观看亚洲视频| 亚洲韩国一区二区三区| 国产精品婷婷午夜在线观看| 99国产精品久久久久久久久久| 亚洲黄页视频免费观看| 久久国产精品99久久久久久老狼 | 亚洲欧美综合精品久久成人| 久久久99爱| 在线日韩视频| 久久综合给合久久狠狠狠97色69| aa级大片欧美三级| 亚洲欧洲精品成人久久奇米网| 久久久久国产精品一区三寸| 亚洲欧美激情视频在线观看一区二区三区|