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

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

系統(tǒng) 1860 0

1. 緣起:

假設(shè)我們的用戶管理系統(tǒng)要求用戶的 ID Name 都必須是唯一的,并且用戶的 ID Name 一經(jīng)確定就不能被修改。而且管理系統(tǒng)經(jīng)常需要根據(jù) ID 來查找 Name ,也經(jīng)常需要根據(jù) Name 來查找 ID 。根據(jù)這樣的需求,我們可以考慮使用一個(gè) Dictionary 來將 ID Name 緩存起來,通常 ID 作為 Key , Name 作為 Value 。這樣便可實(shí)現(xiàn)通過 ID 查詢 Name 的快速查找,但是,通過 Name 查找 ID 就不是那么快了,因?yàn)樯婕暗綄?duì) Dictionary Values 做遍歷的操作。那么,有可能使得通過 Name 查找 ID 的速度與通過 ID 查找 Name 的速度一樣快嗎?

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

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


2. 適用場(chǎng)合:

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

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

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

(3) 經(jīng)常需要根據(jù) Key 來查找 Value 。

(4) 經(jīng)常需要根據(jù) Value 來查找 Key 。

3 .設(shè)計(jì)思想與實(shí)現(xiàn)

IBidirectionalMapping 接口定義如下:

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

/// <summary>
/// Add添加映射對(duì)。如果已經(jīng)有相同的key/value存在,則會(huì)覆蓋。
/// </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();
}

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

在實(shí)現(xiàn) BidirectionalMapping 時(shí),我們使用兩個(gè) Dictionary 來完成雙向映射的功能。一個(gè) Dictionary T1 Key T2 Value ;另一個(gè)剛好反過來。

在實(shí)現(xiàn)的具體過程中,要注意以下幾點(diǎn):

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

(2) 在實(shí)現(xiàn) Add 方法添加一個(gè)“映射對(duì)”的時(shí)候,必須判斷當(dāng)前是否已經(jīng)存在了相同的值,如果存在,則先刪除舊的映射對(duì),再添加新的映射對(duì)。

(3) 要注意一個(gè)細(xì)節(jié), GetAllT1ListCopy GetAllT2ListCopy 的實(shí)現(xiàn)都使用了 lock ,這是因?yàn)樵诳截惖臅r(shí)候會(huì)對(duì)其 Keys Values 進(jìn)行 foreach 遍歷,而在對(duì) Dictionary 中的元素進(jìn)行 foreach 遍歷的時(shí)候,如果同時(shí)向其中添加或刪除元素,則 foreach 操作是會(huì)拋出異常的。

4. 使用時(shí)的注意事項(xiàng)

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

另外,映射對(duì)中的兩個(gè)元素的類型不一定非是 ID Name 這樣的簡(jiǎn)單對(duì)象,實(shí)際上,非常復(fù)雜的對(duì)象也可以緩存在雙向映射中,只要其 GetHashCode 方法實(shí)現(xiàn)的恰當(dāng)就不會(huì)有任何問題。

5. 擴(kuò)展

雙向映射 BidirectionalMapping 暫時(shí)沒有任何擴(kuò)展。

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

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


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

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

【本文對(duì)您有幫助就好】

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

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 宽城| 济南市| 砀山县| 崇仁县| 黎平县| 乌兰县| 济南市| 赣榆县| 繁峙县| 平陆县| 通道| 广东省| 铁岭市| 新和县| 绥宁县| 武强县| 禹州市| 神池县| 德惠市| 万山特区| 噶尔县| 陈巴尔虎旗| 隆子县| 三河市| 平舆县| 高台县| 塔河县| 清涧县| 综艺| 巴林右旗| 桐梓县| 西安市| 玉门市| 郸城县| 怀化市| 清丰县| 克拉玛依市| 澳门| 山阴县| 清水河县| 伊吾县|