hashmap 設計

先來看看泛型的數據隊列。
自然界中的數據關係多分爲兩種,拿人類來看,一類是靠人與人之間的關係來互相關聯,我稱爲關係型,另一種是靠屁股相互關聯,我稱爲位置型。
對於關係型,一個富豪家族,女屌絲想成爲其中成員很簡單,與其中一個老頭建立夫妻關係就加入了這個家族,被虐待了後想脫離它也很簡單,解除夫妻關係就完事了。
再看看位置型,比如廁所裏有20個坑,上面都貼上數字,有人報告第17個坑堵了,找起來會很方便。再比如某市一個市有20個市長,內部等級順序都分好了的,在一次內部會議合影時要排序,攝影員喊一聲第14位的拉鍊開了,第14位市長馬上就什麼知道是自己。
這兩種類型的優點都出來了:
關係型:插入,刪除成員方便。
位置型:查找方便。

並不是報喜不報憂,對方的優點就是已方的缺點,反之,已方的優點就是對方的缺點,大自然是很奇秒的。

人類最大的創新就是學習和模擬大自然,因爲大自然沒有申請專利保護。飛機是模彷鳥類,潛艇是模彷魚類,程序員也要模彷,於是便有了我們的數組和鏈表,分別對應位置型和關係型。
在標準庫裏,分別是 vector和 list.
vector 是分配一段連續的內存塊,一塊一塊的被填充,當填充完的時候,就整個重新分配,並把數據遷移過去,就像那些富豪家族在國內發展不了了,整個搬遷米國。
list 來一個分配一個,建立關係,走一個釋放一個。

vector,list 不是基於 key-value 型的,要把它封裝才能被當作緩存。
於是便有了前文提到的紅黑樹和本文的主角hash map.
紅黑樹的思想是關係型的,不過關係複雜點,模彷的更像點,有了父親,左孩子,右孩子的概念,其實理解成兒子和女兒又有何不可呢。
hash map 自然就是基本位置型的了。

那麼hash map的工作原理是什麼呢?
從名字上就可以看出來,新數據插入和查找都要經過兩步:
1.hash,就是散列。
2.map,就是存儲映射。

那麼爲什麼要散列呢,一切都是爲了找位置,明白了麼,就像那麼多副市長,是怎麼排序的,可以靠體型,也可以靠體重,散列的方法有很多種。
比如兩個字符串key: 
1.hello
2.world

如何才能快速的定位到哪個位置呢,可以把以首字母的ascii碼爲key, 就能快速存儲和快速查找了。hello 對應的是104, world 對應的是119.
hello 104
world 119

建立了一個對應表,既是hash表,也是map表。
再複雜一點,比如有下面的場景:
1.hello
2.hello world
3.world

第1種和第2種如何區別呢,共同對應104位,這個問題在學術上叫散列衝突,比如恰好有兩個副市長的體重一樣。

下面看看我是怎麼設計hash map的

typedef struct yumei_hash_map_s yumei_hash_map_t;
typedef struct yumei_cache_data_s yumei_cache_data_t;

struct yumei_hash_map_s
{
	int  reserve;
	yumei_cache_data_t*   data;

};

struct yumei_cache_map_data_s
{
	int key;
	int times;
	int start_time;

	void*  data;

	yumei_cache_map_data_t* next;
};

yumei_hash_map_t*   yumei_hash_map_create();
int yumei_hash_map_release( yumei_hash_map_t* hm );

int yumei_hash_map_insert( yumei_hash_map_t* hm, int key, void* data );
int yumei_hash_map_get( yumei_hash_map_t* hm, int key, void** data );
int yumei_hash_map_check( yumei_hash_map_t* hm );
int yumei_hash_map_update( yumei_hash_map_t* hm, int key, void* data );

整個框架就搭起來了,核心是散列和衝突的解決。
散列算法:
int kv = key &( reserve - 1 );

衝突解決:
while( tmp ){
	if( tmp->key == key ){
		break;
	}

	tmp = tmp->next;
}

data = tmp->data;

其實是在同一個位置上多掛幾個,就像一個市長位置上有幾個候選人,散列以後再來比對,這是最簡單有效的方法,當然如果需要在掛列上再進行排列或者特殊場景下的二次散列可能效果更好。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章