﻿<?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++博客-阿二的梦想船</title><link>http://www.cppblog.com/richbirdandy/</link><description /><language>zh-cn</language><lastBuildDate>Thu, 09 Apr 2026 12:38:23 GMT</lastBuildDate><pubDate>Thu, 09 Apr 2026 12:38:23 GMT</pubDate><ttl>60</ttl><item><title>redis如何删除过期数据</title><link>http://www.cppblog.com/richbirdandy/archive/2011/11/29/161184.html</link><dc:creator>阿二</dc:creator><author>阿二</author><pubDate>Tue, 29 Nov 2011 11:57:00 GMT</pubDate><guid>http://www.cppblog.com/richbirdandy/archive/2011/11/29/161184.html</guid><wfw:comment>http://www.cppblog.com/richbirdandy/comments/161184.html</wfw:comment><comments>http://www.cppblog.com/richbirdandy/archive/2011/11/29/161184.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/richbirdandy/comments/commentRss/161184.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/richbirdandy/services/trackbacks/161184.html</trackback:ping><description><![CDATA[<div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><span class="Apple-style-span" style="font-size: 14px; "><span style="font-family: 宋体; font-size: 12pt; ">随着</span><span style="font-size: 12pt; ">nosql</span><span style="font-family: 宋体; font-size: 12pt; ">风潮兴起，</span><span style="font-size: 12pt; ">redis</span><span style="font-family: 宋体; font-size: 12pt; ">作为当中一个耀眼的明星，也越来越多的被关注和使用，我在工作中也广泛的用到了</span><span style="font-size: 12pt; ">redis</span><span style="font-family: 宋体; font-size: 12pt; ">来充当</span><span style="font-size: 12pt; ">cache</span><span style="font-family: 宋体; font-size: 12pt; ">和</span><span style="font-size: 12pt; ">key-value DB</span><span style="font-family: 宋体; font-size: 12pt; ">，但当大家发现数据越来越多时</span><span style="font-family: 宋体; font-size: 12pt; ">，不禁有些担心，</span><span style="font-size: 12pt; ">redis</span><span style="font-family: 宋体; font-size: 12pt; ">能撑的住吗，虽然官方已经有漂亮的</span><span style="font-size: 12pt; ">benchmark</span><span style="font-family: 宋体; font-size: 12pt; ">，自己也可以做做压力测试，但是看看源码，也是确认问题最直接的办法之一。比如目前我们要确认的一个问题是，</span><span style="font-size: 12pt; ">redis</span><span style="font-family: 宋体; font-size: 12pt; ">是如何删除过期数据的？</span></span></div>  <p><span style="font-family: 宋体; font-size: 12pt; ">用一个可以</span><span style="font-size: 12pt; ">"find reference"</span><span style="font-family: 宋体; font-size: 12pt; ">的</span><span style="font-size: 12pt; ">IDE,</span><span style="font-family: 宋体; font-size: 12pt; ">沿着</span><span style="font-size: 12pt; ">setex(</span><span style="color: maroon; font-size: 12pt; ">Set the value and expiration of a key</span><span style="color: maroon; font-size: 12pt; ">)</span><span style="font-family: 宋体; font-size: 12pt; ">命令一窥究竟：</span></p>  <p style="text-autospace:none"><font class="Apple-style-span" color="#0000FF" size="4"></font></p><font class="Apple-style-span" color="#0000FF" size="4"><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;setexCommand(redisClient&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">c)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">argv[</span><span style="color: #000000; ">3</span><span style="color: #000000; ">]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;tryObjectEncoding(c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">argv[</span><span style="color: #000000; ">3</span><span style="color: #000000; ">]);<br />&nbsp;&nbsp;&nbsp;&nbsp;setGenericCommand(c,</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">argv[</span><span style="color: #000000; ">1</span><span style="color: #000000; ">],c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">argv[</span><span style="color: #000000; ">3</span><span style="color: #000000; ">],c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">argv[</span><span style="color: #000000; ">2</span><span style="color: #000000; ">]);<br />}</span></div></font>  <p><span style="color: black; font-size: 12pt; ">setGenericCommand</span><span style="font-family: 宋体; font-size: 12pt; ">是一个实现</span><span style="font-size: 12pt; ">set,setnx,setex</span><span style="font-family: 宋体; font-size: 12pt; ">的通用函数，参数设置不同而已。</span></p>  <p style="text-autospace:none"><font class="Apple-style-span" color="#0000FF" size="4"></font></p><font class="Apple-style-span" color="#0000FF" size="4"><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;setCommand(redisClient&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">c)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">argv[</span><span style="color: #000000; ">2</span><span style="color: #000000; ">]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;tryObjectEncoding(c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">argv[</span><span style="color: #000000; ">2</span><span style="color: #000000; ">]);<br />&nbsp;&nbsp;&nbsp;&nbsp;setGenericCommand(c,</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">argv[</span><span style="color: #000000; ">1</span><span style="color: #000000; ">],c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">argv[</span><span style="color: #000000; ">2</span><span style="color: #000000; ">],NULL);<br />}<br />&nbsp;<br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;setnxCommand(redisClient&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">c)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">argv[</span><span style="color: #000000; ">2</span><span style="color: #000000; ">]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;tryObjectEncoding(c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">argv[</span><span style="color: #000000; ">2</span><span style="color: #000000; ">]);<br />&nbsp;&nbsp;&nbsp;&nbsp;setGenericCommand(c,</span><span style="color: #000000; ">1</span><span style="color: #000000; ">,c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">argv[</span><span style="color: #000000; ">1</span><span style="color: #000000; ">],c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">argv[</span><span style="color: #000000; ">2</span><span style="color: #000000; ">],NULL);<br />}<br />&nbsp;<br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;setexCommand(redisClient&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">c)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">argv[</span><span style="color: #000000; ">3</span><span style="color: #000000; ">]&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;tryObjectEncoding(c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">argv[</span><span style="color: #000000; ">3</span><span style="color: #000000; ">]);<br />&nbsp;&nbsp;&nbsp;&nbsp;setGenericCommand(c,</span><span style="color: #000000; ">0</span><span style="color: #000000; ">,c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">argv[</span><span style="color: #000000; ">1</span><span style="color: #000000; ">],c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">argv[</span><span style="color: #000000; ">3</span><span style="color: #000000; ">],c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">argv[</span><span style="color: #000000; ">2</span><span style="color: #000000; ">]);<br />}</span></div></font>  <p><span style="font-family: 宋体; color: black; font-size: 12pt; ">再看</span><span style="color: black; font-size: 12pt; ">setGenericCommand</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">：<br /></span></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;setGenericCommand(redisClient&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">c,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;nx,&nbsp;robj&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">key,&nbsp;robj&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">val,&nbsp;robj&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">expire)&nbsp;{<br /></span><span style="color: #008080; ">&nbsp;2</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">long</span><span style="color: #000000; ">&nbsp;seconds&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;initialized&nbsp;to&nbsp;avoid&nbsp;an&nbsp;harmness&nbsp;warning&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;3</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;4</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(expire)&nbsp;{<br /></span><span style="color: #008080; ">&nbsp;5</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(getLongFromObjectOrReply(c,&nbsp;expire,&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">seconds,&nbsp;NULL)&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;REDIS_OK)<br /></span><span style="color: #008080; ">&nbsp;6</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">&nbsp;7</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(seconds&nbsp;</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)&nbsp;{<br /></span><span style="color: #008080; ">&nbsp;8</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addReplyError(c,</span><span style="color: #000000; ">"</span><span style="color: #000000; ">invalid&nbsp;expire&nbsp;time&nbsp;in&nbsp;SETEX</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">&nbsp;9</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">10</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">11</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">12</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">13</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(lookupKeyWrite(c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">db,key)&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;NULL&nbsp;</span><span style="color: #000000; ">&amp;&amp;</span><span style="color: #000000; ">&nbsp;nx)&nbsp;{<br /></span><span style="color: #008080; ">14</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addReply(c,shared.czero);<br /></span><span style="color: #008080; ">15</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">16</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">17</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;setKey(c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">db,key,val);<br /></span><span style="color: #008080; ">18</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;server.dirty</span><span style="color: #000000; ">++</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">19</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(expire)&nbsp;setExpire(c</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">db,key,time(NULL)</span><span style="color: #000000; ">+</span><span style="color: #000000; ">seconds);&nbsp;<br /></span><span style="color: #008080; ">20</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;addReply(c,&nbsp;nx&nbsp;</span><span style="color: #000000; ">?</span><span style="color: #000000; ">&nbsp;shared.cone&nbsp;:&nbsp;shared.ok);<br /></span><span style="color: #008080; ">21</span>&nbsp;<span style="color: #000000; ">}<br /></span><span style="color: #008080; ">22</span>&nbsp;</div>  <p><span style="font-size: 12pt; ">13</span><span style="font-family: 宋体; font-size: 12pt; ">行处理</span><span style="color: maroon; font-size: 12pt; ">"Set the value of a key, only if the key does not exist"</span><span style="font-family: 宋体; color: maroon; font-size: 12pt; ">的场景，</span><span style="font-size: 12pt; ">17</span><span style="font-family: 宋体; font-size: 12pt; ">行插入这个</span><span style="font-size: 12pt; ">key</span><span style="font-family: 宋体; font-size: 12pt; ">，</span><span style="font-size: 12pt; ">19</span><span style="font-family: 宋体; font-size: 12pt; ">行设置它的超时，注意时间戳已经被设置成了到期时间。这里要看一下</span><span style="color: black; font-size: 12pt; ">redisDb</span><span style="font-size: 12pt; ">(</span><span style="font-family: 宋体; font-size: 12pt; ">即</span><span style="color: black; font-size: 12pt; ">c</span><span style="font-size: 12pt; ">-&gt;<span style="color: black; font-size: 12pt; ">db</span></span><span style="color: black; font-size: 12pt; ">)</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">的定义：</span></p>  <p style="text-autospace:none"><font class="Apple-style-span" color="#0000FF" size="4"></font></p><font class="Apple-style-span" color="#0000FF" size="4"><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">typedef&nbsp;</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;redisDb&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;dict&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">dict;&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;The&nbsp;keyspace&nbsp;for&nbsp;this&nbsp;DB&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;dict&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">expires;&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;Timeout&nbsp;of&nbsp;keys&nbsp;with&nbsp;a&nbsp;timeout&nbsp;set&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;dict&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">blocking_keys;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Keys&nbsp;with&nbsp;clients&nbsp;waiting&nbsp;for&nbsp;data&nbsp;(BLPOP)&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;dict&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">io_keys;&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;Keys&nbsp;with&nbsp;clients&nbsp;waiting&nbsp;for&nbsp;VM&nbsp;I/O&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;dict&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">watched_keys;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;WATCHED&nbsp;keys&nbsp;for&nbsp;MULTI/EXEC&nbsp;CAS&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;id;<br />}&nbsp;redisDb;</span></div></font>  <p><span style="font-family: 宋体; font-size: 12pt; ">仅关注</span><span style="color: black; font-size: 12pt; ">dict</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">和</span><span style="color: black; font-size: 12pt; ">expires</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">，分别来存</span><span style="color: black; font-size: 12pt; ">key-value</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">和它的超时，也就是说如果一个</span><span style="color: black; font-size: 12pt; ">key-value</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">是有超时的，那么它会存在</span><span style="color: black; font-size: 12pt; ">dict</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">里，同时也存到</span><span style="color: black; font-size: 12pt; ">expires</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">里，类似这样的形式：</span><span style="color: black; font-size: 12pt; ">dict[key]:value,expires[key]:timeout.</span></p>  <p><span style="font-family: 宋体; font-size: 12pt; ">当然</span><span style="font-size: 12pt; ">key-value</span><span style="font-family: 宋体; font-size: 12pt; ">没有超时，</span><span style="font-size: 12pt; ">expires</span><span style="font-family: 宋体; font-size: 12pt; ">里就不存在这个</span><span style="font-size: 12pt; ">key</span><span style="font-family: 宋体; font-size: 12pt; ">。</span><span style="font-family: 宋体; font-size: 12pt; ">剩下</span><span style="color: black; font-size: 12pt; ">setKey</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">和</span><span style="color: black; font-size: 12pt; ">setExpire</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">两个函数无非是插数据到两个字典里，这里不再详述。</span></p>  <p><br /></p>  <p><span style="font-family: 宋体; color: black; font-size: 12pt; ">那么</span><span style="color: black; font-size: 12pt; ">redis</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">是如何删除过期</span><span style="color: black; font-size: 12pt; ">key</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">的呢。</span></p>  <p><span style="font-family: 宋体; color: black; font-size: 12pt; ">通过查看</span><span style="color: black; font-size: 12pt; ">dbDelete</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">的调用者，</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">首先注意到这一个函数，是用来删除过期</span><span style="color: black; font-size: 12pt; ">key</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">的。</span></p>  <p style="margin-left:21.25pt;text-indent:-21.25pt;text-autospace:none"><font class="Apple-style-span" size="4"><span class="Apple-style-span" style="font-size: 16px;"></span></font></p><font class="Apple-style-span" size="4"><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;expireIfNeeded(redisDb&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">db,&nbsp;robj&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">key)&nbsp;{<br /></span><span style="color: #008080; ">&nbsp;2</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;time_t&nbsp;when&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;getExpire(db,key);<br /></span><span style="color: #008080; ">&nbsp;3</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;4</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(when&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;No&nbsp;expire&nbsp;for&nbsp;this&nbsp;key&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;5</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;6</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Don't&nbsp;expire&nbsp;anything&nbsp;while&nbsp;loading.&nbsp;It&nbsp;will&nbsp;be&nbsp;done&nbsp;later.&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;7</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(server.loading)&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">&nbsp;8</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;9</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;If&nbsp;we&nbsp;are&nbsp;running&nbsp;in&nbsp;the&nbsp;context&nbsp;of&nbsp;a&nbsp;slave,&nbsp;return&nbsp;ASAP:<br /></span><span style="color: #008080; ">10</span>&nbsp;<span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;the&nbsp;slave&nbsp;key&nbsp;expiration&nbsp;is&nbsp;controlled&nbsp;by&nbsp;the&nbsp;master&nbsp;that&nbsp;will<br /></span><span style="color: #008080; ">11</span>&nbsp;<span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;send&nbsp;us&nbsp;synthesized&nbsp;DEL&nbsp;operations&nbsp;for&nbsp;expired&nbsp;keys.<br /></span><span style="color: #008080; ">12</span>&nbsp;<span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<br /></span><span style="color: #008080; ">13</span>&nbsp;<span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Still&nbsp;we&nbsp;try&nbsp;to&nbsp;return&nbsp;the&nbsp;right&nbsp;information&nbsp;to&nbsp;the&nbsp;caller,&nbsp;<br /></span><span style="color: #008080; ">14</span>&nbsp;<span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;that&nbsp;is,&nbsp;0&nbsp;if&nbsp;we&nbsp;think&nbsp;the&nbsp;key&nbsp;should&nbsp;be&nbsp;still&nbsp;valid,&nbsp;1&nbsp;if<br /></span><span style="color: #008080; ">15</span>&nbsp;<span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;we&nbsp;think&nbsp;the&nbsp;key&nbsp;is&nbsp;expired&nbsp;at&nbsp;this&nbsp;time.&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">16</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(server.masterhost&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;NULL)&nbsp;{<br /></span><span style="color: #008080; ">17</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;time(NULL)&nbsp;</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;when;<br /></span><span style="color: #008080; ">18</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">19</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">20</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Return&nbsp;when&nbsp;this&nbsp;key&nbsp;has&nbsp;not&nbsp;expired&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">21</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(time(NULL)&nbsp;</span><span style="color: #000000; ">&lt;=</span><span style="color: #000000; ">&nbsp;when)&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">22</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">23</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Delete&nbsp;the&nbsp;key&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">24</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;server.stat_expiredkeys</span><span style="color: #000000; ">++</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">25</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;propagateExpire(db,key);<br /></span><span style="color: #008080; ">26</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;dbDelete(db,key);<br /></span><span style="color: #008080; ">27</span>&nbsp;<span style="color: #000000; ">}<br /></span><span style="color: #008080; ">28</span>&nbsp;</div></font>  <p><span style="font-size: 12pt; ">ifNeed</span><span style="font-family: 宋体; font-size: 12pt; ">表示能删则删，所以</span><span style="font-size: 12pt; ">4</span><span style="font-family: 宋体; font-size: 12pt; ">行没有设置超时不删，</span><span style="font-size: 12pt; ">7</span><span style="font-family: 宋体; font-size: 12pt; ">行在</span><span style="font-size: 12pt; ">"loading"</span><span style="font-family: 宋体; font-size: 12pt; ">时不删，</span><span style="font-size: 12pt; ">16</span><span style="font-family: 宋体; font-size: 12pt; ">行非主库不删，</span><span style="font-size: 12pt; ">21</span><span style="font-family: 宋体; font-size: 12pt; ">行未到期不删。</span><span style="font-size: 12pt; ">25</span><span style="font-family: 宋体; font-size: 12pt; ">行同步从库和文件。</span></p>  <p><span style="font-family: 宋体; color: black; font-size: 12pt; ">再看看哪些函数调用了</span><span style="color: black; font-size: 12pt; ">expireIfNeeded</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">，有</span><span style="color: black; font-size: 12pt; ">lookupKeyRead</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">，</span><span style="color: black; font-size: 12pt; ">lookupKeyWrite</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">，</span><span style="color: black; font-size: 12pt; ">dbRandomKey</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">，</span><span style="color: black; font-size: 12pt; ">existsCommand</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">，</span><span style="color: black; font-size: 12pt; ">keysCommand</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">。通过这些函数命名可以看出，只要访问了某一个</span><span style="color: black; font-size: 12pt; ">key</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">，顺带做的事情就是尝试查看过期并删除，这就保证了用户不可能访问到过期的</span><span style="color: black; font-size: 12pt; ">key</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">。但是如果有大量的</span><span style="color: black; font-size: 12pt; ">key</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">过期，并且没有被访问到，那么就浪费了许多内存。</span><span style="color: black; font-size: 12pt; ">Redis</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">是如何处理这个问题的呢。</span></p>  <p><br /></p>  <p><span style="color: black; font-size: 12pt; ">dbDelete</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">的调用者里还发现这样一个函数：<br /></span></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Try&nbsp;to&nbsp;expire&nbsp;a&nbsp;few&nbsp;timed&nbsp;out&nbsp;keys.&nbsp;The&nbsp;algorithm&nbsp;used&nbsp;is&nbsp;adaptive&nbsp;and<br /></span><span style="color: #008080; ">&nbsp;2</span>&nbsp;<span style="color: #008000; ">&nbsp;*&nbsp;will&nbsp;use&nbsp;few&nbsp;CPU&nbsp;cycles&nbsp;if&nbsp;there&nbsp;are&nbsp;few&nbsp;expiring&nbsp;keys,&nbsp;otherwise<br /></span><span style="color: #008080; ">&nbsp;3</span>&nbsp;<span style="color: #008000; ">&nbsp;*&nbsp;it&nbsp;will&nbsp;get&nbsp;more&nbsp;aggressive&nbsp;to&nbsp;avoid&nbsp;that&nbsp;too&nbsp;much&nbsp;memory&nbsp;is&nbsp;used&nbsp;by<br /></span><span style="color: #008080; ">&nbsp;4</span>&nbsp;<span style="color: #008000; ">&nbsp;*&nbsp;keys&nbsp;that&nbsp;can&nbsp;be&nbsp;removed&nbsp;from&nbsp;the&nbsp;keyspace.&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;5</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;activeExpireCycle(</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">)&nbsp;{<br /></span><span style="color: #008080; ">&nbsp;6</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;j;<br /></span><span style="color: #008080; ">&nbsp;7</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;8</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;(j&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&nbsp;j&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;server.dbnum;&nbsp;j</span><span style="color: #000000; ">++</span><span style="color: #000000; ">)&nbsp;{<br /></span><span style="color: #008080; ">&nbsp;9</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;expired;<br /></span><span style="color: #008080; ">10</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redisDb&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">db&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;server.db</span><span style="color: #000000; ">+</span><span style="color: #000000; ">j;<br /></span><span style="color: #008080; ">11</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">12</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;Continue&nbsp;to&nbsp;expire&nbsp;if&nbsp;at&nbsp;the&nbsp;end&nbsp;of&nbsp;the&nbsp;cycle&nbsp;more&nbsp;than&nbsp;25%<br /></span><span style="color: #008080; ">13</span>&nbsp;<span style="color: #008000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;of&nbsp;the&nbsp;keys&nbsp;were&nbsp;expired.&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">14</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">do</span><span style="color: #000000; ">&nbsp;{<br /></span><span style="color: #008080; ">15</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">long</span><span style="color: #000000; ">&nbsp;num&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;dictSize(db</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">expires);<br /></span><span style="color: #008080; ">16</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time_t&nbsp;now&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;time(NULL);<br /></span><span style="color: #008080; ">17</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">18</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;expired&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">19</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(num&nbsp;</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;REDIS_EXPIRELOOKUPS_PER_CRON)<br /></span><span style="color: #008080; ">20</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;num&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;REDIS_EXPIRELOOKUPS_PER_CRON;<br /></span><span style="color: #008080; ">21</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">&nbsp;(num</span><span style="color: #000000; ">--</span><span style="color: #000000; ">)&nbsp;{<br /></span><span style="color: #008080; ">22</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dictEntry&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">de;<br /></span><span style="color: #008080; ">23</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time_t&nbsp;t;<br /></span><span style="color: #008080; ">24</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">25</span>&nbsp;<span style="color: #000000; ">&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; ">&nbsp;((de&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;dictGetRandomKey(db</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">expires))&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;NULL)&nbsp;</span><span style="color: #0000FF; ">break</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">26</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;(time_t)&nbsp;dictGetEntryVal(de);<br /></span><span style="color: #008080; ">27</span>&nbsp;<span style="color: #000000; ">&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; ">&nbsp;(now&nbsp;</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;t)&nbsp;{<br /></span><span style="color: #008080; ">28</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sds&nbsp;key&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;dictGetEntryKey(de);<br /></span><span style="color: #008080; ">29</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;robj&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">keyobj&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;createStringObject(key,sdslen(key));<br /></span><span style="color: #008080; ">30</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">31</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;propagateExpire(db,keyobj);<br /></span><span style="color: #008080; ">32</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dbDelete(db,keyobj);<br /></span><span style="color: #008080; ">33</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;decrRefCount(keyobj);<br /></span><span style="color: #008080; ">34</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;expired</span><span style="color: #000000; ">++</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">35</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;server.stat_expiredkeys</span><span style="color: #000000; ">++</span><span style="color: #000000; ">;<br /></span><span style="color: #008080; ">36</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">37</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">38</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">&nbsp;(expired&nbsp;</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;REDIS_EXPIRELOOKUPS_PER_CRON</span><span style="color: #000000; ">/</span><span style="color: #000000; ">4</span><span style="color: #000000; ">);<br /></span><span style="color: #008080; ">39</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;}<br /></span><span style="color: #008080; ">40</span>&nbsp;<span style="color: #000000; ">}<br /></span><span style="color: #008080; ">41</span>&nbsp;</div>  <p><span style="font-family: 宋体; font-size: 12pt; ">这个函数的意图已经有说明：</span><span style="font-family: 宋体; font-size: 12pt; ">删一点点过期</span><span style="font-size: 12pt; ">key</span><span style="font-family: 宋体; font-size: 12pt; ">，如果过期</span><span style="font-size: 12pt; ">key</span><span style="font-family: 宋体; font-size: 12pt; ">较少，那也只用一点点</span><span style="font-size: 12pt; ">cpu</span><span style="font-family: 宋体; font-size: 12pt; ">。</span><span style="font-size: 12pt; ">25</span><span style="font-family: 宋体; font-size: 12pt; ">行随机取一个</span><span style="font-size: 12pt; ">key</span><span style="font-family: 宋体; font-size: 12pt; ">，</span><span style="font-size: 12pt; ">38</span><span style="font-family: 宋体; font-size: 12pt; ">行删</span><span style="font-size: 12pt; ">key</span><span style="font-family: 宋体; font-size: 12pt; ">成功的概率较低就退出。这个函数被放在一个</span><span style="font-size: 12pt; ">cron</span><span style="font-family: 宋体; font-size: 12pt; ">里，每毫秒被调用一次。这个算法保证每次会删除一定比例的</span><span style="font-size: 12pt; ">key</span><span style="font-family: 宋体; font-size: 12pt; ">，但是如果</span><span style="font-size: 12pt; ">key</span><span style="font-family: 宋体; font-size: 12pt; ">总量很大，而这个比例控制的太大，就需要更多次的循环，浪费</span><span style="font-size: 12pt; ">cpu</span><span style="font-family: 宋体; font-size: 12pt; ">，控制的太小，过期的</span><span style="font-size: 12pt; ">key</span><span style="font-family: 宋体; font-size: 12pt; ">就会变多，浪费内存&#8212;&#8212;这就是时空权衡了。</span></p>  <p>&nbsp;</p>  <p><span style="font-family: 宋体; color: black; font-size: 12pt; ">最后在</span><span style="color: black; font-size: 12pt; ">dbDelete</span><span style="font-family: 宋体; color: black; font-size: 12pt; ">的调用者里还发现这样一个函数：</span></p>  <p style="text-autospace:none"><font class="Apple-style-span" color="#008000" size="4"><span class="Apple-style-span" style="font-size: 16px;"></span></font></p><font class="Apple-style-span" color="#008000" size="4"><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<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; ">&nbsp;This&nbsp;function&nbsp;gets&nbsp;called&nbsp;when&nbsp;'maxmemory'&nbsp;is&nbsp;set&nbsp;on&nbsp;the&nbsp;config&nbsp;file&nbsp;to&nbsp;limit<br />&nbsp;*&nbsp;the&nbsp;max&nbsp;memory&nbsp;used&nbsp;by&nbsp;the&nbsp;server,&nbsp;and&nbsp;we&nbsp;are&nbsp;out&nbsp;of&nbsp;memory.<br />&nbsp;*&nbsp;This&nbsp;function&nbsp;will&nbsp;try&nbsp;to,&nbsp;in&nbsp;order:<br />&nbsp;*<br />&nbsp;*&nbsp;-&nbsp;Free&nbsp;objects&nbsp;from&nbsp;the&nbsp;free&nbsp;list<br />&nbsp;*&nbsp;-&nbsp;Try&nbsp;to&nbsp;remove&nbsp;keys&nbsp;with&nbsp;an&nbsp;EXPIRE&nbsp;set<br />&nbsp;*<br />&nbsp;*&nbsp;It&nbsp;is&nbsp;not&nbsp;possible&nbsp;to&nbsp;free&nbsp;enough&nbsp;memory&nbsp;to&nbsp;reach&nbsp;used-memory&nbsp;&lt;&nbsp;maxmemory<br />&nbsp;*&nbsp;the&nbsp;server&nbsp;will&nbsp;start&nbsp;refusing&nbsp;commands&nbsp;that&nbsp;will&nbsp;enlarge&nbsp;even&nbsp;more&nbsp;the<br />&nbsp;*&nbsp;memory&nbsp;usage.<br />&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;freeMemoryIfNeeded(</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">)</span></div></font>  <p><span style="font-family: 宋体; font-size: 12pt; ">这个函数太长就不再详述了，注释部分说明只有在配置文件中设置了最大内存时候才会调用这个函数，而设置这个参数的意义是，你把</span><span style="font-size: 12pt; ">redis</span><span style="font-family: 宋体; font-size: 12pt; ">当做一个内存</span><span style="font-size: 12pt; ">cache</span><span style="font-family: 宋体; font-size: 12pt; ">而不是</span><span style="font-size: 12pt; ">key-value</span><span style="font-family: 宋体; font-size: 12pt; ">数据库。</span></p>  <p><br /></p>  <p><span style="font-family: 宋体; font-size: 12pt; ">以上</span><span style="font-size: 12pt; ">3</span><span style="font-family: 宋体; font-size: 12pt; ">种删除过期</span><span style="font-size: 12pt; ">key</span><span style="font-family: 宋体; font-size: 12pt; ">的途径，第二种定期删除一定比例的</span><span style="font-size: 12pt; ">key</span><span style="font-family: 宋体; font-size: 12pt; ">是主要的删除途径，第一种&#8220;读时删除&#8221;保证过期</span><span style="font-size: 12pt; ">key</span><span style="font-family: 宋体; font-size: 12pt; ">不会被访问到，第三种是一个当内存超出设定时的暴力手段。由此也能看出</span><span style="font-size: 12pt; ">redis</span><span style="font-family: 宋体; font-size: 12pt; ">设计的巧妙之处，</span></p></div><img src ="http://www.cppblog.com/richbirdandy/aggbug/161184.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/richbirdandy/" target="_blank">阿二</a> 2011-11-29 19:57 <a href="http://www.cppblog.com/richbirdandy/archive/2011/11/29/161184.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Poco::TCPServer框架解析</title><link>http://www.cppblog.com/richbirdandy/archive/2010/09/10/123994.html</link><dc:creator>阿二</dc:creator><author>阿二</author><pubDate>Thu, 09 Sep 2010 17:05:00 GMT</pubDate><guid>http://www.cppblog.com/richbirdandy/archive/2010/09/10/123994.html</guid><wfw:comment>http://www.cppblog.com/richbirdandy/comments/123994.html</wfw:comment><comments>http://www.cppblog.com/richbirdandy/archive/2010/09/10/123994.html#Feedback</comments><slash:comments>13</slash:comments><wfw:commentRss>http://www.cppblog.com/richbirdandy/comments/commentRss/123994.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/richbirdandy/services/trackbacks/123994.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: POCO C++ Libraries提供一套 C++ 的类库用以开发基于网络的可移植的应用程序，功能涉及线程、文件、流，网络协议包括：HTTP、FTP、SMTP 等，还提供 XML 的解析和 SQL 数据库的访问接口。不仅给我的工作带来极大的便利，而且设计巧妙，代码易读，注释丰富，也是非常好的学习材料。&nbsp;&nbsp;<a href='http://www.cppblog.com/richbirdandy/archive/2010/09/10/123994.html'>阅读全文</a><img src ="http://www.cppblog.com/richbirdandy/aggbug/123994.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/richbirdandy/" target="_blank">阿二</a> 2010-09-10 01:05 <a href="http://www.cppblog.com/richbirdandy/archive/2010/09/10/123994.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从海量数据中找出中位数</title><link>http://www.cppblog.com/richbirdandy/archive/2008/09/09/61426.html</link><dc:creator>阿二</dc:creator><author>阿二</author><pubDate>Tue, 09 Sep 2008 14:49:00 GMT</pubDate><guid>http://www.cppblog.com/richbirdandy/archive/2008/09/09/61426.html</guid><wfw:comment>http://www.cppblog.com/richbirdandy/comments/61426.html</wfw:comment><comments>http://www.cppblog.com/richbirdandy/archive/2008/09/09/61426.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/richbirdandy/comments/commentRss/61426.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/richbirdandy/services/trackbacks/61426.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">题目和基本思路都来源网上，本人加以整理。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">题目：在一个文件中有 10G 个整数，乱序排列，要求找出中位数。内存限制为 2G。只写出思路即可（内存限制为 2G的意思就是，可以使用2G的空间来运行程序，而不考虑这台机器上的其他软件的占用内存）。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">关于中位数：数据排序后，位置在最中间的数值。即将数据分成两部分，一部分大于该数值，一部分小于该数值。中位数的位置：当样本数为奇数时，中位数=(N+1)/2 ; 当样本数为偶数时，中位数为N/2与1+N/2的均值（那么10G个数的中位数，就第5G大的数与第5G+1大的数的均值了）。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">分析：明显是一道工程性很强的题目，和一般的查找中位数的题目有几点不同。<br>1. 原数据不能读进内存，不然可以用快速选择，如果数的范围合适的话还可以考虑桶排序或者计数排序，但这里假设是32位整数，仍有4G种取值，需要一个16G大小的数组来计数。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">2. 若看成从N个数中找出第K大的数，如果K个数可以读进内存，可以利用最小或最大堆，但这里K=N/2,有5G个数，仍然不能读进内存。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">3. 接上，对于N个数和K个数都不能一次读进内存的情况，《编程之美》里给出一个方案：设k&lt;K,且k个数可以完全读进内存，那么先构建k个数的堆，先找出第0到k大的数，再扫描一遍数组找出第k+1到2k的数，再扫描直到找出第K个数。虽然每次时间大约是nlog(k)，但需要扫描ceil(K/k)次，这里要扫描5次。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">解法：首先假设是32位无符号整数。<br>1. 读一遍10G个整数，把整数映射到256M个区段中，用一个64位无符号整数给每个相应区段记数。<br>说明：整数范围是0 - 2^32 - 1，一共有4G种取值，映射到256M个区段，则每个区段有16（4G/256M = 16）种值，每16个值算一段， 0～15是第1段，16～31是第2段，&#8230;&#8230;2^32-16 ～2^32-1是第256M段。一个64位无符号整数最大值是0～8G-1，这里先不考虑溢出的情况。总共占用内存256M&#215;8B=2GB。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">2. 从前到后对每一段的计数累加，当累加的和超过5G时停止，找出这个区段（即累加停止时达到的区段，也是中位数所在的区段）的数值范围，设为[a，a+15]，同时记录累加到前一个区段的总数，设为m。然后，释放除这个区段占用的内存。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">3. 再读一遍10G个整数，把在[a，a+15]内的每个值计数，即有16个计数。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">4. 对新的计数依次累加，每次的和设为n，当m+n的值超过5G时停止，此时的这个计数所对应的数就是中位数。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">总结：<br>1.以上方法只要读两遍整数，对每个整数也只是常数时间的操作，总体来说是线性时间。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">2. 考虑其他情况。<br>若是有符号的整数，只需改变映射即可。若是64为整数，则增加每个区段的范围，那么在第二次读数时，要考虑更多的计数。若过某个计数溢出，那么可认定所在的区段或代表整数为所求，这里只需做好相应的处理。噢，忘了还要找第5G+1大的数了，相信有了以上的成果，找到这个数也不难了吧。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">3. 时空权衡。<br>花费256个区段也许只是恰好配合2GB的内存（其实也不是，呵呵）。可以增大区段范围，减少区段数目，节省一些内存，虽然增加第二部分的对单个数值的计数，但第一部分对每个区段的计数加快了（总体改变？？待测）。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体">4. 映射时尽量用位操作，由于每个区段的起点都是2的整数幂，映射起来也很方便。<br></p>
<img src ="http://www.cppblog.com/richbirdandy/aggbug/61426.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/richbirdandy/" target="_blank">阿二</a> 2008-09-09 22:49 <a href="http://www.cppblog.com/richbirdandy/archive/2008/09/09/61426.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于boost::multi_array的矩阵相乘</title><link>http://www.cppblog.com/richbirdandy/archive/2008/09/09/61408.html</link><dc:creator>阿二</dc:creator><author>阿二</author><pubDate>Tue, 09 Sep 2008 12:21:00 GMT</pubDate><guid>http://www.cppblog.com/richbirdandy/archive/2008/09/09/61408.html</guid><wfw:comment>http://www.cppblog.com/richbirdandy/comments/61408.html</wfw:comment><comments>http://www.cppblog.com/richbirdandy/archive/2008/09/09/61408.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/richbirdandy/comments/commentRss/61408.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/richbirdandy/services/trackbacks/61408.html</trackback:ping><description><![CDATA[<span style="FONT-SIZE: 12pt">博客第一篇，还望大家多多指点。<br><br>看了半天的boost::multi_array文档，才发现可以用shape()[]这个的东西，来取某一维的长度 <br><br>而关于视图部分，小弟看的一知半解， <br>比如，怎么样把一个4&#215;4的矩阵分成4个2&#215;2的矩阵呢 <br>虽然可以用别的途径解决，但还是想看下multi_array的视图操作 <br><br>本来要实现下Strassen算法的， <br>下面是普通的矩阵乘法。<br><br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">boost/multi_array.hpp</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;std;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>typedef&nbsp;boost::multi_array</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;matrix;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>matrix&nbsp;matrix_multiply(matrix</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;a,matrix</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;b)<br><img id=Codehighlighter1_164_498_Open_Image onclick="this.style.display='none'; Codehighlighter1_164_498_Open_Text.style.display='none'; Codehighlighter1_164_498_Closed_Image.style.display='inline'; Codehighlighter1_164_498_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_164_498_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_164_498_Closed_Text.style.display='none'; Codehighlighter1_164_498_Open_Image.style.display='inline'; Codehighlighter1_164_498_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_164_498_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_164_498_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;matrix::index&nbsp;row</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">a.shape()[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">];<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;matrix::index&nbsp;col</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">b.shape()[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">];<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;matrix&nbsp;c(boost::extents[row][col]);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(matrix::index&nbsp;i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">a.shape()[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">];&nbsp;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">i)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(matrix::index&nbsp;j</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;j</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">b.shape()[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">];&nbsp;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">j)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(matrix::index&nbsp;k</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;k</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">a.shape()[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">];&nbsp;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">k)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c[i][j]</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">a[i][k]</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">b[k][j];<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;c;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;print(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;matrix</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;m)<br><img id=Codehighlighter1_529_686_Open_Image onclick="this.style.display='none'; Codehighlighter1_529_686_Open_Text.style.display='none'; Codehighlighter1_529_686_Closed_Image.style.display='inline'; Codehighlighter1_529_686_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_529_686_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_529_686_Closed_Text.style.display='none'; Codehighlighter1_529_686_Open_Image.style.display='inline'; Codehighlighter1_529_686_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_529_686_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_529_686_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(matrix::index&nbsp;i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">m.shape()[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">];&nbsp;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">endl,</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">i)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(matrix::index&nbsp;j</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;j</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">m.shape()[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">];&nbsp;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">j)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">m[i][j]</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img id=Codehighlighter1_700_1226_Open_Image onclick="this.style.display='none'; Codehighlighter1_700_1226_Open_Text.style.display='none'; Codehighlighter1_700_1226_Closed_Image.style.display='inline'; Codehighlighter1_700_1226_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_700_1226_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_700_1226_Closed_Text.style.display='none'; Codehighlighter1_700_1226_Open_Image.style.display='inline'; Codehighlighter1_700_1226_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main()&nbsp;</span><span id=Codehighlighter1_700_1226_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_700_1226_Open_Text><span style="COLOR: #000000">{&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img id=Codehighlighter1_725_774_Open_Image onclick="this.style.display='none'; Codehighlighter1_725_774_Open_Text.style.display='none'; Codehighlighter1_725_774_Closed_Image.style.display='inline'; Codehighlighter1_725_774_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_725_774_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_725_774_Closed_Text.style.display='none'; Codehighlighter1_725_774_Open_Image.style.display='inline'; Codehighlighter1_725_774_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;values[]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span id=Codehighlighter1_725_774_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_725_774_Open_Text><span style="COLOR: #000000">{&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000">;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;values_size&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;matrix&nbsp;A(boost::extents[</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">][</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">]);&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;matrix&nbsp;B(boost::extents[</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">][</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">]);&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;A.assign(values,values&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;values_size);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;B.assign(values,values&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;values_size);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">matrix&nbsp;A</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">endl;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(A);&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">endl;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">endl;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">matrix&nbsp;B</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">endl;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(B);&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">endl;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">endl;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">matrix&nbsp;C</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">endl;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;print(matrix_multiply(A,B));<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">endl;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">&nbsp;</span></div>
</span>
<img src ="http://www.cppblog.com/richbirdandy/aggbug/61408.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/richbirdandy/" target="_blank">阿二</a> 2008-09-09 20:21 <a href="http://www.cppblog.com/richbirdandy/archive/2008/09/09/61408.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>