<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[Snooda]]></title> 
<link>http://www.snooda.com/index</link> 
<description><![CDATA[Snooda's Blog]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[Snooda]]></copyright>
<item>
<link>http://www.snooda.com/read/</link>
<title><![CDATA[一个C++的坑-unorderedmap之顺序问题]]></title> 
<author>snooda &lt;admin@snooda.com&gt;</author>
<category><![CDATA[默认分类]]></category>
<pubDate>Wed, 21 Jul 2021 12:34:14 +0000</pubDate> 
<guid>http://www.snooda.com/read/</guid> 
<description>
<![CDATA[ 
	&nbsp;&nbsp;&nbsp;&nbsp;最近遇到一个bug，定位了非常久，感觉有必要分享出来。。。避免后人掉坑。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;前段时间发现了一个raft主从间内存不一致的场景，导致切主后数据异常。。当时费了很大的力气排除掉其他模块逻辑问题。后来问题缩小到raft state machine里。由于raft高度依赖state machine幂等性（重启、切主都会导致状态机重做，如果逻辑不是严格幂等，就会出现状态不一致问题），一般要求日志中必须记录绝对操作，尽量不记相对操作。但有一个round-robin分配资源的场景，还是依赖了一下资源节点的排序问题。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;最早是使用std::map来存，使用迭代器遍历。由于map本身是有序的，所以三副本之间是一致的。<br/>&nbsp;&nbsp;&nbsp;&nbsp;后来有不熟悉的同学为了优化map的lg(n)性能，改用了基于哈希的unorderedmap，那么问题就来了。逻辑上map和unorderedmap都支持迭代器遍历。所以只修改数据类型，不修改逻辑是可以兼容的。简单执行也没有问题。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;已知unorderedmap肯定不能保证遍历结果的有序，但是目前场景也并不要求结果有序，只要每次遍历结果顺序不变就行，那么unorderedmap能否保证遍历顺序幂等性？目前看答案是“不能”。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;简单来想，hash表就是对元素做哈希，然后选定桶，对于桶内的元素就串到list上。那么只要按同样的顺序插入，似乎也是可以保序的。因为unorderedmap内部存在自动rehash过程。。一旦rehash，节点的遍历顺序就会变化。。。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;所以一定要重视“unordered”关键字。。。任何情况下unorderedmap都不保证任何顺序。。。。<br/>Tags - <a href="http://www.snooda.com/tags/unorderedmap/" rel="tag">unorderedmap</a> , <a href="http://www.snooda.com/tags/c%252B%252B/" rel="tag">c++</a>
]]>
</description>
</item><item>
<link>http://www.snooda.com/read/#blogcomment</link>
<title><![CDATA[[评论] 一个C++的坑-unorderedmap之顺序问题]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://www.snooda.com/read/#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>