﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-一个能思想的人，才真是一个力量无边的人。 —— 巴尔扎克 -随笔分类-Redis分析</title><link>http://www.cppblog.com/IronOxide/category/19849.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 29 Aug 2012 15:08:22 GMT</lastBuildDate><pubDate>Wed, 29 Aug 2012 15:08:22 GMT</pubDate><ttl>60</ttl><item><title>Redis源码剖析：哈希表</title><link>http://www.cppblog.com/IronOxide/archive/2012/08/29/188667.html</link><dc:creator>IronOxide</dc:creator><author>IronOxide</author><pubDate>Wed, 29 Aug 2012 12:41:00 GMT</pubDate><guid>http://www.cppblog.com/IronOxide/archive/2012/08/29/188667.html</guid><wfw:comment>http://www.cppblog.com/IronOxide/comments/188667.html</wfw:comment><comments>http://www.cppblog.com/IronOxide/archive/2012/08/29/188667.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/IronOxide/comments/commentRss/188667.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/IronOxide/services/trackbacks/188667.html</trackback:ping><description><![CDATA[<span style="font-family: '宋体'; font-size: 10pt; font-weight: bold">声明：本文版权归IronOxide所有，博客地址：<a href="http://www.cppblog.com/IronOxide/"><span style="color: #3366ff">http://www.cppblog.com/IronOxide/</span></a></span><br />&nbsp;<br /><strong><span style="font-size: 12pt">Hash</span></strong><strong><span style="font-family: 宋体; font-size: 12pt">表（</span></strong><strong><span style="font-size: 12pt">Hash Table</span></strong><strong><span style="font-family: 宋体; font-size: 12pt">）</span></strong><strong><span style="font-size: 12pt"></span></strong>
<p><strong>&nbsp;</strong></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp; hash</span><span style="font-family: 宋体">表实际上由</span>size<span style="font-family: 宋体">个的桶组成一个桶数组</span>table[0...size-1] <span style="font-family: 宋体">。当一个对象经过哈希之后，</span><span style="font-family: 宋体">得到一个相应的</span>value , <span style="font-family: 宋体">于是我们把这个对象放到桶</span>table[ value ]<span style="font-family: 宋体">中。当一个桶中有</span><span style="font-family: 宋体">多个对象时，我们把桶中的对象组织成为一个链表。这在冲突处理上称之为</span><span style="font-family: 宋体; color: red">拉链法。</span></p>
<p>&nbsp;</p>
<p><strong><span style="font-family: 宋体; font-size: 12pt">负载因子（</span></strong><strong><span style="font-size: 12pt">load factor</span></strong><strong><span style="font-family: 宋体; font-size: 12pt">）</span></strong><strong><span style="font-size: 12pt"> </span></strong></p>
<p><strong>&nbsp;</strong></p>
<p><span>&nbsp;&nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体">假设一个</span>hash<span style="font-family: 宋体">表中桶的个数为</span> size , <span style="font-family: 宋体">存储的元素个数为</span>used .<span style="font-family: 宋体">则我们称</span> used / size <span style="font-family: 宋体">为</span><span style="font-family: 宋体; color: red">负载因子</span><span style="color: red">loadFactor </span>. <span style="font-family: 宋体">一般的情况下，当</span>loadFactor&lt;=1<span style="font-family: 宋体">时，</span>hash<span style="font-family: 宋体">表查找的期望复杂度为</span>O(1).&nbsp;<span style="font-family: 宋体">因此，每次往</span>hash<span style="font-family: 宋体">表中添加元素时，我们必须保证是在</span>loadFactor &lt;1<span style="font-family: 宋体">的情况下，才能够添加。</span></p>
<p>&nbsp;</p>
<p><strong><span style="font-family: 宋体; font-size: 12pt">容量扩张（</span></strong><strong><span style="font-size: 12pt">Expand</span></strong><strong><span style="font-family: 宋体; font-size: 12pt">）</span></strong><strong><span style="font-size: 12pt">&amp;&nbsp;</span></strong><strong><span style="font-family: 宋体; font-size: 12pt">分摊转移</span></strong><strong></strong></p>
<p><strong>&nbsp;</strong></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">当我们添加一个新元素时，一旦</span>loadFactor<span style="font-family: 宋体">大于等于</span>1<span style="font-family: 宋体">了，我们不能单纯的往</span>hash<span style="font-family: 宋体">表里边添加元素。因为添加完之后，</span>loadFactor<span style="font-family: 宋体">将大于</span>1<span style="font-family: 宋体">，这样也就不能保证查找的期望时间复杂度为常数级了。这时，我们应该对桶数组进行一次容量扩张，让</span>size<span style="font-family: 宋体">增大</span> <span style="font-family: 宋体">。这样就能保证添加元素后</span> used / size <span style="font-family: 宋体">仍然小于等于</span>1 <span style="font-family: 宋体">，</span> <span style="font-family: 宋体">从而保证查找的期望时间复杂度为</span>O(1).<span style="font-family: 宋体">但是，如何进行容量扩张呢？</span> C++<span style="font-family: 宋体">中的</span>vector<span style="font-family: 宋体">的容量扩张是一种好方法。于是有了如下思路</span> <span style="font-family: 宋体">：　</span>Hash<span style="font-family: 宋体">表中每次发现</span>loadFactor==1<span style="font-family: 宋体">时，就开辟一个原来桶数组的两倍空间（称为新桶数组），然后把原来的桶数组中元素全部转移过来到新的桶数组中。注意这里转移是需要元素一个个重新哈希到新桶中的，原因后面会讲到。</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">这种方法的缺点是，容量扩张是一次完成的，期间要花很长时间一次转移</span>hash<span style="font-family: 宋体">表中的所有元素。这样在</span>hash<span style="font-family: 宋体">表中</span>loadFactor==1<span style="font-family: 宋体">时，往里边插入一个元素将会等候很长的时间。<br />&nbsp;&nbsp;&nbsp;&nbsp;</span>redis<span style="font-family: 宋体">中的</span>dict.c<span style="font-family: 宋体">中的设计思路是用两个</span>hash<span style="font-family: 宋体">表来进行进行扩容和转移的工作：当从第一个</span>hash<span style="font-family: 宋体">表的</span>loadFactor=1<span style="font-family: 宋体">时，如果要往字典里插入一个元素，首先为第二个</span>hash<span style="font-family: 宋体">表开辟</span>2<span style="font-family: 宋体">倍第一个</span>hash<span style="font-family: 宋体">表的容量，同时将第一个</span>hash<span style="font-family: 宋体">表的一个非空桶中元素全部转移到第二个</span>hash<span style="font-family: 宋体">表中，然后把待插入元素存储到第二个</span>hash<span style="font-family: 宋体">表里。继续往字典里插入第二个元素，又会将第一个</span>hash<span style="font-family: 宋体">表的一个非空桶中元素全部转移到第二个</span>hash<span style="font-family: 宋体">表中，然后把元素存储到第二个</span>hash<span style="font-family: 宋体">表里&#8230;&#8230;直到第一个</span>hash<span style="font-family: 宋体">表为空。</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;</span><span style="font-family: 宋体">这种策略</span><span style="font-family: 宋体; color: red">就把第一个</span><span style="color: red">hash</span><span style="font-family: 宋体; color: red">表所有元素的转移分摊为多次转移</span><span style="font-family: 宋体">，而且每次转移的期望时间复杂度为</span>O(1)<span style="font-family: 宋体">。这样就不会出现某一次往字典中插入元素要等候很长时间的情况了。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">为了更深入的理解这个过程，先看看在</span>dict.h<span style="font-family: 宋体">中的两个结构体：</p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="font-family: Courier; color: #000000">typedef&nbsp;</span><span style="font-family: Courier; color: #0000ff">struct</span><span style="font-family: Courier; color: #000000">&nbsp;dictht&nbsp;{<br /></span><span style="font-family: Courier; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;dictEntry&nbsp;</span><span style="font-family: Courier; color: #000000">**</span><span style="font-family: Courier; color: #000000">table;<br /></span><span style="font-family: Courier; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="font-family: Courier; color: #0000ff">long</span><span style="font-family: Courier; color: #000000">&nbsp;size;<br /></span><span style="font-family: Courier; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="font-family: Courier; color: #0000ff">long</span><span style="font-family: Courier; color: #000000">&nbsp;sizemask;<br /></span><span style="font-family: Courier; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="font-family: Courier; color: #0000ff">long</span><span style="font-family: Courier; color: #000000">&nbsp;used;<br /></span><span style="font-family: Courier; color: #000000">}&nbsp;dictht;<br /><br /></span><span style="font-family: Courier; color: #000000">typedef&nbsp;</span><span style="font-family: Courier; color: #0000ff">struct</span><span style="font-family: Courier; color: #000000">&nbsp;dict&nbsp;{<br /></span><span style="font-family: Courier; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;dictType&nbsp;</span><span style="font-family: Courier; color: #000000">*</span><span style="font-family: Courier; color: #000000">type;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-family: Courier; color: #0000ff">void</span><span style="color: #000000">&nbsp;</span><span style="font-family: Courier; color: #000000">*</span><span style="font-family: Courier; color: #000000">privdata;<br /></span><span style="font-family: Courier; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;dictht&nbsp;ht[</span><span style="font-family: Courier; color: #000000">2</span><span style="font-family: Courier; color: #000000">];<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-family: Courier; color: #0000ff">int</span><span style="font-family: Courier; color: #000000">&nbsp;rehashidx;&nbsp;</span><span style="font-family: Courier; color: #008000">/*</span><span style="font-family: Courier; color: #008000">&nbsp;rehashing&nbsp;not&nbsp;in&nbsp;progress&nbsp;if&nbsp;rehashidx&nbsp;==&nbsp;-1&nbsp;</span><span style="font-family: Courier; color: #008000">*/</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-family: Courier; color: #0000ff">int</span><span style="font-family: Courier; color: #000000">&nbsp;iterators;&nbsp;</span><span style="font-family: Courier; color: #008000">/*</span><span style="font-family: Courier; color: #008000">&nbsp;number&nbsp;of&nbsp;iterators&nbsp;currently&nbsp;running&nbsp;</span><span style="font-family: Courier; color: #008000">*/</span><span style="color: #000000"><br /></span><span style="font-family: Courier; color: #000000">}&nbsp;dict;</span><span style="color: #000000"><br /></span></div>
<p style="text-indent: 21pt"></p>
<p style="text-indent: 26.25pt; margin: 0cm 0cm 0pt; mso-char-indent-count: 2.5" class="MsoNormal"><span lang="EN-US"><font face="Calibri">dictht</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">指的就是上面说的桶数组，</span><span lang="EN-US"><font face="Calibri">size</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">用来表示容量，一般为</span><span lang="EN-US"><font face="Calibri">2^n </font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">，</span><span lang="EN-US"><font face="Calibri">sizemask</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">（一般为</span><span lang="EN-US"><font face="Calibri">2^n-1,</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">二进制表示为</span><span lang="EN-US"><font face="Calibri">n</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">个</span><span lang="EN-US"><font face="Calibri">1</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">）用来对哈希值取模</span><span lang="EN-US"><font face="Calibri"> , used</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">表示</span><span lang="EN-US"><font face="Calibri">hash</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">表中存储了多少个元素。</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span lang="EN-US"><font face="Calibri">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dict</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">表示字典，由两个桶数组组成，</span><span lang="EN-US"><font face="Calibri">type</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">是一些函数指针（哈希函数及</span><span lang="EN-US"><font face="Calibri">key</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">，</span><span lang="EN-US"><font face="Calibri">value</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的一些处理函数）。<br /><br /></span></p>
<p style="text-indent: 21pt"></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-size: 12pt" lang="EN-US"><font face="Calibri">d-&gt;rehashidx <o:p></o:p></font></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-size: 12pt" lang="EN-US"><o:p><font face="Calibri">&nbsp;</font></o:p></span></strong></p>
<p style="text-indent: 21pt; margin: 0cm 0cm 0pt; mso-char-indent-count: 2.0" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">这个变量的理解很关键：</span></p>
<p style="text-indent: 21pt; margin: 0cm 0cm 0pt; mso-char-indent-count: 2.0" class="MsoNormal"><span lang="EN-US"><font face="Calibri">d-&gt;rehashidx </font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">表明了新元素到底是存储到桶数组</span><span lang="EN-US"><font face="Calibri">0</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">中，还是桶数组</span><span lang="EN-US"><font face="Calibri">1</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">中，同时指明了</span><span lang="EN-US"><font face="Calibri">d-&gt;h[0]</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">中到底是哪一个桶转移到</span><span lang="EN-US"><font face="Calibri">d-&gt;h[1]</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">中。</span></p>
<p style="text-indent: 21pt; margin: 0cm 0cm 0pt; mso-char-indent-count: 2.0" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">当</span><span lang="EN-US"><font face="Calibri">d-&gt;rehashidx==-1</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">时，这时新添加的元素应该存储在桶数组</span><span lang="EN-US"><font face="Calibri">0</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">里边。</span></p>
<p style="text-indent: 21pt; margin: 0cm 0cm 0pt; mso-char-indent-count: 2.0" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">当</span><span lang="EN-US"><font face="Calibri">d-&gt;rehashidx!=-1 </font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">时，表示应该将桶数组</span><span lang="EN-US"><font face="Calibri">0</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">中的第一个非空桶元素全部转移到桶数组</span><span lang="EN-US"><font face="Calibri">1</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">中来</span><span lang="EN-US"><font face="Calibri">(</font></span><span style="font-family: 宋体; color: red; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">不妨称这个过程为桶转移，或者称为</span><span lang="EN-US"><font face="Calibri"><span style="color: red">rehash)</span></font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">。这个过程必须将非空桶中的元素一个个重新哈希放到桶数组</span><span lang="EN-US"><font face="Calibri">1</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">中，因为</span><span lang="EN-US"><font face="Calibri">d-&gt;h[1]-&gt;sizemask</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">已经不同于</span><span lang="EN-US"><font face="Calibri">d-&gt;h[0]-&gt;sizemask</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">了。这时新添加的元素应该存储在桶数组</span><span lang="EN-US"><font face="Calibri">1</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">里边，因为此刻的桶数组</span><span lang="EN-US"><font face="Calibri">0</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的</span><span lang="EN-US"><font face="Calibri">loadFactor</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">为</span><span lang="EN-US"><font face="Calibri">1 </font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">，而桶数组</span><span lang="EN-US"><font face="Calibri">1</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的</span><span lang="EN-US"><font face="Calibri">loadFactor</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">小于</span><span lang="EN-US"><font face="Calibri">1 </font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">。</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span lang="EN-US"><o:p><font face="Calibri">&nbsp;</font></o:p></span></p>
<p style="text-indent: 21pt; margin: 0cm 0cm 0pt; mso-char-indent-count: 2.0" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">当发现桶数组</span><span lang="EN-US"><font face="Calibri">0</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">中的元素全部都转移到桶数组</span><span lang="EN-US"><font face="Calibri">1</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">中，即桶数组</span><span lang="EN-US"><font face="Calibri">0</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">为空时。释放桶数组</span><span lang="EN-US"><font face="Calibri">0</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的空间，把桶数组</span><span lang="EN-US"><font face="Calibri">0</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的指针指向桶数组</span><span lang="EN-US"><font face="Calibri">1</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">。将</span><span lang="EN-US"><font face="Calibri">d-&gt;rehashidx</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">赋值为</span><span lang="EN-US"><font face="Calibri">-1 </font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">，</span><font face="Calibri"> </font><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">这样桶数组</span><span lang="EN-US"><font face="Calibri">1</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">就空了，下次添加元素时，仍然添加到桶数组</span><span lang="EN-US"><font face="Calibri">0</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">中。直到桶数组</span><span lang="EN-US"><font face="Calibri">0</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的元素个数超过桶的个数，我们又重新开辟桶数组</span><span lang="EN-US"><font face="Calibri">0</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的</span><span lang="EN-US"><font face="Calibri">2</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">倍空间给桶数组</span><span lang="EN-US"><font face="Calibri">1 </font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">，</span><font face="Calibri"> </font><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">同时修改</span><span lang="EN-US"><font face="Calibri">d-&gt;rehashidx=0</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">，这样下次添加元素是就添加到桶数组</span><span lang="EN-US"><font face="Calibri">1</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">中去了。</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span lang="EN-US"><o:p><font face="Calibri">&nbsp;</font></o:p></span></p>
<p style="text-indent: 21pt; margin: 0cm 0cm 0pt; mso-char-indent-count: 2.0" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">值得注意的是，在每次删除、查找、替换操作进行之前，根据</span><span lang="EN-US"><font face="Calibri">d-&gt;rehashidx</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的状态来判断是否需要进行桶转移。这可以加快转移速度。</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span lang="EN-US"><o:p><font face="Calibri">&nbsp;</font></o:p></span></p>
<p style="text-indent: 21pt; margin: 0cm 0cm 0pt; mso-char-indent-count: 2.0" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">下面是一份精简的伪代码，通过依次插入</span><span lang="EN-US"><font face="Calibri">element[1..n]</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">这</span><span lang="EN-US"><font face="Calibri">n</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">个元素到</span><span lang="EN-US"><font face="Calibri">dict</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">来详细描述容量扩张及转移的过程：<br /><br /></p>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-family: Courier; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; text-decoration: ; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000">//</span><span style="color: #008000">初始化两个hash表</span><span style="color: #008000"><br /></span><span style="color: #000000">d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">h[</span><span style="color: #000000">0</span><span style="color: #000000">].size&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">4</span><span style="color: #000000">&nbsp;;&nbsp;d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">h[</span><span style="color: #000000">1</span><span style="color: #000000">].used&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">&nbsp;;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">分配四个空桶</span><span style="color: #008000"><br /></span><span style="color: #000000">d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">h[</span><span style="color: #000000">1</span><span style="color: #000000">].size&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">&nbsp;;&nbsp;d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">h[</span><span style="color: #000000">1</span><span style="color: #000000">].used&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">&nbsp;;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">初始化一个空表</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;<br /></span><span style="color: #0000ff">for</span><span style="color: #000000">(i&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">&nbsp;;&nbsp;i&nbsp;</span><span style="color: #000000">&lt;=</span><span style="color: #000000">&nbsp;n&nbsp;;&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">&nbsp;i){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">rehashidx&nbsp;</span><span style="color: #000000">!=-</span><span style="color: #000000">1</span><span style="color: #000000">&nbsp;){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">h[</span><span style="color: #000000">0</span><span style="color: #000000">]</span><span style="color: #000000">-&gt;</span><span style="color: #000000">used&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;把&nbsp;d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">h[</span><span style="color: #000000">0</span><span style="color: #000000">]中一个非空桶元素转移（重新hash）到&nbsp;d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">h[</span><span style="color: #000000">1</span><span style="color: #000000">]中&nbsp;&nbsp;；&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;上一步会使得:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;d-&gt;h[0]-&gt;used&nbsp;-=&nbsp;转移的元素个数&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;d-&gt;h[1]-&gt;used&nbsp;+=&nbsp;转移的元素个数&nbsp;；</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;把&nbsp;element[i]&nbsp;哈希到&nbsp;d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">h[</span><span style="color: #000000">1</span><span style="color: #000000">]中&nbsp;&nbsp;;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;d-&gt;h[1]-&gt;used&nbsp;++&nbsp;</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #0000ff">else</span><span style="color: #000000">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">用桶数组1覆盖桶数组0；&nbsp;赋值前要释放d-&gt;h[0]的空间，赋值后重置d-&gt;h[1])</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">h[</span><span style="color: #000000">0</span><span style="color: #000000">]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">h[</span><span style="color: #000000">1</span><span style="color: #000000">]&nbsp;;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">rehashidx&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">&nbsp;;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;把element[i]哈希到d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">h[</span><span style="color: #000000">0</span><span style="color: #000000">]中；</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;d-&gt;h[0]-&gt;used&nbsp;++&nbsp;;&nbsp;</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">h[</span><span style="color: #000000">0</span><span style="color: #000000">]</span><span style="color: #000000">-&gt;</span><span style="color: #000000">used&nbsp;</span><span style="color: #000000">&gt;=</span><span style="color: #000000">&nbsp;d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">h[</span><span style="color: #000000">0</span><span style="color: #000000">]</span><span style="color: #000000">-&gt;</span><span style="color: #000000">size&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">h[</span><span style="color: #000000">1</span><span style="color: #000000">]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;bucket[</span><span style="color: #000000">2</span><span style="color: #000000">*</span><span style="color: #000000">d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">h[</span><span style="color: #000000">0</span><span style="color: #000000">]</span><span style="color: #000000">-&gt;</span><span style="color: #000000">size&nbsp;];&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;d-&gt;h[0]-&gt;size&nbsp;等于d-&gt;h[0]-&gt;size的2倍&nbsp;</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;把element[i]哈希到d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">h[</span><span style="color: #000000">1</span><span style="color: #000000">]中&nbsp;;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;d-&gt;h[1]-&gt;used&nbsp;++&nbsp;</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">rehashidx&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #0000ff">else</span><span style="color: #000000">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;把element[i]哈希到d</span><span style="color: #000000">-&gt;</span><span style="color: #000000">h[</span><span style="color: #000000">0</span><span style="color: #000000">]中;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;d-&gt;h[0]-&gt;used&nbsp;++&nbsp;</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /></span></div>
<p style="text-indent: 21pt; margin: 0cm 0cm 0pt; mso-char-indent-count: 2.0" class="MsoNormal"><br /><br /><br /></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; font-size: 12pt; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">字典的迭代器（</span></strong><strong style="mso-bidi-font-weight: normal"><span style="font-size: 12pt" lang="EN-US"><font face="Calibri">Iterator</font></span></strong><strong style="mso-bidi-font-weight: normal"><span style="font-family: 宋体; font-size: 12pt; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">）</span></strong><strong style="mso-bidi-font-weight: normal"><span style="font-size: 12pt" lang="EN-US"><o:p></o:p></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span lang="EN-US"><o:p><font face="Calibri">&nbsp;</font></o:p></span></p>
<p style="text-indent: 21pt; margin: 0cm 0cm 0pt; mso-char-indent-count: 2.0" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">分为<strong style="mso-bidi-font-weight: normal">安全迭代器</strong></span><span lang="EN-US"><font face="Calibri">( safe Iterator )</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">和<strong style="mso-bidi-font-weight: normal">非安全迭代器</strong></span><font face="Calibri"> </font><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">。<br /><br /></span></p>
<p style="text-indent: 21pt; margin: 0cm 0cm 0pt; mso-char-indent-count: 2.0" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">安全迭代器能够保证在迭代器未释放之前，字典两个</span><span lang="EN-US"><font face="Calibri">hash</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">表之间不会进行桶转移。<br /><br /></span></p>
<p style="text-indent: 21pt; margin: 0cm 0cm 0pt; mso-char-indent-count: 2.0" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">桶转移对迭代器的影响是非常大的，假设一个迭代器指向</span><span lang="EN-US"><font face="Calibri">d-&gt;h[0]</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的某个桶中的元素实体，在一次桶转移后，这个实体被</span><span lang="EN-US"><font face="Calibri">rehash</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">到</span><span lang="EN-US"><font face="Calibri">d-&gt;h[1]</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">中。而在</span><span lang="EN-US"><font face="Calibri">d-&gt;h[1]</font></span><span style="font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">中根本不知道哪些元素被迭代器放过过，哪些没有被访问过，这样有可能让迭代器重复访问或者缺失访问字典中的一些元素。所以安全迭代器能够保证不多不少不重复的访问到所有的元素（当然在迭代过程中，不能涉及插入新元素和删除新元素的操作）。</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span lang="EN-US"><o:p><font face="Calibri">&nbsp;</font></o:p></span></p>
<p style="text-indent: 21pt; margin: 0cm 0cm 0pt; mso-char-indent-count: 2.0" class="MsoNormal"><br /></span></p>
<p style="text-indent: 21pt"><br /></span></p><img src ="http://www.cppblog.com/IronOxide/aggbug/188667.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/IronOxide/" target="_blank">IronOxide</a> 2012-08-29 20:41 <a href="http://www.cppblog.com/IronOxide/archive/2012/08/29/188667.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>