日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

ESBasic 可復用的.NET類庫(11) -- 雙向映射

系統 1785 0

1. 緣起:

假設我們的用戶管理系統要求用戶的 ID Name 都必須是唯一的,并且用戶的 ID Name 一經確定就不能被修改。而且管理系統經常需要根據 ID 來查找 Name ,也經常需要根據 Name 來查找 ID 。根據這樣的需求,我們可以考慮使用一個 Dictionary 來將 ID Name 緩存起來,通常 ID 作為 Key Name 作為 Value 。這樣便可實現通過 ID 查詢 Name 的快速查找,但是,通過 Name 查找 ID 就不是那么快了,因為涉及到對 Dictionary Values 做遍歷的操作。那么,有可能使得通過 Name 查找 ID 的速度與通過 ID 查找 Name 的速度一樣快嗎?

于是,我設計了 ESBasic.ObjectManagement.Cache.IBidirectionalMapping (雙向映射)來解決這個問題。

雙向映射的形象示意圖如下:
ESBasic 可復用的.NET類庫(11) -- 雙向映射 IBidirectionalMapping


2. 適用場合:

如果滿足以下的條件,則可以使用雙向映射:

(1) Key 是唯一的, Value 也是唯一的。

(2) 需要對 Key Value 做緩存。

(3) 經常需要根據 Key 來查找 Value

(4) 經常需要根據 Value 來查找 Key 。

3 .設計思想與實現

IBidirectionalMapping 接口定義如下:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> /// <summary>
/// IBidirectionalMapping雙向映射。即Key和Value都是唯一的,在這種情況下使用IBidirectionalMapping可提升依據Value查找Key的速度。
/// 該接口的實現必須是線程安全的。2008.08.20
/// </summary>
public interface IBidirectionalMapping < T1,T2 >
{
int Count{ get ;}

/// <summary>
/// Add添加映射對。如果已經有相同的key/value存在,則會覆蓋。
/// </summary>
void Add(T1t1,T2t2);

void RemoveByT1(T1t1);
void RemoveByT2(T2t2);

T1GetT1(T2t2);
T2GetT2(T1t1);

bool ContainsT1(T1t1);
bool ContainsT2(T2t2);

/// <summary>
/// GetAllT1ListCopy返回T1類型元素列表的拷貝。
/// </summary>
IList < T1 > GetAllT1ListCopy();

/// <summary>
/// GetAllT2ListCopy返回T2類型元素列表的拷貝。
/// </summary>
IList < T2 > GetAllT2ListCopy();
}

該接口使用了兩個泛型參數,根據上面的描述,一個泛型參數表示 Key 的類型,另一個泛型參數表示 Vlaue 的類型。由于,在雙向映射中, Key Value 是對稱的,所以我沒有使用 TKey TValue 來命名它們,而是使用 T1 T2 。

在實現 BidirectionalMapping 時,我們使用兩個 Dictionary 來完成雙向映射的功能。一個 Dictionary T1 Key , T2 Value ;另一個剛好反過來。

在實現的具體過程中,要注意以下幾點:

(1) 為了允許在多線程的環境中使用雙向映射,所以 BidirectionalMapping 必須在對內部 Dictionary 操作的時候進行加鎖控制。

(2) 在實現 Add 方法添加一個“映射對”的時候,必須判斷當前是否已經存在了相同的值,如果存在,則先刪除舊的映射對,再添加新的映射對。

(3) 要注意一個細節, GetAllT1ListCopy GetAllT2ListCopy 的實現都使用了 lock ,這是因為在拷貝的時候會對其 Keys Values 進行 foreach 遍歷,而在對 Dictionary 中的元素進行 foreach 遍歷的時候,如果同時向其中添加或刪除元素,則 foreach 操作是會拋出異常的。

4. 使用時的注意事項

BidirectionalMapping 提升了通過 Name 查找 ID 的速度,這是通過使用了更大的內存來做到的,是典型的“空間換時間”的例子。所以,對于巨大規模的映射對的緩存,要注意內存的使用問題。

另外,映射對中的兩個元素的類型不一定非是 ID Name 這樣的簡單對象,實際上,非常復雜的對象也可以緩存在雙向映射中,只要其 GetHashCode 方法實現的恰當就不會有任何問題。

5. 擴展

雙向映射 BidirectionalMapping 暫時沒有任何擴展。

注:ESBasic源碼可到 http://esbasic.codeplex.com/ 下載。
ESBasic討論:37677395
ESBasic開源前言

ESBasic 可復用的.NET類庫(11) -- 雙向映射 IBidirectionalMapping


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。?!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 海门市| 永宁县| 新宁县| 遂川县| 庆安县| 高青县| 南召县| 新津县| 台山市| 长沙县| 湘阴县| 肥东县| 交城县| 甘肃省| 台山市| 宣化县| 怀化市| 澎湖县| 安阳市| 贡嘎县| 永泰县| 鄯善县| 读书| 仙游县| 广元市| 天水市| 安吉县| 江油市| 台南县| 迭部县| 扎兰屯市| 临澧县| 博白县| 东山县| 开化县| 岳普湖县| 海宁市| 西宁市| 揭阳市| 微博| 班戈县|