<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet href='http://feed.luliban.com/styles/podcast2.xsl' type='text/xsl' ?><!--这是一个由Feedsy提供技术支持的Feed，为了提高读者阅读的体验，以及满足用户美化自己Feed的需要，我们设计了多种精美的Feed模板，提供给大家选择，所有最终呈现出来的样式，皆由用户自愿选择使用，未经许可，任何团体和个人，请不要擅自修改样式或者盗用，这是对于用户选择权的尊重。--><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:fs="http://www.feedsky.com/namespace/feed" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><atom:link href="http://feed.luliban.com" type="application/rss+xml" ref="self"></atom:link><fs:self_link href="http://feed.feedsky.com/luliban" type="application/rss+xml"></fs:self_link><lastBuildDate>Sun, 06 Jul 2008 11:31:06 GMT</lastBuildDate><title>陆离斑「博」</title><description>wyt on linux, python, nba ...</description><image><url>http://www.feedsky.com/feed/luliban/sc/gif</url><title>陆离斑「博」</title><link>http://luliban.com/blog/</link></image><link atom:type="text/html">http://luliban.com/blog/</link><id xmlns="http://www.w3.org/2005/Atom">tag:blogger.com,1999:blog-7286295415331143255</id><link xmlns="http://www.w3.org/2005/Atom" rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/7286295415331143255/posts/default?start-index=26&amp;max-results=25"></link><link xmlns="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7286295415331143255/posts/default"></link><link xmlns="http://www.w3.org/2005/Atom" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://luliban.com/blog/feeds/atom.xml"></link><author xmlns="http://www.w3.org/2005/Atom"><name>wyt</name><uri>http://www.blogger.com/profile/04947921907676762514</uri><email>noreply@blogger.com</email></author><generator xmlns="http://www.w3.org/2005/Atom" version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>108</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><pubDate>Sun, 06 Jul 2008 11:31:06 GMT</pubDate><managingEditor>wyt</managingEditor><dc:date>2008-07-06T11:31:06Z</dc:date><item><title>有备无患：pinyin-urlify - 根据汉字自动生成拼音 URL</title><link atom:title="有备无患：pinyin-urlify - 根据汉字自动生成拼音 URL" atom:type="text/html">http://item.feedsky.com/~feedsky/luliban/~6996753/89487017/4034731/1/item.html</link><id xmlns="http://www.w3.org/2005/Atom">tag:blogger.com,1999:blog-7286295415331143255.post-1320338599645208961</id><content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;p&gt;根据文章标题中的英语单词自动生成文章的 URL 是一个很好的体验，比如标题为“&lt;a rel=&quot;nofollow&quot; title=&quot;Girl's death sparks riot in China&quot; href=&quot;http://edition.cnn.com/2008/WORLD/asiapcf/06/30/china.riots/index.html&quot; id=&quot;hjgz&quot;&gt;Girl's death sparks riot in China&lt;/a&gt;”，会被转换成“girls-death-sparks-riot-china”这样与之对应的 URL。这样既可获得 &lt;a title=&quot;Cool URI&quot; rel=&quot;nofollow&quot; href=&quot;http://www.w3.org/Provider/Style/URI&quot; id=&quot;zl1v&quot;&gt;Cool URIs&lt;/a&gt;，又便于用户记忆，同时也有利于 &lt;a rel=&quot;nofollow&quot; title=&quot;SEO&quot; href=&quot;http://www.chinamyhosting.com/seoblog/2006/08/19/whats-seo/&quot; id=&quot;s92m&quot;&gt;SEO&lt;/a&gt;，&lt;a rel=&quot;nofollow&quot; title=&quot;Blogger&quot; href=&quot;http://www.blogger.com&quot; id=&quot;ied5&quot;&gt;Blogger&lt;/a&gt; 和 &lt;a rel=&quot;nofollow&quot; title=&quot;Wordpress&quot; href=&quot;http://www.wordpress.com/&quot; id=&quot;w-.u&quot;&gt;Wordpress&lt;/a&gt; 也都支持类似体验。而中文的文章标题，也可以先将其中的汉字转化为拼音后再组成相应的 URL，比如标题为“&lt;a rel=&quot;nofollow&quot; title=&quot;俯卧撑&quot; href=&quot;http://www.google.com/search?q=俯卧撑+瓮安&quot;&gt;俯卧撑&lt;/a&gt;”，可以被转换成“fu-wo-cheng”。&lt;br /&gt;
&lt;br /&gt;
&lt;a title=&quot;pinyin-urlify&quot; href=&quot;http://code.google.com/p/pinyin-urlify/&quot; id=&quot;hof4&quot;&gt;pinyin-urlify&lt;/a&gt; 是我这几天写的能根据汉字自动生成拼音 URL 的 Python 脚本。它可以将汉字映射成有英语字母组成的拼音，和多种西方语言的字母（拉丁语、希腊语、俄语等）映射成相近的英语字母。要说明的是，汉字-拼音的映射表是从 &lt;a title=&quot;pyzh 项目&quot; href=&quot;http://code.google.com/p/pyzh/&quot; id=&quot;l_q.&quot;&gt;pyzh 项目&lt;/a&gt;中获得，而其他西方语言的映射表则是从 &lt;a title=&quot;Django 项目&quot; href=&quot;http://www.djangoproject.com/&quot; id=&quot;z5sj&quot;&gt;Django 项目&lt;/a&gt;中获得，&lt;b id=&quot;mrrn&quot;&gt;特表感谢&lt;/b&gt;。&lt;br /&gt;
&lt;br /&gt;
pinyin-urlify 支持自定义停用词列表（stop words）和保留词列表（reserved words）。停用词列表中的单词都会被过滤，不会出现在生成的 URL 中。生成的 URL 如果和保留词列表中的某一个单词匹配，则会被替换成默认的 URL 字符串。pinyin-urlify 可以指定 URL 的最大长度。不过，如果遇到有较多汉字组成的文章标题的话，实际生成的 URL 可能会比限定的最大长度小一些。我希望能在以后修正这一点。&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;使用示例&lt;/h4&gt;
&lt;pre class=&quot;codes&quot;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; from urlify import urlify
&amp;gt;&amp;gt;&amp;gt; urlify(u'三个俯卧撑引发的血案', default='blog_post',
...        max_length=50, stop_words=[u'is', u'a', u'an'],
...        reserved_words=[u'new', u'edit'])
u'san-ge-fu-wo-cheng-yin-fa-de-xue'&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
欢迎大家用 svn 检出 pinyin-urlify 的副本来使用。欢迎任何意见或建议 :-)&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;$ svn checkout http://pinyin-urlify.googlecode.com/svn/trunk/ pinyin-urlify&lt;/code&gt;&lt;/pre&gt;</content><author xmlns="http://www.w3.org/2005/Atom"><name>wyt</name><uri>http://www.blogger.com/profile/04947921907676762514</uri><email>noreply@blogger.com</email></author><content:encoded>&lt;p&gt;根据文章标题中的英语单词自动生成文章的 URL 是一个很好的体验，比如标题为“&lt;a rel=&quot;nofollow&quot; title=&quot;Girl's death sparks riot in China&quot; href=&quot;http://edition.cnn.com/2008/WORLD/asiapcf/06/30/china.riots/index.html&quot; id=&quot;hjgz&quot;&gt;Girl's death sparks riot in China&lt;/a&gt;”，会被转换成“girls-death-sparks-riot-china”这样与之对应的 URL。这样既可获得 &lt;a title=&quot;Cool URI&quot; rel=&quot;nofollow&quot; href=&quot;http://www.w3.org/Provider/Style/URI&quot; id=&quot;zl1v&quot;&gt;Cool URIs&lt;/a&gt;，又便于用户记忆，同时也有利于 &lt;a rel=&quot;nofollow&quot; title=&quot;SEO&quot; href=&quot;http://www.chinamyhosting.com/seoblog/2006/08/19/whats-seo/&quot; id=&quot;s92m&quot;&gt;SEO&lt;/a&gt;，&lt;a rel=&quot;nofollow&quot; title=&quot;Blogger&quot; href=&quot;http://www.blogger.com&quot; id=&quot;ied5&quot;&gt;Blogger&lt;/a&gt; 和 &lt;a rel=&quot;nofollow&quot; title=&quot;Wordpress&quot; href=&quot;http://www.wordpress.com/&quot; id=&quot;w-.u&quot;&gt;Wordpress&lt;/a&gt; 也都支持类似体验。而中文的文章标题，也可以先将其中的汉字转化为拼音后再组成相应的 URL，比如标题为“&lt;a rel=&quot;nofollow&quot; title=&quot;俯卧撑&quot; href=&quot;http://www.google.com/search?q=俯卧撑+瓮安&quot;&gt;俯卧撑&lt;/a&gt;”，可以被转换成“fu-wo-cheng”。&lt;br /&gt;
&lt;br /&gt;
&lt;a title=&quot;pinyin-urlify&quot; href=&quot;http://code.google.com/p/pinyin-urlify/&quot; id=&quot;hof4&quot;&gt;pinyin-urlify&lt;/a&gt; 是我这几天写的能根据汉字自动生成拼音 URL 的 Python 脚本。它可以将汉字映射成有英语字母组成的拼音，和多种西方语言的字母（拉丁语、希腊语、俄语等）映射成相近的英语字母。要说明的是，汉字-拼音的映射表是从 &lt;a title=&quot;pyzh 项目&quot; href=&quot;http://code.google.com/p/pyzh/&quot; id=&quot;l_q.&quot;&gt;pyzh 项目&lt;/a&gt;中获得，而其他西方语言的映射表则是从 &lt;a title=&quot;Django 项目&quot; href=&quot;http://www.djangoproject.com/&quot; id=&quot;z5sj&quot;&gt;Django 项目&lt;/a&gt;中获得，&lt;b id=&quot;mrrn&quot;&gt;特表感谢&lt;/b&gt;。&lt;br /&gt;
&lt;br /&gt;
pinyin-urlify 支持自定义停用词列表（stop words）和保留词列表（reserved words）。停用词列表中的单词都会被过滤，不会出现在生成的 URL 中。生成的 URL 如果和保留词列表中的某一个单词匹配，则会被替换成默认的 URL 字符串。pinyin-urlify 可以指定 URL 的最大长度。不过，如果遇到有较多汉字组成的文章标题的话，实际生成的 URL 可能会比限定的最大长度小一些。我希望能在以后修正这一点。&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;使用示例&lt;/h4&gt;
&lt;pre class=&quot;codes&quot;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; from urlify import urlify
&amp;gt;&amp;gt;&amp;gt; urlify(u'三个俯卧撑引发的血案', default='blog_post',
...        max_length=50, stop_words=[u'is', u'a', u'an'],
...        reserved_words=[u'new', u'edit'])
u'san-ge-fu-wo-cheng-yin-fa-de-xue'&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
欢迎大家用 svn 检出 pinyin-urlify 的副本来使用。欢迎任何意见或建议 :-)&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;$ svn checkout http://pinyin-urlify.googlecode.com/svn/trunk/ pinyin-urlify&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;!-- Feedsky flare --&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=0e493f59bd0bbc4c7f8cb11a5dc2e664&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=0e493f59bd0bbc4c7f8cb11a5dc2e664&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=498845e9ccc2a87c3567125bfead040b&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=498845e9ccc2a87c3567125bfead040b&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=cbd3a937e53c99ebc8923ee391497cc2&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=cbd3a937e53c99ebc8923ee391497cc2&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=f95e305d3aafc178c28deaf41dade2bc&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=f95e305d3aafc178c28deaf41dade2bc&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;!-- /Feedsky flare --&gt;</content:encoded><category domain="http://www.blogger.com/atom/ns#">python</category><pubDate>Sun, 06 Jul 2008 19:31:06 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-7286295415331143255.post-1320338599645208961</guid><dc:creator>wyt</dc:creator><fs:srclink>http://luliban.com/blog/2008/07/pinyin-urlify-url.html</fs:srclink><fs:srcfeed>http://luliban.com/blog/feeds/atom.xml</fs:srcfeed><fs:itemid>feedsky/luliban/~6996753/89487017/4034731</fs:itemid></item><item><title>有备无患：浏览器端缓存（基于 jQuery）</title><link atom:title="有备无患：浏览器端缓存（基于 jQuery）" atom:type="text/html">http://item.feedsky.com/~feedsky/luliban/~6996753/90067667/4034731/1/item.html</link><id xmlns="http://www.w3.org/2005/Atom">tag:blogger.com,1999:blog-7286295415331143255.post-4901571834404718695</id><content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;p&gt;最近在翻《&lt;a rel=&quot;nofollow&quot; title=&quot;Ajax 设计模式&quot; href=&quot;http://www.douban.com/subject/2121078/&quot;&gt;Ajax 设计模式&lt;/a&gt;》，所以想把其中的一部分模式实现出来练手 &lt;a rel=&quot;nofollow&quot; title=&quot;jQuery&quot; href=&quot;http://jquery.com/&quot;&gt;jQuery&lt;/a&gt;，今天写了一个简单的引入 LRU 算法的浏览器端缓存（Browser Side Cache）。&lt;br /&gt;
&lt;br /&gt;
浏览器端缓存用来保留服务器返回的查询结果。这种缓存是一个 Javascript 里类似映射的对象，存储成对的查询结果；查询是缓存的键（Key），服务器返回的结果是缓存的值（Value）。因此，每当浏览器需要查询服务器时，先检查缓存。如果该查询是缓存中的一个键，则与键对应的值将被当作结果，而不必再向服务器查询。&lt;br /&gt;
&lt;br /&gt;
LRU （Least Recently Used）是将存储在缓存中的自上一次获取之后，最长时间未被使用的项目（Item）丢弃的一种算法。可以用两个数组（Array）来实现，其一是用来存储查询结果的键值对（Key-Value Pairs），其二是一个先进先出（FIFO）的队列，每一个新项目被塞入队列的尾部，并随着后续项目的跟进，逐渐逼近队列的头部。当队列全满时，每次向尾部塞入一个新项目，就要从头部弹出一个旧项目。而每当一个项目被缓存查询时，它会被送回到队列的尾部，这样可以确保最长时间未被使用的项目总是在开头处。&lt;br /&gt;
&lt;br /&gt;
另外，还有一种常用的缓存算法，LFU （Least Frequently Used），它将自上一次获取后最少被使用的项目丢弃。&lt;br /&gt;
&lt;br /&gt;
顺便一说，下面贴出的代码是由&lt;a id=&quot;umnt10&quot; title=&quot;代码发芽网&quot; href=&quot;http://www.fayaa.com/code/home/&quot;&gt;代码发芽网&lt;/a&gt;生产的纯 HTML。代码发芽网是一个“无需插件支持 Blog 代码高亮，支持近百种编程语言，多种配色主题支持，代码版本管理”的代码片段管理网站。因为不是由 Javascript 脚本来高亮处理，所以在 feed 里也一样可以看到效果，这一点很赞。不过，由于用处不大的 id 和 class 也包含在生成的 HTML 里，所以体积偏大。比如说下面这段代码，在删除了多余的 id 和 class，套上代码专用的 &lt;a id=&quot;umnt11&quot; rel=&quot;nofollow&quot; title=&quot;pre&quot; href=&quot;http://www.w3schools.com/TAGS/tag_pre.asp&quot;&gt;pre&lt;/a&gt; 和 &lt;a id=&quot;umnt12&quot; rel=&quot;nofollow&quot; title=&quot;code&quot; href=&quot;http://www.w3schools.com/TAGS/tag_phrase_elements.asp&quot;&gt;code&lt;/a&gt; 标签，并将 &amp;amp;nbsp; 还原成空格之后，体积可以缩小一半仅17KB（原来35KB），更适合 blog 来贴代码。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;cache.js&lt;/h4&gt;
&lt;pre class=&quot;codes&quot;&gt;&lt;code&gt;&lt;span&gt;01&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt; &lt;span&gt;Cache&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;02&lt;/span&gt;     &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* A browser side LRU cache &lt;/span&gt;
&lt;span&gt;03&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     * Author: Wu Yuntao &amp;lt;http://luliban.com/blog/&amp;gt;&lt;/span&gt;
&lt;span&gt;04&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     * License: GPLv3&lt;/span&gt;
&lt;span&gt;05&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     *&lt;/span&gt;
&lt;span&gt;06&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     * Usage:&lt;/span&gt;
&lt;span&gt;07&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     * var cache = new Cache(10);   // create a new cache object&lt;/span&gt;
&lt;span&gt;08&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     * cache.put('w', 'wiki');      // put an item into cache&lt;/span&gt;
&lt;span&gt;09&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     * cache.get('w');              // get the value of item with key&lt;/span&gt;
&lt;span&gt;10&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     * cache.remove('w');           // remove an item with specified key&lt;/span&gt;
&lt;span&gt;11&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     * cache.initialize()           // re-initialize the cache&lt;/span&gt;
&lt;span&gt;12&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     * cache.size(10)               // resize the cache&lt;/span&gt;
&lt;span&gt;13&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     */&lt;/span&gt;
&lt;span&gt;14&lt;/span&gt;     &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;initialize&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;15&lt;/span&gt; &lt;span&gt;}&lt;/span&gt;
&lt;span&gt;16&lt;/span&gt; 
&lt;span&gt;17&lt;/span&gt; &lt;span&gt;Cache&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;prototype&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;=&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;18&lt;/span&gt;     &lt;span&gt;initialize&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;19&lt;/span&gt;         &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* Initialize cache.&lt;/span&gt;
&lt;span&gt;20&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         * ``size`` is the number of maxmium items this cache should hold.&lt;/span&gt;
&lt;span&gt;21&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         * Default is maxium integer.&lt;/span&gt;
&lt;span&gt;22&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         */&lt;/span&gt;
&lt;span&gt;23&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_keys&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32);&quot;&gt;Array&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;
&lt;span&gt;24&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_items&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32);&quot;&gt;Array&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;
&lt;span&gt;25&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_size&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;=&lt;/span&gt; &lt;span&gt;size&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;||&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_size&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;||&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32);&quot;&gt;Number&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;MAX_VALUE&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;;&lt;/span&gt;
&lt;span&gt;26&lt;/span&gt;     &lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt;
&lt;span&gt;27&lt;/span&gt; 
&lt;span&gt;28&lt;/span&gt;     &lt;span&gt;is_empty&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span&gt;()&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;29&lt;/span&gt;         &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* Check if cache is empty&lt;/span&gt;
&lt;span&gt;30&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         */&lt;/span&gt;
&lt;span&gt;31&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_keys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;length&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: rgb(64, 160, 112);&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_items&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;length&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: rgb(64, 160, 112);&quot;&gt;0&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;32&lt;/span&gt;     &lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt;
&lt;span&gt;33&lt;/span&gt; 
&lt;span&gt;34&lt;/span&gt;     &lt;span&gt;size&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;35&lt;/span&gt;         &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* Resize cache if ``size`` is specified, or return accual size of cache.&lt;/span&gt;
&lt;span&gt;36&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         */&lt;/span&gt;
&lt;span&gt;37&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;typeof&lt;/span&gt; &lt;span&gt;size&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: rgb(64, 112, 160);&quot;&gt;'undefined'&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_keys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;;&lt;/span&gt;
&lt;span&gt;38&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_size&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;=&lt;/span&gt; &lt;span&gt;size&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;;&lt;/span&gt;
&lt;span&gt;39&lt;/span&gt;     &lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt;
&lt;span&gt;40&lt;/span&gt; 
&lt;span&gt;41&lt;/span&gt;     &lt;span&gt;put&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt; &lt;span&gt;value&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;42&lt;/span&gt;         &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* Put a new item into cache, if the size of cache reaches limit,&lt;/span&gt;
&lt;span&gt;43&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         * cache will remove the least recently used (LRU) automatically.&lt;/span&gt;
&lt;span&gt;44&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         * ``key`` of an item should be a string.&lt;/span&gt;
&lt;span&gt;45&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         * ``value`` of an item could be anything, string, array or object.&lt;/span&gt;
&lt;span&gt;46&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         * If ``value`` is not defined, returns null.&lt;/span&gt;
&lt;span&gt;47&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         */&lt;/span&gt;
&lt;span&gt;48&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;typeof&lt;/span&gt; &lt;span&gt;value&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;!=&lt;/span&gt; &lt;span style=&quot;color: rgb(64, 112, 160);&quot;&gt;'undefined'&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;49&lt;/span&gt;             &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_keys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;50&lt;/span&gt;             &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_items&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;]&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;=&lt;/span&gt; &lt;span&gt;value&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;;&lt;/span&gt;
&lt;span&gt;51&lt;/span&gt; 
&lt;span&gt;52&lt;/span&gt;             &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_keys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;length&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;53&lt;/span&gt;                 &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;remove_least&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;
&lt;span&gt;54&lt;/span&gt;             &lt;span&gt;}&lt;/span&gt;
&lt;span&gt;55&lt;/span&gt;         &lt;span&gt;}&lt;/span&gt;
&lt;span&gt;56&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span&gt;value&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;;&lt;/span&gt;
&lt;span&gt;57&lt;/span&gt;     &lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt;
&lt;span&gt;58&lt;/span&gt; 
&lt;span&gt;59&lt;/span&gt;     &lt;span&gt;get&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;60&lt;/span&gt;         &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* Retrieve an item by its key and move it to the tail of cache.&lt;/span&gt;
&lt;span&gt;61&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         * If the item of ``key`` does not exist, returns null.&lt;/span&gt;
&lt;span&gt;62&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         */&lt;/span&gt;
&lt;span&gt;63&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;typeof&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_items&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;]&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: rgb(64, 112, 160);&quot;&gt;'undefined'&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;;&lt;/span&gt;
&lt;span&gt;64&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;var&lt;/span&gt; &lt;span&gt;used_key&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_remove_key&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;65&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_keys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;used_key&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;66&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_items&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;
&lt;span&gt;67&lt;/span&gt;     &lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt;
&lt;span&gt;68&lt;/span&gt; 
&lt;span&gt;69&lt;/span&gt;     &lt;span&gt;remove_least&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span&gt;()&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;70&lt;/span&gt;         &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* Manually remove the least recently used item. */&lt;/span&gt;
&lt;span&gt;71&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;is_empty&lt;/span&gt;&lt;span&gt;())&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;remove&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_keys&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span style=&quot;color: rgb(64, 160, 112);&quot;&gt;0&lt;/span&gt;&lt;span&gt;]);&lt;/span&gt;
&lt;span&gt;72&lt;/span&gt;     &lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt;
&lt;span&gt;73&lt;/span&gt; 
&lt;span&gt;74&lt;/span&gt;     &lt;span&gt;remove&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;75&lt;/span&gt;         &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* Remove an item by its key.&lt;/span&gt;
&lt;span&gt;76&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         * If the item of ``key`` does not exist, returns null.&lt;/span&gt;
&lt;span&gt;77&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         */&lt;/span&gt;
&lt;span&gt;78&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;typeof&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_items&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;]&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: rgb(64, 112, 160);&quot;&gt;'undefined'&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;;&lt;/span&gt;
&lt;span&gt;79&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_remove_key&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;80&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_remove_value&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;81&lt;/span&gt;     &lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt;
&lt;span&gt;82&lt;/span&gt; 
&lt;span&gt;83&lt;/span&gt;     &lt;span&gt;_remove_key&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;84&lt;/span&gt;         &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* Remove the ``key`` in ``this._keys``.&lt;/span&gt;
&lt;span&gt;85&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         */&lt;/span&gt;
&lt;span&gt;86&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;var&lt;/span&gt; &lt;span&gt;i&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;=&lt;/span&gt; &lt;span&gt;$&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;inArray&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_keys&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;87&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_keys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;splice&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: rgb(64, 160, 112);&quot;&gt;1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;88&lt;/span&gt;     &lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt;
&lt;span&gt;89&lt;/span&gt; 
&lt;span&gt;90&lt;/span&gt;     &lt;span&gt;_remove_value&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;91&lt;/span&gt;         &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* Remove the item in ``this._items``. */&lt;/span&gt;
&lt;span&gt;92&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;var&lt;/span&gt; &lt;span&gt;value&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_items&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;
&lt;span&gt;93&lt;/span&gt;         &lt;span&gt;delete&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_items&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;
&lt;span&gt;94&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span&gt;value&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;;&lt;/span&gt;
&lt;span&gt;95&lt;/span&gt;     &lt;span&gt;}&lt;/span&gt;
&lt;span&gt;96&lt;/span&gt; 
&lt;span&gt;97&lt;/span&gt; &lt;span&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content><author xmlns="http://www.w3.org/2005/Atom"><name>wyt</name><uri>http://www.blogger.com/profile/04947921907676762514</uri><email>noreply@blogger.com</email></author><content:encoded>&lt;p&gt;最近在翻《&lt;a rel=&quot;nofollow&quot; title=&quot;Ajax 设计模式&quot; href=&quot;http://www.douban.com/subject/2121078/&quot;&gt;Ajax 设计模式&lt;/a&gt;》，所以想把其中的一部分模式实现出来练手 &lt;a rel=&quot;nofollow&quot; title=&quot;jQuery&quot; href=&quot;http://jquery.com/&quot;&gt;jQuery&lt;/a&gt;，今天写了一个简单的引入 LRU 算法的浏览器端缓存（Browser Side Cache）。&lt;br /&gt;
&lt;br /&gt;
浏览器端缓存用来保留服务器返回的查询结果。这种缓存是一个 Javascript 里类似映射的对象，存储成对的查询结果；查询是缓存的键（Key），服务器返回的结果是缓存的值（Value）。因此，每当浏览器需要查询服务器时，先检查缓存。如果该查询是缓存中的一个键，则与键对应的值将被当作结果，而不必再向服务器查询。&lt;br /&gt;
&lt;br /&gt;
LRU （Least Recently Used）是将存储在缓存中的自上一次获取之后，最长时间未被使用的项目（Item）丢弃的一种算法。可以用两个数组（Array）来实现，其一是用来存储查询结果的键值对（Key-Value Pairs），其二是一个先进先出（FIFO）的队列，每一个新项目被塞入队列的尾部，并随着后续项目的跟进，逐渐逼近队列的头部。当队列全满时，每次向尾部塞入一个新项目，就要从头部弹出一个旧项目。而每当一个项目被缓存查询时，它会被送回到队列的尾部，这样可以确保最长时间未被使用的项目总是在开头处。&lt;br /&gt;
&lt;br /&gt;
另外，还有一种常用的缓存算法，LFU （Least Frequently Used），它将自上一次获取后最少被使用的项目丢弃。&lt;br /&gt;
&lt;br /&gt;
顺便一说，下面贴出的代码是由&lt;a id=&quot;umnt10&quot; title=&quot;代码发芽网&quot; href=&quot;http://www.fayaa.com/code/home/&quot;&gt;代码发芽网&lt;/a&gt;生产的纯 HTML。代码发芽网是一个“无需插件支持 Blog 代码高亮，支持近百种编程语言，多种配色主题支持，代码版本管理”的代码片段管理网站。因为不是由 Javascript 脚本来高亮处理，所以在 feed 里也一样可以看到效果，这一点很赞。不过，由于用处不大的 id 和 class 也包含在生成的 HTML 里，所以体积偏大。比如说下面这段代码，在删除了多余的 id 和 class，套上代码专用的 &lt;a id=&quot;umnt11&quot; rel=&quot;nofollow&quot; title=&quot;pre&quot; href=&quot;http://www.w3schools.com/TAGS/tag_pre.asp&quot;&gt;pre&lt;/a&gt; 和 &lt;a id=&quot;umnt12&quot; rel=&quot;nofollow&quot; title=&quot;code&quot; href=&quot;http://www.w3schools.com/TAGS/tag_phrase_elements.asp&quot;&gt;code&lt;/a&gt; 标签，并将 &amp;amp;nbsp; 还原成空格之后，体积可以缩小一半仅17KB（原来35KB），更适合 blog 来贴代码。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;cache.js&lt;/h4&gt;
&lt;pre class=&quot;codes&quot;&gt;&lt;code&gt;&lt;span&gt;01&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt; &lt;span&gt;Cache&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;02&lt;/span&gt;     &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* A browser side LRU cache &lt;/span&gt;
&lt;span&gt;03&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     * Author: Wu Yuntao &amp;lt;http://luliban.com/blog/&amp;gt;&lt;/span&gt;
&lt;span&gt;04&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     * License: GPLv3&lt;/span&gt;
&lt;span&gt;05&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     *&lt;/span&gt;
&lt;span&gt;06&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     * Usage:&lt;/span&gt;
&lt;span&gt;07&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     * var cache = new Cache(10);   // create a new cache object&lt;/span&gt;
&lt;span&gt;08&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     * cache.put('w', 'wiki');      // put an item into cache&lt;/span&gt;
&lt;span&gt;09&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     * cache.get('w');              // get the value of item with key&lt;/span&gt;
&lt;span&gt;10&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     * cache.remove('w');           // remove an item with specified key&lt;/span&gt;
&lt;span&gt;11&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     * cache.initialize()           // re-initialize the cache&lt;/span&gt;
&lt;span&gt;12&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     * cache.size(10)               // resize the cache&lt;/span&gt;
&lt;span&gt;13&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;     */&lt;/span&gt;
&lt;span&gt;14&lt;/span&gt;     &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;initialize&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;15&lt;/span&gt; &lt;span&gt;}&lt;/span&gt;
&lt;span&gt;16&lt;/span&gt; 
&lt;span&gt;17&lt;/span&gt; &lt;span&gt;Cache&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;prototype&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;=&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;18&lt;/span&gt;     &lt;span&gt;initialize&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;19&lt;/span&gt;         &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* Initialize cache.&lt;/span&gt;
&lt;span&gt;20&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         * ``size`` is the number of maxmium items this cache should hold.&lt;/span&gt;
&lt;span&gt;21&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         * Default is maxium integer.&lt;/span&gt;
&lt;span&gt;22&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         */&lt;/span&gt;
&lt;span&gt;23&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_keys&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32);&quot;&gt;Array&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;
&lt;span&gt;24&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_items&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32);&quot;&gt;Array&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;
&lt;span&gt;25&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_size&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;=&lt;/span&gt; &lt;span&gt;size&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;||&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_size&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;||&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32);&quot;&gt;Number&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;MAX_VALUE&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;;&lt;/span&gt;
&lt;span&gt;26&lt;/span&gt;     &lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt;
&lt;span&gt;27&lt;/span&gt; 
&lt;span&gt;28&lt;/span&gt;     &lt;span&gt;is_empty&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span&gt;()&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;29&lt;/span&gt;         &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* Check if cache is empty&lt;/span&gt;
&lt;span&gt;30&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         */&lt;/span&gt;
&lt;span&gt;31&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_keys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;length&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: rgb(64, 160, 112);&quot;&gt;0&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_items&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;length&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: rgb(64, 160, 112);&quot;&gt;0&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;32&lt;/span&gt;     &lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt;
&lt;span&gt;33&lt;/span&gt; 
&lt;span&gt;34&lt;/span&gt;     &lt;span&gt;size&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;35&lt;/span&gt;         &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* Resize cache if ``size`` is specified, or return accual size of cache.&lt;/span&gt;
&lt;span&gt;36&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         */&lt;/span&gt;
&lt;span&gt;37&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;typeof&lt;/span&gt; &lt;span&gt;size&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: rgb(64, 112, 160);&quot;&gt;'undefined'&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_keys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;;&lt;/span&gt;
&lt;span&gt;38&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_size&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;=&lt;/span&gt; &lt;span&gt;size&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;;&lt;/span&gt;
&lt;span&gt;39&lt;/span&gt;     &lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt;
&lt;span&gt;40&lt;/span&gt; 
&lt;span&gt;41&lt;/span&gt;     &lt;span&gt;put&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt; &lt;span&gt;value&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;42&lt;/span&gt;         &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* Put a new item into cache, if the size of cache reaches limit,&lt;/span&gt;
&lt;span&gt;43&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         * cache will remove the least recently used (LRU) automatically.&lt;/span&gt;
&lt;span&gt;44&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         * ``key`` of an item should be a string.&lt;/span&gt;
&lt;span&gt;45&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         * ``value`` of an item could be anything, string, array or object.&lt;/span&gt;
&lt;span&gt;46&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         * If ``value`` is not defined, returns null.&lt;/span&gt;
&lt;span&gt;47&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         */&lt;/span&gt;
&lt;span&gt;48&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;typeof&lt;/span&gt; &lt;span&gt;value&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;!=&lt;/span&gt; &lt;span style=&quot;color: rgb(64, 112, 160);&quot;&gt;'undefined'&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;49&lt;/span&gt;             &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_keys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;50&lt;/span&gt;             &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_items&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;]&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;=&lt;/span&gt; &lt;span&gt;value&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;;&lt;/span&gt;
&lt;span&gt;51&lt;/span&gt; 
&lt;span&gt;52&lt;/span&gt;             &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_keys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;length&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;53&lt;/span&gt;                 &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;remove_least&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;
&lt;span&gt;54&lt;/span&gt;             &lt;span&gt;}&lt;/span&gt;
&lt;span&gt;55&lt;/span&gt;         &lt;span&gt;}&lt;/span&gt;
&lt;span&gt;56&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span&gt;value&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;;&lt;/span&gt;
&lt;span&gt;57&lt;/span&gt;     &lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt;
&lt;span&gt;58&lt;/span&gt; 
&lt;span&gt;59&lt;/span&gt;     &lt;span&gt;get&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;60&lt;/span&gt;         &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* Retrieve an item by its key and move it to the tail of cache.&lt;/span&gt;
&lt;span&gt;61&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         * If the item of ``key`` does not exist, returns null.&lt;/span&gt;
&lt;span&gt;62&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         */&lt;/span&gt;
&lt;span&gt;63&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;typeof&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_items&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;]&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: rgb(64, 112, 160);&quot;&gt;'undefined'&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;;&lt;/span&gt;
&lt;span&gt;64&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;var&lt;/span&gt; &lt;span&gt;used_key&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_remove_key&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;65&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_keys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;used_key&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;66&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_items&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;
&lt;span&gt;67&lt;/span&gt;     &lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt;
&lt;span&gt;68&lt;/span&gt; 
&lt;span&gt;69&lt;/span&gt;     &lt;span&gt;remove_least&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span&gt;()&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;70&lt;/span&gt;         &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* Manually remove the least recently used item. */&lt;/span&gt;
&lt;span&gt;71&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;is_empty&lt;/span&gt;&lt;span&gt;())&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;remove&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_keys&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span style=&quot;color: rgb(64, 160, 112);&quot;&gt;0&lt;/span&gt;&lt;span&gt;]);&lt;/span&gt;
&lt;span&gt;72&lt;/span&gt;     &lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt;
&lt;span&gt;73&lt;/span&gt; 
&lt;span&gt;74&lt;/span&gt;     &lt;span&gt;remove&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;75&lt;/span&gt;         &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* Remove an item by its key.&lt;/span&gt;
&lt;span&gt;76&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         * If the item of ``key`` does not exist, returns null.&lt;/span&gt;
&lt;span&gt;77&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         */&lt;/span&gt;
&lt;span&gt;78&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;if&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;typeof&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_items&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;]&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: rgb(64, 112, 160);&quot;&gt;'undefined'&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;;&lt;/span&gt;
&lt;span&gt;79&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_remove_key&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;80&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_remove_value&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;81&lt;/span&gt;     &lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt;
&lt;span&gt;82&lt;/span&gt; 
&lt;span&gt;83&lt;/span&gt;     &lt;span&gt;_remove_key&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;84&lt;/span&gt;         &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* Remove the ``key`` in ``this._keys``.&lt;/span&gt;
&lt;span&gt;85&lt;/span&gt; &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;         */&lt;/span&gt;
&lt;span&gt;86&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;var&lt;/span&gt; &lt;span&gt;i&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;=&lt;/span&gt; &lt;span&gt;$&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;inArray&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_keys&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;87&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_keys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;splice&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: rgb(64, 160, 112);&quot;&gt;1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
&lt;span&gt;88&lt;/span&gt;     &lt;span&gt;}&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;,&lt;/span&gt;
&lt;span&gt;89&lt;/span&gt; 
&lt;span&gt;90&lt;/span&gt;     &lt;span&gt;_remove_value&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;91&lt;/span&gt;         &lt;span style=&quot;color: rgb(96, 160, 176); font-style: italic;&quot;&gt;/* Remove the item in ``this._items``. */&lt;/span&gt;
&lt;span&gt;92&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;var&lt;/span&gt; &lt;span&gt;value&lt;/span&gt; &lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_items&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;
&lt;span&gt;93&lt;/span&gt;         &lt;span&gt;delete&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;_items&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;
&lt;span&gt;94&lt;/span&gt;         &lt;span style=&quot;color: rgb(0, 112, 32); font-weight: bold;&quot;&gt;return&lt;/span&gt; &lt;span&gt;value&lt;/span&gt;&lt;span style=&quot;color: rgb(102, 102, 102);&quot;&gt;;&lt;/span&gt;
&lt;span&gt;95&lt;/span&gt;     &lt;span&gt;}&lt;/span&gt;
&lt;span&gt;96&lt;/span&gt; 
&lt;span&gt;97&lt;/span&gt; &lt;span&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;!-- Feedsky flare --&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=d3eea419cc624d69f19c98775d0bf76f&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=d3eea419cc624d69f19c98775d0bf76f&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=42d2279ef96a2c5f8763120072cea9b0&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=42d2279ef96a2c5f8763120072cea9b0&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=d2ae9e45cbfacb89925475176417644d&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=d2ae9e45cbfacb89925475176417644d&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=3ff5a243a7c0d534540bd011f82c4987&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=3ff5a243a7c0d534540bd011f82c4987&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;!-- /Feedsky flare --&gt;</content:encoded><category domain="http://www.blogger.com/atom/ns#">javascript</category><pubDate>Fri, 04 Jul 2008 21:31:25 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-7286295415331143255.post-4901571834404718695</guid><dc:creator>wyt</dc:creator><fs:srclink>http://luliban.com/blog/2008/07/jquery.html</fs:srclink><fs:srcfeed>http://luliban.com/blog/feeds/atom.xml</fs:srcfeed><fs:itemid>feedsky/luliban/~6996753/90067667/4034731</fs:itemid></item><item><title>有备无患：绕过 GHS 用自定义域名发布 Blogger</title><link atom:title="有备无患：绕过 GHS 用自定义域名发布 Blogger" atom:type="text/html">http://item.feedsky.com/~feedsky/luliban/~6996753/87867494/4034731/1/item.html</link><id xmlns="http://www.w3.org/2005/Atom">tag:blogger.com,1999:blog-7286295415331143255.post-1472011599496106035</id><content xmlns="http://www.w3.org/2005/Atom" type="html">2007年1月，&lt;a rel=&quot;nofollow&quot; title=&quot;Google Blogger&quot; href=&quot;http://www.blogger.com&quot;&gt;Google Blogger&lt;/a&gt; 的自定义域名功能推出不到一个星期，就&lt;a rel=&quot;nofollow&quot; title=&quot;Blogger的自定义域名功能被废&quot; href=&quot;http://www.gseeker.com/50226711/bloggerceaeee_56005.php&quot;&gt;被 GFW 给废了&lt;/a&gt;。原因就是 GFW 隔断了国内用户对 Google 的免费主机托管服务 ghs.google.com 的访问。&lt;br /&gt;

&lt;br /&gt;

今天试着将 App Engine 应用部署到自己域名的时候，发现 App Engine 不需要将 CNAME record 指向 ghs.google.com，从而可以避开 GFW。而&lt;a rel=&quot;nofollow&quot; title=&quot;App Engine URLs&quot; href=&quot;http://www.google.com/support/a/bin/answer.py?hl=en&amp;answer=91080&quot;&gt;同样的方法&lt;/a&gt;也可以适用于 Blogger。方法如下：&lt;br /&gt;

&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;
把 Blogger 的发布方式切换成“自定义域名（Custom Domain）”。在“你的域名（Your Domain）”一栏中填上域名，比如，py.thonic.org。保存设置（Save Settings）。&lt;/li&gt;

&lt;li&gt;在你的域名注册商那里，修改域名（thonic.org）的 DNS 设置。为子域名（py）添加一条 A record，指向下面四个 IP 地址的其中之一。举例来说，就是添加这样一条记录：&lt;b&gt;py.thonic.org  86400  IN  A  216.239.34.21&lt;/b&gt;。
&lt;ul&gt;
&lt;li&gt;216.239.32.21&lt;/li&gt;
&lt;li&gt;216.239.34.21&lt;/li&gt;
&lt;li&gt;216.239.36.21&lt;/li&gt;
&lt;li&gt;216.239.38.21&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;/ol&gt;

&lt;br /&gt;

DNS 设置的改动需要一段时间来完成，一般不会超过24小时。这样就可以重新使用 Blogger 的自定义域名功能了，只是，这次又可以持续多久呢？

&lt;br /&gt;
&lt;br /&gt;

&lt;h4&gt;2008-06-26 UPDATE&lt;/h4&gt;
&lt;p&gt;我把上面的 IP 绑定到自己的域名了，ghs.luliban.com。以后也可以像 ghs.google.com 一样，添加一条 CNAME 记录到 ghs.luliban.com 来绑定 Google Blogger 或者 Google Apps 了。&lt;/p&gt;</content><author xmlns="http://www.w3.org/2005/Atom"><name>wyt</name><uri>http://www.blogger.com/profile/04947921907676762514</uri><email>noreply@blogger.com</email></author><content:encoded>2007年1月，&lt;a rel=&quot;nofollow&quot; title=&quot;Google Blogger&quot; href=&quot;http://www.blogger.com&quot;&gt;Google Blogger&lt;/a&gt; 的自定义域名功能推出不到一个星期，就&lt;a rel=&quot;nofollow&quot; title=&quot;Blogger的自定义域名功能被废&quot; href=&quot;http://www.gseeker.com/50226711/bloggerceaeee_56005.php&quot;&gt;被 GFW 给废了&lt;/a&gt;。原因就是 GFW 隔断了国内用户对 Google 的免费主机托管服务 ghs.google.com 的访问。&lt;br /&gt;

&lt;br /&gt;

今天试着将 App Engine 应用部署到自己域名的时候，发现 App Engine 不需要将 CNAME record 指向 ghs.google.com，从而可以避开 GFW。而&lt;a rel=&quot;nofollow&quot; title=&quot;App Engine URLs&quot; href=&quot;http://www.google.com/support/a/bin/answer.py?hl=en&amp;answer=91080&quot;&gt;同样的方法&lt;/a&gt;也可以适用于 Blogger。方法如下：&lt;br /&gt;

&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;
把 Blogger 的发布方式切换成“自定义域名（Custom Domain）”。在“你的域名（Your Domain）”一栏中填上域名，比如，py.thonic.org。保存设置（Save Settings）。&lt;/li&gt;

&lt;li&gt;在你的域名注册商那里，修改域名（thonic.org）的 DNS 设置。为子域名（py）添加一条 A record，指向下面四个 IP 地址的其中之一。举例来说，就是添加这样一条记录：&lt;b&gt;py.thonic.org  86400  IN  A  216.239.34.21&lt;/b&gt;。
&lt;ul&gt;
&lt;li&gt;216.239.32.21&lt;/li&gt;
&lt;li&gt;216.239.34.21&lt;/li&gt;
&lt;li&gt;216.239.36.21&lt;/li&gt;
&lt;li&gt;216.239.38.21&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;

&lt;/ol&gt;

&lt;br /&gt;

DNS 设置的改动需要一段时间来完成，一般不会超过24小时。这样就可以重新使用 Blogger 的自定义域名功能了，只是，这次又可以持续多久呢？

&lt;br /&gt;
&lt;br /&gt;

&lt;h4&gt;2008-06-26 UPDATE&lt;/h4&gt;
&lt;p&gt;我把上面的 IP 绑定到自己的域名了，ghs.luliban.com。以后也可以像 ghs.google.com 一样，添加一条 CNAME 记录到 ghs.luliban.com 来绑定 Google Blogger 或者 Google Apps 了。&lt;/p&gt;&lt;br /&gt;&lt;!-- Feedsky flare --&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=c641820961c5f1eeca56b604cb9a711c&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=c641820961c5f1eeca56b604cb9a711c&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=cc51869ff183cd86928c1312dab84ee7&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=cc51869ff183cd86928c1312dab84ee7&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=5cd6cf33393f3d83a73b9da7e1548f02&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=5cd6cf33393f3d83a73b9da7e1548f02&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=d19b93d34593c105c34a6898e03d89d2&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=d19b93d34593c105c34a6898e03d89d2&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;!-- /Feedsky flare --&gt;</content:encoded><category domain="http://www.blogger.com/atom/ns#">blogger</category><category domain="http://www.blogger.com/atom/ns#">google</category><pubDate>Thu, 26 Jun 2008 20:01:01 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-7286295415331143255.post-1472011599496106035</guid><dc:creator>wyt</dc:creator><fs:srclink>http://luliban.com/blog/2008/05/ghs-blogger.html</fs:srclink><fs:srcfeed>http://luliban.com/blog/feeds/atom.xml</fs:srcfeed><fs:itemid>feedsky/luliban/~6996753/87867494/4034731</fs:itemid></item><item><title>有备无患：在 GitHub 上用不同的 SSH 公钥部署多个应用</title><link atom:title="有备无患：在 GitHub 上用不同的 SSH 公钥部署多个应用" atom:type="text/html">http://item.feedsky.com/~feedsky/luliban/~6996753/87867490/4034731/1/item.html</link><id xmlns="http://www.w3.org/2005/Atom">tag:blogger.com,1999:blog-7286295415331143255.post-2921259291670305060</id><content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;p&gt;
&lt;a href=&quot;http://github.com&quot; title=&quot;GitHub&quot; rel=&quot;nofollow&quot;&gt;GitHub&lt;/a&gt; 是一个免费的基于 git 的开源软件仓库托管服务，包括 &lt;a href=&quot;http://github.com/rails/rails/tree&quot; rel=&quot;nofollow&quot;&gt;Ruby on Rails&lt;/a&gt;， &lt;a href=&quot;http://github.com/dchelimsky/rspec/tree&quot; rel=&quot;nofollow&quot;&gt;Rspec&lt;/a&gt;，&lt;a href=&quot;http://github.com/sstephenson/prototype/tree&quot; rel=&quot;nofollow&quot;&gt;Prototype&lt;/a&gt; 在内的许多开源软件都在 GitHub 上架设了软件仓库。
&lt;/p&gt;

&lt;br /&gt;

&lt;p&gt;
如果你有两个或两个以上的 GitHub 仓库，并且想用不同的公钥／私钥来管理这些仓库的话，会遇到这样一个问题。当你 clone 第一个仓库的时候，git 会使用第一对公钥／私钥，这个时候仍然一切正常。可当你需要用另一对公钥／私钥来 clone 第二个仓库的时候，git 默认仍然会使用第一对公钥／私钥，然后 GitHub 就会返回一个授权错误。
&lt;/p&gt;

&lt;br /&gt;

&lt;p&gt;要解决这个问题，首先需要在 ~/.ssh/ 目录下新建一个 config 文件，为不同的项目分别指定公钥／私钥&lt;/p&gt;

&lt;h3&gt;~/.ssh/config&lt;/h3&gt;
&lt;pre class=&quot;codes&quot;&gt;&lt;code&gt;Host project-1
    HostName github.com
    User git
    IdentityFile /home/wyt/.ssh/id_rsa_project_1

Host project-2
    HostName github.com
    User git
    IdentityFile /home/wyt/.ssh/id_rsa_project_2
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;

&lt;p&gt;然后用 ssh-keygen 创建对应的公钥／私钥。&lt;/p&gt;

&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ ls -l ~/.ssh&lt;/b&gt;
total 24
-rw-r--r-- 1 wyt wyt  244 2008-06-21 13:18 config
-rw------- 1 wyt wyt 1675 2008-06-21 13:04 id_rsa_project_1
-rw-r--r-- 1 wyt wyt  392 2008-06-21 13:04 id_rsa_project_1.pub
-rw------- 1 wyt wyt 1675 2008-05-20 11:24 id_rsa_project_2
-rw-r--r-- 1 wyt wyt  392 2008-05-20 11:24 id_rsa_project_2.pub
-rw-r--r-- 1 wyt wyt  802 2008-05-24 22:44 known_hosts
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;

&lt;p&gt;将公钥上传到 GitHub 上之后，就可以用下面的指令 clone 相应的软件仓库了&lt;/p&gt;

&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ git clone git@project-1:username/project-1.git
$ git clone git@project-2:username/project-2.git&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;
&lt;br /&gt;

&lt;h3&gt;参考页面&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://alblue.blogspot.com/2005/08/howto-ssh-logins-using-keys.html&quot; title=&quot;[HowTo] SSH logins using keys&quot;&gt;[HowTo] SSH logins using keys&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://github.com/guides/multiple-github-accounts&quot; title=&quot;Multiple GitHub Accounts&quot;&gt;Multiple GitHub Accounts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://logicalawesome.lighthouseapp.com/projects/8570-github/tickets/515-deploying-mulitple-apps-to-the-same-machine-public-key-restrictions#ticket-515-3&quot; title=&quot;Deploying Mulitple Apps to the Same Machine Public Key Restrictions&quot;&gt;Deploying Mulitple Apps to the Same Machine Public Key Restrictions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author xmlns="http://www.w3.org/2005/Atom"><name>wyt</name><uri>http://www.blogger.com/profile/04947921907676762514</uri><email>noreply@blogger.com</email></author><content:encoded>&lt;p&gt;
&lt;a href=&quot;http://github.com&quot; title=&quot;GitHub&quot; rel=&quot;nofollow&quot;&gt;GitHub&lt;/a&gt; 是一个免费的基于 git 的开源软件仓库托管服务，包括 &lt;a href=&quot;http://github.com/rails/rails/tree&quot; rel=&quot;nofollow&quot;&gt;Ruby on Rails&lt;/a&gt;， &lt;a href=&quot;http://github.com/dchelimsky/rspec/tree&quot; rel=&quot;nofollow&quot;&gt;Rspec&lt;/a&gt;，&lt;a href=&quot;http://github.com/sstephenson/prototype/tree&quot; rel=&quot;nofollow&quot;&gt;Prototype&lt;/a&gt; 在内的许多开源软件都在 GitHub 上架设了软件仓库。
&lt;/p&gt;

&lt;br /&gt;

&lt;p&gt;
如果你有两个或两个以上的 GitHub 仓库，并且想用不同的公钥／私钥来管理这些仓库的话，会遇到这样一个问题。当你 clone 第一个仓库的时候，git 会使用第一对公钥／私钥，这个时候仍然一切正常。可当你需要用另一对公钥／私钥来 clone 第二个仓库的时候，git 默认仍然会使用第一对公钥／私钥，然后 GitHub 就会返回一个授权错误。
&lt;/p&gt;

&lt;br /&gt;

&lt;p&gt;要解决这个问题，首先需要在 ~/.ssh/ 目录下新建一个 config 文件，为不同的项目分别指定公钥／私钥&lt;/p&gt;

&lt;h3&gt;~/.ssh/config&lt;/h3&gt;
&lt;pre class=&quot;codes&quot;&gt;&lt;code&gt;Host project-1
    HostName github.com
    User git
    IdentityFile /home/wyt/.ssh/id_rsa_project_1

Host project-2
    HostName github.com
    User git
    IdentityFile /home/wyt/.ssh/id_rsa_project_2
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;

&lt;p&gt;然后用 ssh-keygen 创建对应的公钥／私钥。&lt;/p&gt;

&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ ls -l ~/.ssh&lt;/b&gt;
total 24
-rw-r--r-- 1 wyt wyt  244 2008-06-21 13:18 config
-rw------- 1 wyt wyt 1675 2008-06-21 13:04 id_rsa_project_1
-rw-r--r-- 1 wyt wyt  392 2008-06-21 13:04 id_rsa_project_1.pub
-rw------- 1 wyt wyt 1675 2008-05-20 11:24 id_rsa_project_2
-rw-r--r-- 1 wyt wyt  392 2008-05-20 11:24 id_rsa_project_2.pub
-rw-r--r-- 1 wyt wyt  802 2008-05-24 22:44 known_hosts
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;

&lt;p&gt;将公钥上传到 GitHub 上之后，就可以用下面的指令 clone 相应的软件仓库了&lt;/p&gt;

&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ git clone git@project-1:username/project-1.git
$ git clone git@project-2:username/project-2.git&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;
&lt;br /&gt;

&lt;h3&gt;参考页面&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://alblue.blogspot.com/2005/08/howto-ssh-logins-using-keys.html&quot; title=&quot;[HowTo] SSH logins using keys&quot;&gt;[HowTo] SSH logins using keys&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://github.com/guides/multiple-github-accounts&quot; title=&quot;Multiple GitHub Accounts&quot;&gt;Multiple GitHub Accounts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://logicalawesome.lighthouseapp.com/projects/8570-github/tickets/515-deploying-mulitple-apps-to-the-same-machine-public-key-restrictions#ticket-515-3&quot; title=&quot;Deploying Mulitple Apps to the Same Machine Public Key Restrictions&quot;&gt;Deploying Mulitple Apps to the Same Machine Public Key Restrictions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;&lt;!-- Feedsky flare --&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=e0320990b5089a5095ace7fbef3924e3&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=e0320990b5089a5095ace7fbef3924e3&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=ff6382b59ed7c68aaf3d80d32cd55ae2&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=ff6382b59ed7c68aaf3d80d32cd55ae2&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=94d473ec4b249f3fd3b6f031bc538656&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=94d473ec4b249f3fd3b6f031bc538656&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=a395d34c737562ccb5f283590754391b&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=a395d34c737562ccb5f283590754391b&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;!-- /Feedsky flare --&gt;</content:encoded><category domain="http://www.blogger.com/atom/ns#">linux</category><category domain="http://www.blogger.com/atom/ns#">git</category><pubDate>Sat, 21 Jun 2008 16:36:06 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-7286295415331143255.post-2921259291670305060</guid><dc:creator>wyt</dc:creator><fs:srclink>http://luliban.com/blog/2008/06/github-ssh.html</fs:srclink><fs:srcfeed>http://luliban.com/blog/feeds/atom.xml</fs:srcfeed><fs:itemid>feedsky/luliban/~6996753/87867490/4034731</fs:itemid></item><item><title>有备无患：在 Gentoo 上部署 Git + Gitosis 服务器的笔记</title><link atom:title="有备无患：在 Gentoo 上部署 Git + Gitosis 服务器的笔记" atom:type="text/html">http://item.feedsky.com/~feedsky/luliban/~6996753/87867493/4034731/1/item.html</link><id xmlns="http://www.w3.org/2005/Atom">tag:blogger.com,1999:blog-7286295415331143255.post-6968119548310588834</id><content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;a title=&quot;Git&quot; href=&quot;http://git.or.cz/&quot; rel=&quot;nofollow&quot;&gt;Git&lt;/a&gt; 是 &lt;a rel=&quot;nofollow&quot; href=&quot;http://en.wikipedia.org/wiki/Linus_Torvalds&quot; title=&quot;Linus Torvalds&quot;&gt;Linus Torvalds&lt;/a&gt; 为了帮助管理 Linux 内核开发而开发的分布式版本控制软件（Distributed SCM）。Git 汲取了 Torvalds 在维护大型的分布式项目开发方面的经验和对文件系统性能的丰富知识，正如其文档所描述的，“是一个快速、可扩展的分布式版本控制系统，它具有极为丰富的命令集，对内部系统提供了高级操作和完全访问。”目前，Linux 内核、X.org 服务器和 Ruby on Rails 等开源项目的版本控制系统都已经切换到 Git。&lt;br /&gt;

&lt;br /&gt;

&lt;a rel=&quot;nofollow&quot; title=&quot;Gitosis&quot; href=&quot;http://eagain.net/gitweb/?p=gitosis.git;a=summary&quot;&gt;Gitosis&lt;/a&gt; 是 &lt;a rel=&quot;nofollow&quot; title=&quot;Tommi Virtanen&quot; href=&quot;http://eagain.net/about/&quot;&gt;Tommi Virtanen&lt;/a&gt; 为了更方便和安全的辅助 Git 架设和管理软件版本库 (Software Repository) 而开发的工具软件。虽然 Git 本身也提供 git-daemon 以架设版本库，但在用户访问控制上做的并不严格。而 Gitosis 允许单个用户帐号管理多个版本库，使用 SSH keys 管理用户认证，不需要 shell 帐号就可以解决多用户访问集中版本库的问题。&lt;br /&gt;

&lt;br /&gt;

需要说明的是，我使用的 Gitosis 是 &lt;a rel=&quot;nofollow&quot; title=&quot;robbat2&quot; href=&quot;http://robbat2.livejournal.com/&quot;&gt;robbat2&lt;/a&gt; 为了部署新的 &lt;a rel=&quot;nofollow&quot; title=&quot;Gentoo Overlays&quot; href=&quot;http://git.overlays.gentoo.org/&quot;&gt;Gentoo Overlays&lt;/a&gt; 而开发的 &lt;a rel=&quot;nofollow&quot; title=&quot;Gentoo 分支版本&quot; href=&quot;http://git.overlays.gentoo.org/gitweb/?p=proj/gitosis-gentoo.git&quot;&gt;Gentoo 分支版本&lt;/a&gt; (Gentoo Fork Version)，和上游版本 (Origin Upstream Version) 相比有如下不同：&lt;br /&gt;

&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;支持 git+ssh://HOST/REPO 风格的相对路径；&lt;/li&gt;
&lt;li&gt;支持以命令行参数方式导入 keys，如 &lt;b&gt;gitosis-init --adminkey=FILE --adminname=STRING；&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;智能处理 SSH keys，支持 SSH1 和 SSH2 keys；&lt;/li&gt;
&lt;li&gt;将上游版本默认的目录权限 0750 更改为 0755，以便用 nobody:nobody 运行 git-daemon。&lt;/li&gt;
&lt;/ul&gt;

&lt;br /&gt;
这篇文章详细记录了我在本地安装和部署 Git + Gitosis 的过程和遇到的问题，希望为大家提供一些参考。欢迎 Fix-Me :-)&lt;br /&gt;


&lt;br /&gt;


&lt;h3&gt;安装 Git + Gitosis&lt;/h3&gt;

安装 git 和 gitosis-gentoo。安装完后，Gentoo 会自动添加 git 用户和组，并将版本库的主目录设为 /var/spool/gitosis/repositories。&lt;br /&gt;

&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;# echo &quot;&amp;gt;=dev-util/git-1.5.5&quot; &amp;gt;&amp;gt; /etc/portage/package.keywords
# echo &quot;&amp;gt;=dev-util/gitosis-gentoo-0.2_p20080203&quot; &amp;gt;&amp;gt; /etc/portage/package.keywords
# emerge -av git gitosis-gentoo&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;

如果你的主机上没有装 SSH 的话，还要安装 openssh， 以及 keychain 用来管理 ssh-agents（可选）。&lt;br /&gt;

&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;# emerge -av openssh keychain&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;

安装完后，启动 sshd，并加入默认启动。&lt;br /&gt;

&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;# /etc/init.d/sshd start
# rc-update add sshd default&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;

&lt;h3&gt;配置 Gitosis&lt;/h3&gt;

首先生成一个 ssh key。&lt;br /&gt;

&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ ssh-keygen -t rsa&lt;/b&gt;
Generating public/private rsa key pair.
Enter file in which to save the key (/home/wyt/.ssh/id_rsa):（回车）
Created directory '/home/wyt/.ssh'.
Enter passphrase (empty for no passphrase):（直接回车）
Enter same passphrase again: （直接回车）
Your identification has been saved in /home/wyt/.ssh/id_rsa.
Your public key has been saved in /home/wyt/.ssh/id_rsa.pub.
The key fingerprint is:
dd:33:cc:99:33:00:66:77:ff:00:bb:99:00:22:55:88 wyt@gentoo
&lt;/code&gt;&lt;/pre&gt;


&lt;br /&gt;
我把 ssh key 保存在默认的 ~/.ssh/id_rsa，你也可以选择其他地方。接下来把 id_rsa.pub 上传到服务器。其中的root@gentoo，root 是根用户名，gentoo 是主机名，可以从 /etc/conf.d/hostname 得知。&lt;br /&gt;

&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ cat /etc/conf.d/hostname&lt;/b&gt;
hostname=&quot;gentoo&quot;
&lt;b&gt;$ scp ~/.ssh/id_rsa.pub root@gentoo:&lt;/b&gt;
Password: （输入 root 帐户密码）
id_rsa.pub&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 100%&amp;nbsp; 392&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.4KB/s&amp;nbsp;&amp;nbsp; 00:00&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
上传完毕后，用 gitosis-init 初始化版本库。&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ sudo su -
# sudo -H -u git gitosis-init &amp;lt; ~/id_rsa.pub&lt;/b&gt;
Initialized empty Git repository in ./
Reinitialized existing Git repository in ./
&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;
上面第二条命令中，-u 表示 sudo 将切换至 git 用户，-H 表示 sudo 将切换至该用户的主目录。初始化完成后，将创建一个名为 gitosis-admin 的版本库，用于 Gitosis 的设置和管理。你需要把它 clone 到相应目录。&lt;br /&gt;

&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ mkdir git
$ cd git
$  git clone git@gentoo:gitosis-admin.git
$ cd gitosis-admin
$ ls -lh&lt;/b&gt;
-rw-r--r-- 1 wyt wyt 80 2008-05-19 00:10 gitosis.conf
drwxr-xr-x 2 wyt wyt 80 2008-05-19 00:10 keydir&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
gitosis-admin 目录下有一个 gitosis.conf 文件和一个 keydir 目录。gitosis.conf 用来保存项目，用户和权限等版本库配置，而 keydir 用来保存用户的 ssh key。因为 gitosis-admin 也是 Git 的版本库，所以在修改完配置之后，只需要简单的 commit &amp;amp; push，就可以很快很方便的更新服务器的配置了。接下来就用 Gitosis 创建新版本库和添加授权用户。&lt;br /&gt;

&lt;br /&gt;

&lt;h3&gt;创建新的版本库&lt;/h3&gt;
gitosis.conf 里有 gitosis-admin 的默认配置，只要依样画葫芦创建一个新版本库即可。下面举例创建 local_test 版本库，把下面这段 code 追加到 gitosis.conf。&lt;br /&gt;

&lt;br /&gt;

&lt;h4&gt;gitosis.conf&lt;/h4&gt;
&lt;pre class=&quot;codes&quot;&gt;&lt;code&gt;[group localteam]
writable = local_test
members = wyt@gentoo
&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;

这段 code 定义了新的版本库，包括开发小组的名称 &quot;localteam&quot;，版本库的名称 &quot;local_test&quot;，以及拥有写权限的小组成员 &quot;wyt@gentoo&quot;。接下来把新的版本库所配置 commit &amp;amp; push 到服务器上。&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ git commit -a -m &quot;添加新的版本库 local_test&quot;
$ git push&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
接下来在本地创建版本库，然后将其上传到服务器&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ mkdir local_test
$ cd local_test
$ git init
$ git remote add origin git@gentoo:local_test.git&lt;/b&gt;

# add &amp;amp; commit 一些文件，然后……

&lt;b&gt;$ git push origin master:refs/heads/master&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;

&lt;h3&gt;添加成员用户&lt;/h3&gt;
添加版本库的成员用户的步骤可以分为两步。一是将用户的 SSH 公钥复制到 keydir/ 目录。二是编辑 gitosis.conf，将这些用户的名字加入 &quot;members&quot;。&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ cd gitosis-admin/
$ cp ~/zhangsan@gentoo.pub keydir/
$ cp ~/lisi@gentoo.pub keydir/
$ git add keydir/zhangsan@gentoo.pub keydir/lisi@gentoo.pub&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;

编辑 gitosis.conf&lt;br /&gt;

&lt;br /&gt;
&lt;h4&gt;gitosis.conf&lt;/h4&gt;
&lt;pre class=&quot;codes&quot;&gt;&lt;code&gt;[group localteam]
writable = local_test
members = wyt@gentoo zhangsan@gentoo lisi@gentoo&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
接下来，将设置提交到服务器&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ git commit -a -m '添加 local_test 版本库成员：张三、李四'
$ git push&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;选择需要输出的版本库&lt;/h3&gt;
&lt;br /&gt;
&lt;h4&gt;输出所有版本库&lt;/h4&gt;
编辑 /etc/conf.d/git-daemon&lt;br /&gt;
&lt;pre class=&quot;codes&quot;&gt;&lt;code&gt;GITDAEMON_OPTS=&quot;--syslog --base-path=/var/spool/gitosis/repositories/ --export-all&quot;&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;

&lt;h4&gt;选择输出版本库&lt;/h4&gt;

编辑 /etc/conf.d/git-daemon&lt;br /&gt;

&lt;pre class=&quot;codes&quot;&gt;&lt;code&gt;GITDAEMON_OPTS=&quot;--syslog --base-path=/var/spool/gitosis/repositories/&quot;&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;
然后在每个选择输出的版本库目录中，添加一个 git-daemon-export-ok 文件&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ sudo touch /var/spool/gitosis/repositories/local_test.git/git-daemon-export-ok&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;启动 git-daemon&lt;/h3&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;# /etc/init.d/git-daemon start
# rc-update add git-daemon default&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
如果一切正常的话，我们应该已经大功告成，完成部署 Git + Gitosis 服务器了。现在可以试一下远程 clone。&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ git clone git://169.254.64.95/local_test.git&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;参考链接&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://technicalpickles.com/posts/gitosis-on-gentoo&quot; title=&quot;Gitosis on Gentoo @ Technical Pickles&quot;&gt;Gitosis on Gentoo @ Technical Pickles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://gentoo-wiki.com/Gitosis&quot; title=&quot;Gitosis - Gentoo Linux Wiki&quot;&gt;Gitosis - Gentoo Linux Wiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way&quot; title=&quot;Hosting Git repositories, The Easy (and Secure) Way&quot;&gt;Hosting Git repositories, The Easy (and Secure) Way&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://robbat2.livejournal.com/217665.html&quot; title=&quot;robbat2: Gitosis on Gentoo, important notes&quot;&gt;robbat2: Gitosis on Gentoo, important notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; title=&quot;Git in a Nutshell&quot; href=&quot;http://www.chem.helsinki.fi/%7Ejonas/git_guides/HTML/git_guide/git_guide.html&quot;&gt;Git in a Nutshell&lt;/a&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;2008-05-20 UPDATE&lt;/h4&gt;
clone 只读版本库：&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ git clone git://169.254.64.95/local_test.git&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;

clone 可读写版本库：&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ git clone git+ssh://git@169.254.64.95/local_test.git&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;

创建新的可读写版本库：&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ git remote add origin git+ssh://git@169.254.64.95/new_local_test.git
$ git push origin master:refs/heads/master&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;</content><author xmlns="http://www.w3.org/2005/Atom"><name>wyt</name><uri>http://www.blogger.com/profile/04947921907676762514</uri><email>noreply@blogger.com</email></author><content:encoded>&lt;a title=&quot;Git&quot; href=&quot;http://git.or.cz/&quot; rel=&quot;nofollow&quot;&gt;Git&lt;/a&gt; 是 &lt;a rel=&quot;nofollow&quot; href=&quot;http://en.wikipedia.org/wiki/Linus_Torvalds&quot; title=&quot;Linus Torvalds&quot;&gt;Linus Torvalds&lt;/a&gt; 为了帮助管理 Linux 内核开发而开发的分布式版本控制软件（Distributed SCM）。Git 汲取了 Torvalds 在维护大型的分布式项目开发方面的经验和对文件系统性能的丰富知识，正如其文档所描述的，“是一个快速、可扩展的分布式版本控制系统，它具有极为丰富的命令集，对内部系统提供了高级操作和完全访问。”目前，Linux 内核、X.org 服务器和 Ruby on Rails 等开源项目的版本控制系统都已经切换到 Git。&lt;br /&gt;

&lt;br /&gt;

&lt;a rel=&quot;nofollow&quot; title=&quot;Gitosis&quot; href=&quot;http://eagain.net/gitweb/?p=gitosis.git;a=summary&quot;&gt;Gitosis&lt;/a&gt; 是 &lt;a rel=&quot;nofollow&quot; title=&quot;Tommi Virtanen&quot; href=&quot;http://eagain.net/about/&quot;&gt;Tommi Virtanen&lt;/a&gt; 为了更方便和安全的辅助 Git 架设和管理软件版本库 (Software Repository) 而开发的工具软件。虽然 Git 本身也提供 git-daemon 以架设版本库，但在用户访问控制上做的并不严格。而 Gitosis 允许单个用户帐号管理多个版本库，使用 SSH keys 管理用户认证，不需要 shell 帐号就可以解决多用户访问集中版本库的问题。&lt;br /&gt;

&lt;br /&gt;

需要说明的是，我使用的 Gitosis 是 &lt;a rel=&quot;nofollow&quot; title=&quot;robbat2&quot; href=&quot;http://robbat2.livejournal.com/&quot;&gt;robbat2&lt;/a&gt; 为了部署新的 &lt;a rel=&quot;nofollow&quot; title=&quot;Gentoo Overlays&quot; href=&quot;http://git.overlays.gentoo.org/&quot;&gt;Gentoo Overlays&lt;/a&gt; 而开发的 &lt;a rel=&quot;nofollow&quot; title=&quot;Gentoo 分支版本&quot; href=&quot;http://git.overlays.gentoo.org/gitweb/?p=proj/gitosis-gentoo.git&quot;&gt;Gentoo 分支版本&lt;/a&gt; (Gentoo Fork Version)，和上游版本 (Origin Upstream Version) 相比有如下不同：&lt;br /&gt;

&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;支持 git+ssh://HOST/REPO 风格的相对路径；&lt;/li&gt;
&lt;li&gt;支持以命令行参数方式导入 keys，如 &lt;b&gt;gitosis-init --adminkey=FILE --adminname=STRING；&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;智能处理 SSH keys，支持 SSH1 和 SSH2 keys；&lt;/li&gt;
&lt;li&gt;将上游版本默认的目录权限 0750 更改为 0755，以便用 nobody:nobody 运行 git-daemon。&lt;/li&gt;
&lt;/ul&gt;

&lt;br /&gt;
这篇文章详细记录了我在本地安装和部署 Git + Gitosis 的过程和遇到的问题，希望为大家提供一些参考。欢迎 Fix-Me :-)&lt;br /&gt;


&lt;br /&gt;


&lt;h3&gt;安装 Git + Gitosis&lt;/h3&gt;

安装 git 和 gitosis-gentoo。安装完后，Gentoo 会自动添加 git 用户和组，并将版本库的主目录设为 /var/spool/gitosis/repositories。&lt;br /&gt;

&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;# echo &quot;&amp;gt;=dev-util/git-1.5.5&quot; &amp;gt;&amp;gt; /etc/portage/package.keywords
# echo &quot;&amp;gt;=dev-util/gitosis-gentoo-0.2_p20080203&quot; &amp;gt;&amp;gt; /etc/portage/package.keywords
# emerge -av git gitosis-gentoo&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;

如果你的主机上没有装 SSH 的话，还要安装 openssh， 以及 keychain 用来管理 ssh-agents（可选）。&lt;br /&gt;

&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;# emerge -av openssh keychain&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;

安装完后，启动 sshd，并加入默认启动。&lt;br /&gt;

&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;# /etc/init.d/sshd start
# rc-update add sshd default&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;

&lt;h3&gt;配置 Gitosis&lt;/h3&gt;

首先生成一个 ssh key。&lt;br /&gt;

&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ ssh-keygen -t rsa&lt;/b&gt;
Generating public/private rsa key pair.
Enter file in which to save the key (/home/wyt/.ssh/id_rsa):（回车）
Created directory '/home/wyt/.ssh'.
Enter passphrase (empty for no passphrase):（直接回车）
Enter same passphrase again: （直接回车）
Your identification has been saved in /home/wyt/.ssh/id_rsa.
Your public key has been saved in /home/wyt/.ssh/id_rsa.pub.
The key fingerprint is:
dd:33:cc:99:33:00:66:77:ff:00:bb:99:00:22:55:88 wyt@gentoo
&lt;/code&gt;&lt;/pre&gt;


&lt;br /&gt;
我把 ssh key 保存在默认的 ~/.ssh/id_rsa，你也可以选择其他地方。接下来把 id_rsa.pub 上传到服务器。其中的root@gentoo，root 是根用户名，gentoo 是主机名，可以从 /etc/conf.d/hostname 得知。&lt;br /&gt;

&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ cat /etc/conf.d/hostname&lt;/b&gt;
hostname=&quot;gentoo&quot;
&lt;b&gt;$ scp ~/.ssh/id_rsa.pub root@gentoo:&lt;/b&gt;
Password: （输入 root 帐户密码）
id_rsa.pub&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 100%&amp;nbsp; 392&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.4KB/s&amp;nbsp;&amp;nbsp; 00:00&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
上传完毕后，用 gitosis-init 初始化版本库。&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ sudo su -
# sudo -H -u git gitosis-init &amp;lt; ~/id_rsa.pub&lt;/b&gt;
Initialized empty Git repository in ./
Reinitialized existing Git repository in ./
&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;
上面第二条命令中，-u 表示 sudo 将切换至 git 用户，-H 表示 sudo 将切换至该用户的主目录。初始化完成后，将创建一个名为 gitosis-admin 的版本库，用于 Gitosis 的设置和管理。你需要把它 clone 到相应目录。&lt;br /&gt;

&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ mkdir git
$ cd git
$  git clone git@gentoo:gitosis-admin.git
$ cd gitosis-admin
$ ls -lh&lt;/b&gt;
-rw-r--r-- 1 wyt wyt 80 2008-05-19 00:10 gitosis.conf
drwxr-xr-x 2 wyt wyt 80 2008-05-19 00:10 keydir&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
gitosis-admin 目录下有一个 gitosis.conf 文件和一个 keydir 目录。gitosis.conf 用来保存项目，用户和权限等版本库配置，而 keydir 用来保存用户的 ssh key。因为 gitosis-admin 也是 Git 的版本库，所以在修改完配置之后，只需要简单的 commit &amp;amp; push，就可以很快很方便的更新服务器的配置了。接下来就用 Gitosis 创建新版本库和添加授权用户。&lt;br /&gt;

&lt;br /&gt;

&lt;h3&gt;创建新的版本库&lt;/h3&gt;
gitosis.conf 里有 gitosis-admin 的默认配置，只要依样画葫芦创建一个新版本库即可。下面举例创建 local_test 版本库，把下面这段 code 追加到 gitosis.conf。&lt;br /&gt;

&lt;br /&gt;

&lt;h4&gt;gitosis.conf&lt;/h4&gt;
&lt;pre class=&quot;codes&quot;&gt;&lt;code&gt;[group localteam]
writable = local_test
members = wyt@gentoo
&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;

这段 code 定义了新的版本库，包括开发小组的名称 &quot;localteam&quot;，版本库的名称 &quot;local_test&quot;，以及拥有写权限的小组成员 &quot;wyt@gentoo&quot;。接下来把新的版本库所配置 commit &amp;amp; push 到服务器上。&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ git commit -a -m &quot;添加新的版本库 local_test&quot;
$ git push&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
接下来在本地创建版本库，然后将其上传到服务器&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ mkdir local_test
$ cd local_test
$ git init
$ git remote add origin git@gentoo:local_test.git&lt;/b&gt;

# add &amp;amp; commit 一些文件，然后……

&lt;b&gt;$ git push origin master:refs/heads/master&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;

&lt;h3&gt;添加成员用户&lt;/h3&gt;
添加版本库的成员用户的步骤可以分为两步。一是将用户的 SSH 公钥复制到 keydir/ 目录。二是编辑 gitosis.conf，将这些用户的名字加入 &quot;members&quot;。&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ cd gitosis-admin/
$ cp ~/zhangsan@gentoo.pub keydir/
$ cp ~/lisi@gentoo.pub keydir/
$ git add keydir/zhangsan@gentoo.pub keydir/lisi@gentoo.pub&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;

编辑 gitosis.conf&lt;br /&gt;

&lt;br /&gt;
&lt;h4&gt;gitosis.conf&lt;/h4&gt;
&lt;pre class=&quot;codes&quot;&gt;&lt;code&gt;[group localteam]
writable = local_test
members = wyt@gentoo zhangsan@gentoo lisi@gentoo&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
接下来，将设置提交到服务器&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ git commit -a -m '添加 local_test 版本库成员：张三、李四'
$ git push&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;选择需要输出的版本库&lt;/h3&gt;
&lt;br /&gt;
&lt;h4&gt;输出所有版本库&lt;/h4&gt;
编辑 /etc/conf.d/git-daemon&lt;br /&gt;
&lt;pre class=&quot;codes&quot;&gt;&lt;code&gt;GITDAEMON_OPTS=&quot;--syslog --base-path=/var/spool/gitosis/repositories/ --export-all&quot;&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;

&lt;h4&gt;选择输出版本库&lt;/h4&gt;

编辑 /etc/conf.d/git-daemon&lt;br /&gt;

&lt;pre class=&quot;codes&quot;&gt;&lt;code&gt;GITDAEMON_OPTS=&quot;--syslog --base-path=/var/spool/gitosis/repositories/&quot;&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;
然后在每个选择输出的版本库目录中，添加一个 git-daemon-export-ok 文件&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ sudo touch /var/spool/gitosis/repositories/local_test.git/git-daemon-export-ok&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;启动 git-daemon&lt;/h3&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;# /etc/init.d/git-daemon start
# rc-update add git-daemon default&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
如果一切正常的话，我们应该已经大功告成，完成部署 Git + Gitosis 服务器了。现在可以试一下远程 clone。&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ git clone git://169.254.64.95/local_test.git&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;参考链接&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://technicalpickles.com/posts/gitosis-on-gentoo&quot; title=&quot;Gitosis on Gentoo @ Technical Pickles&quot;&gt;Gitosis on Gentoo @ Technical Pickles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://gentoo-wiki.com/Gitosis&quot; title=&quot;Gitosis - Gentoo Linux Wiki&quot;&gt;Gitosis - Gentoo Linux Wiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way&quot; title=&quot;Hosting Git repositories, The Easy (and Secure) Way&quot;&gt;Hosting Git repositories, The Easy (and Secure) Way&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://robbat2.livejournal.com/217665.html&quot; title=&quot;robbat2: Gitosis on Gentoo, important notes&quot;&gt;robbat2: Gitosis on Gentoo, important notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; title=&quot;Git in a Nutshell&quot; href=&quot;http://www.chem.helsinki.fi/%7Ejonas/git_guides/HTML/git_guide/git_guide.html&quot;&gt;Git in a Nutshell&lt;/a&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;2008-05-20 UPDATE&lt;/h4&gt;
clone 只读版本库：&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ git clone git://169.254.64.95/local_test.git&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;

clone 可读写版本库：&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ git clone git+ssh://git@169.254.64.95/local_test.git&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;

创建新的可读写版本库：&lt;br /&gt;
&lt;pre class=&quot;commands&quot;&gt;&lt;code&gt;&lt;b&gt;$ git remote add origin git+ssh://git@169.254.64.95/new_local_test.git
$ git push origin master:refs/heads/master&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;!-- Feedsky flare --&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=e52abfc8408e60d05b835325298324ac&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=e52abfc8408e60d05b835325298324ac&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=e6838c244370511c4f540cfd01b3a5ff&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=e6838c244370511c4f540cfd01b3a5ff&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=fcd2409921400395ff778e6c3d813464&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=fcd2409921400395ff778e6c3d813464&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=eb8fae2aa29cfd27a5c78aa01c4fde20&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=eb8fae2aa29cfd27a5c78aa01c4fde20&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;!-- /Feedsky flare --&gt;</content:encoded><category domain="http://www.blogger.com/atom/ns#">gentoo</category><category domain="http://www.blogger.com/atom/ns#">linux</category><category domain="http://www.blogger.com/atom/ns#">git</category><pubDate>Sat, 21 Jun 2008 16:31:21 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-7286295415331143255.post-6968119548310588834</guid><dc:creator>wyt</dc:creator><fs:srclink>http://luliban.com/blog/2008/05/gentoo-git-gitosis.html</fs:srclink><fs:srcfeed>http://luliban.com/blog/feeds/atom.xml</fs:srcfeed><fs:itemid>feedsky/luliban/~6996753/87867493/4034731</fs:itemid></item><item><title>悠言悠闲：Firefox 下载日</title><link atom:title="悠言悠闲：Firefox 下载日" atom:type="text/html">http://item.feedsky.com/~feedsky/luliban/~6996753/87867491/4034731/1/item.html</link><id xmlns="http://www.w3.org/2005/Atom">tag:blogger.com,1999:blog-7286295415331143255.post-3876905514274792940</id><content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;a href=&quot;http://www.spreadfirefox.com/en-US/worldrecord&quot; &gt;&lt;img border=&quot;0&quot; alt=&quot;Download Day 2008&quot; title=&quot;Download Day 2008&quot; src=&quot;http://www.spreadfirefox.com/sites/all/themes/spreadfirefox_RCS/images/download-day/buttons/en-US/dday_badge_fox.png&quot; /&gt;&lt;/a&gt;

&lt;p&gt;Firefox 3正式下载时间为北京时间六月十八日凌晨一点。下载日活动届时开始，请在北京时间六月十九日凌晨一点之前下载Firefox 3。&lt;/p&gt;</content><author xmlns="http://www.w3.org/2005/Atom"><name>wyt</name><uri>http://www.blogger.com/profile/04947921907676762514</uri><email>noreply@blogger.com</email></author><content:encoded>&lt;a href=&quot;http://www.spreadfirefox.com/en-US/worldrecord&quot; &gt;&lt;img border=&quot;0&quot; alt=&quot;Download Day 2008&quot; title=&quot;Download Day 2008&quot; src=&quot;http://www.spreadfirefox.com/sites/all/themes/spreadfirefox_RCS/images/download-day/buttons/en-US/dday_badge_fox.png&quot; /&gt;&lt;/a&gt;

&lt;p&gt;Firefox 3正式下载时间为北京时间六月十八日凌晨一点。下载日活动届时开始，请在北京时间六月十九日凌晨一点之前下载Firefox 3。&lt;/p&gt;&lt;br /&gt;&lt;!-- Feedsky flare --&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=ee93c6638992e05565fb5cc0504a8e8a&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=ee93c6638992e05565fb5cc0504a8e8a&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=0e25cf18f274c041aa0df2cb1eb3ff22&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=0e25cf18f274c041aa0df2cb1eb3ff22&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=4d42282ddbdc5bbf2c0a455d2ff68f75&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=4d42282ddbdc5bbf2c0a455d2ff68f75&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=f5731f64352aa48cb914c77674ba364c&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=f5731f64352aa48cb914c77674ba364c&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;!-- /Feedsky flare --&gt;</content:encoded><category domain="http://www.blogger.com/atom/ns#">互联网</category><pubDate>Wed, 18 Jun 2008 00:06:27 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-7286295415331143255.post-3876905514274792940</guid><dc:creator>wyt</dc:creator><fs:srclink>http://luliban.com/blog/2008/06/firefox.html</fs:srclink><fs:srcfeed>http://luliban.com/blog/feeds/atom.xml</fs:srcfeed><fs:itemid>feedsky/luliban/~6996753/87867491/4034731</fs:itemid></item><item><title>有备无患：增强豆瓣收藏对话框的 Greasemonkey 脚本</title><link atom:title="有备无患：增强豆瓣收藏对话框的 Greasemonkey 脚本" atom:type="text/html">http://item.feedsky.com/~feedsky/luliban/~6996753/87867492/4034731/1/item.html</link><id xmlns="http://www.w3.org/2005/Atom">tag:blogger.com,1999:blog-7286295415331143255.post-4964011711521755373</id><content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;p&gt;经常使用 &lt;a href=&quot;http://del.icio.us/&quot; rel=&quot;nofollow&quot;&gt;del.icio.us&lt;/a&gt; 的人，一定也很熟悉 del.icio.us 的跟随键盘输入自动提示标签（Tag Suggest）的功能。它为用户管理大量的标签带来方便，比如不必去费神记忆单词的拼写，避免为同一语义定义多个标签等。这是靠我们的大脑来记忆管理，或者类似&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.douban.com/&quot;&gt;豆瓣&lt;/a&gt;只提供10个最常用的标签，不能做到的。&lt;br /&gt;

&lt;br /&gt;

这个 &lt;a rel=&quot;nofollow&quot; href=&quot;http://addons.mozilla.org/firefox/addon/748&quot;&gt;Greasemonkey&lt;/a&gt; 脚本的主要功能，是为豆瓣收藏对话框提供类似 del.icio.us 的标签提示功能。另外还重新布置了读过／在读／想读等按钮的布局，并添加了删除收藏的按钮。&lt;br /&gt;

&lt;br /&gt;

目前脚本的版本为0.1，欢迎试用。有什么建议或意见，&lt;a href=&quot;http://luliban.com/blog/2008/05/enhanced-douban-collecting-dialog.html#comments&quot;&gt;欢迎留言&lt;/a&gt;:-)&lt;/p&gt;

&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;http://luliban.com/blog/uploaded_images/screenshot-enhanced-douban-collecting-dialog.png&quot; title=&quot;屏幕截图&quot;&gt;&lt;img src=&quot;http://luliban.com/blog/uploaded_images/screenshot-enhanced-douban-collecting-dialog.png&quot; alt=&quot;Screenshot - Enhanced Douban Collecting Dialog&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;br /&gt;

&lt;h3&gt;功能&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;类似 &lt;a href=&quot;http://del.icio.us/&quot; title=&quot;Del.icio.us&quot; rel=&quot;nofollow&quot;&gt;del.icio.us&lt;/a&gt; 的随输入自动提示标签（Tag Suggest）&lt;/li&gt;
&lt;li&gt;重新安排了读过／在读／想读等按钮的布局，保证 UI 路径的一致性&lt;/li&gt;
&lt;li&gt;增加了删除收藏的按钮&lt;/li&gt;
&lt;/ul&gt;

&lt;br /&gt;
&lt;h3&gt;下载&lt;/h3&gt;
&lt;a href=&quot;http://userscripts.org/scripts/show/27345&quot; title=&quot;Enhanced Douban Collecting Dialog&quot;&gt;&lt;img style=&quot;border: none;&quot; src=&quot;http://luliban.com/images/download90.gif&quot; alt=&quot;下载脚本&quot; /&gt;&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;2008-05-31 UPDATE&lt;/h4&gt;
&lt;p&gt;脚本更新至0.2，有下列更新&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;增加了对个人收藏页，标签页，豆瓣猜，TOP250等页面中的收藏对话框的支持&lt;/li&gt;
&lt;li&gt;修正了之前脚本中已知的 BUG&lt;/li&gt;
&lt;/ul&gt;</content><author xmlns="http://www.w3.org/2005/Atom"><name>wyt</name><uri>http://www.blogger.com/profile/04947921907676762514</uri><email>noreply@blogger.com</email></author><content:encoded>&lt;p&gt;经常使用 &lt;a href=&quot;http://del.icio.us/&quot; rel=&quot;nofollow&quot;&gt;del.icio.us&lt;/a&gt; 的人，一定也很熟悉 del.icio.us 的跟随键盘输入自动提示标签（Tag Suggest）的功能。它为用户管理大量的标签带来方便，比如不必去费神记忆单词的拼写，避免为同一语义定义多个标签等。这是靠我们的大脑来记忆管理，或者类似&lt;a rel=&quot;nofollow&quot; href=&quot;http://www.douban.com/&quot;&gt;豆瓣&lt;/a&gt;只提供10个最常用的标签，不能做到的。&lt;br /&gt;

&lt;br /&gt;

这个 &lt;a rel=&quot;nofollow&quot; href=&quot;http://addons.mozilla.org/firefox/addon/748&quot;&gt;Greasemonkey&lt;/a&gt; 脚本的主要功能，是为豆瓣收藏对话框提供类似 del.icio.us 的标签提示功能。另外还重新布置了读过／在读／想读等按钮的布局，并添加了删除收藏的按钮。&lt;br /&gt;

&lt;br /&gt;

目前脚本的版本为0.1，欢迎试用。有什么建议或意见，&lt;a href=&quot;http://luliban.com/blog/2008/05/enhanced-douban-collecting-dialog.html#comments&quot;&gt;欢迎留言&lt;/a&gt;:-)&lt;/p&gt;

&lt;br /&gt;
&lt;div&gt;&lt;a href=&quot;http://luliban.com/blog/uploaded_images/screenshot-enhanced-douban-collecting-dialog.png&quot; title=&quot;屏幕截图&quot;&gt;&lt;img src=&quot;http://luliban.com/blog/uploaded_images/screenshot-enhanced-douban-collecting-dialog.png&quot; alt=&quot;Screenshot - Enhanced Douban Collecting Dialog&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;br /&gt;

&lt;h3&gt;功能&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;类似 &lt;a href=&quot;http://del.icio.us/&quot; title=&quot;Del.icio.us&quot; rel=&quot;nofollow&quot;&gt;del.icio.us&lt;/a&gt; 的随输入自动提示标签（Tag Suggest）&lt;/li&gt;
&lt;li&gt;重新安排了读过／在读／想读等按钮的布局，保证 UI 路径的一致性&lt;/li&gt;
&lt;li&gt;增加了删除收藏的按钮&lt;/li&gt;
&lt;/ul&gt;

&lt;br /&gt;
&lt;h3&gt;下载&lt;/h3&gt;
&lt;a href=&quot;http://userscripts.org/scripts/show/27345&quot; title=&quot;Enhanced Douban Collecting Dialog&quot;&gt;&lt;img style=&quot;border: none;&quot; src=&quot;http://luliban.com/images/download90.gif&quot; alt=&quot;下载脚本&quot; /&gt;&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;2008-05-31 UPDATE&lt;/h4&gt;
&lt;p&gt;脚本更新至0.2，有下列更新&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;增加了对个人收藏页，标签页，豆瓣猜，TOP250等页面中的收藏对话框的支持&lt;/li&gt;
&lt;li&gt;修正了之前脚本中已知的 BUG&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;&lt;!-- Feedsky flare --&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=42386738df62a37d3374fb79fde3fa37&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=42386738df62a37d3374fb79fde3fa37&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=b2431a2e2ce09272e9e402e5b0f70cb7&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=b2431a2e2ce09272e9e402e5b0f70cb7&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=83b78923ce0d5ab7d65ea0455fb46c6c&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=83b78923ce0d5ab7d65ea0455fb46c6c&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=49c54a4e9caae23a9510c0ebdfcdfe9b&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/luliban?i=49c54a4e9caae23a9510c0ebdfcdfe9b&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;!-- /Feedsky flare --&gt;</content:encoded><category domain="http://www.blogger.com/atom/ns#">javascript</category><category domain="http://www.blogger.com/atom/ns#">greasemonkey</category><category domain="http://www.blogger.com/atom/ns#">豆瓣</category><pubDate>Sun, 01 Jun 2008 14:47:35 +0800</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-7286295415331143255.post-4964011711521755373</guid><dc:creator>wyt</dc:creator><fs:srclink>http://luliban.com/blog/2008/05/enhanced-douban-collecting-dialog.html</fs:srclink><fs:srcfeed>http://luliban.com/blog/feeds/atom.xml</fs:srcfeed><fs:itemid>feedsky/luliban/~6996753/87867492/4034731</fs:itemid></item><item><title>有备无患：用 AideRSS + Google Reader 辅助阅读</title><link atom:title="有备无患：用 AideRSS + Google Reader 辅助阅读" atom:type="text/html">http://item.feedsky.com/~feedsky/luliban/~6996753/87867501/4034731/1/item.html</link><id xmlns="http://www.w3.org/2005/Atom">tag:blogger.com,1999:blog-7286295415331143255.post-6970860275498506697</id><content xmlns="http://www.w3.org/2005/Atom" type="html">&lt;p&gt;

前几天我计算出自己的 &lt;a title=&quot;有备无患：怎样评价Feed阅读效率&quot; href=&quot;http://luliban.com/blog/2008/04/feed.html&quot; id=&quot;q6jc&quot;&gt;FRER（Feed 阅读效率评价）&lt;/a&gt;为15.14，这意味着在 Google Reader 读到的大约85%的文章，至少对我来说，是噪声。这里所浪费的时间，虽然不能直接推算，但估计至少有三分之一。为了更有效率的利用这些时间，我尝试用 &lt;a rel=&quot;nofollow&quot; title=&quot;AideRSS + GoogleReader Firefox extension&quot; href=&quot;http://gr.aiderss.com/?downloadsquad&quot; id=&quot;c_g0&quot;&gt;AideRSS 为 Google Reader 设计的 Firefox 扩展&lt;/a&gt;来辅助阅读。&lt;br /&gt;

&lt;br /&gt;

&lt;a rel=&quot;nofollow&quot; title=&quot;AideRSS&quot; href=&quot;http://www.aiderss.com/&quot; id=&quot;n2tn&quot;&gt;AideRSS&lt;/a&gt; 原本是一款在线的 feed 过滤工具。它通过分析 PageRank，文章评论和 Trackback 的数量，以及文章被 del.icio.us 和 Digg 用户收藏的次数等指标，计算出相应的 &lt;a rel=&quot;nofollow&quot; title=&quot;PostRank&quot; href=&quot;http://blog.aiderss.com/faq/#postrank&quot; id=&quot;b8mv&quot;&gt;AideRSS PostRank&lt;/a&gt;（从1.0到10），并以此为用户过滤 feeds 减少信息过载带来的困扰。而 AideRSS 的这个 Firefox 扩展将 PostRank 整合到 Google Reader 中，我们可以在每一篇文章的标题左侧看到相应的 PostRank，在末尾看到相应的评论、Trackback、del.icio.us 和 digg 收藏的具体数目。另外，我们还可根据 PostRank 的高低过滤出 Good，Great 和 Best 的文章来选择阅读。&lt;/p&gt;

&lt;br /&gt;

&lt;div&gt;&lt;a href=&quot;http://luliban.com/blog/uploaded_images/aiderss-screenshot.jpg&quot;&gt;&lt;img id=&quot;j3h2&quot; style=&quot;width: 450px; height: 355px;&quot; src=&quot;http://luliban.com/blog/uploaded_images/aiderss-screenshot-450.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;p&gt;
&lt;b&gt;几天使用下来，AideRSS 确实能提高一些阅读的命中率，特别是在读流量大更新快的 blogs 的时候，比如CrunchGear，LifeHacker 等。另外读那些只输出摘要的 feeds 的时候，比如新闻类的 feeds，del.icio.us 上的 linux tag 等，我也可以根据 PostRank 快速过滤掉一些文章。&lt;/b&gt;&lt;br /&gt;

&lt;br /&gt;

&lt;b&gt;另一方面，AideRSS 对草根 blogs 不会像&lt;a rel=&quot;nofollow&quot; title=&quot;豆瓣九点&quot; href=&quot;http://9.douban.com/&quot;&gt;豆瓣九点&lt;/a&gt;那么“势利眼”——死盯着订阅数不放，不用去担心 PostRank 会不会把草根的声音屏蔽了的问题。&lt;/b&gt;PostRank 的算法中，似乎流量较少的草根们反而更“容易”拿到高 PostRank。举例子来说，我的《&lt;a class=&quot;direct&quot; href=&quot;http://luliban.com/blog/2008/03/bloggerftp.html&quot; title=&quot;有备无患：为Blogger传统模板（FTP发布）添加标签云&quot;&gt;有备无患：为Blogger传统模板（FTP发布）添加标签云&lt;/a&gt;》只有4个 backlink，2条评论和2个 del.icio.us 收藏，被评到8.3分，而 LifeHacker 的《&lt;a rel=&quot;nofollow&quot; href=&quot;http://lifehacker.com/376705/bind-papers-together-without-staples-or-clips&quot; title=&quot;Bind Papers Together Without Staples or Clips [How To]&quot; &gt;Bind Papers Together Without Staples or Clips [How To]&lt;/a&gt;》有39条评论，7次 del.icio.us，5次 digg，却只有5.3分。&lt;br/&gt;

&lt;br/&gt;

虽然 AideRSS + Google Reader Firefox Extension 还在 private beta 阶段，虽然会拖慢 Google Reader 的响应速度（wyt：要通过 AideRSS 的服务器取数据），虽然还和 Firefox 上最流行的扩展之一 GreaseMonkey 有冲突（wyt：AideRSS 另外提供了一个 GM 脚本，实现和扩展同样的功能），它还是值得去试一试。不过，真正的结论还要等几个星期以后，看看我的 FRER 有没有因此而提高了。&lt;/p&gt;</content><author xmlns="http://www.w3.org/2005/Atom"><name>wyt</name><uri>http://www.blogger.com/profile/04947921907676762514</uri><email>noreply@blogger.com</email></author><content:encoded>&lt;p&gt;

前几天我计算出自己的 &lt;a title=&quot;有备无患：怎样评价Feed阅读效率&quot; href=&quot;http://luliban.com/blog/2008/04/feed.html&quot; id=&quot;q6jc&quot;&gt;FRER（Feed 阅读效率评价）&lt;/a&gt;为15.14，这意味着在 Google Reader 读到的大约85%的文章，至少对我来说，是噪声。这里所浪费的时间，虽然不能直接推算，但估计至少有三分之一。为了更有效率的利用这些时间，我尝试用 &lt;a rel=&quot;nofollow&quot; title=&quot;AideRSS + GoogleReader Firefox extension&quot; href=&quot;http://gr.aiderss.com/?downloadsquad&quot; id=&quot;c_g0&quot;&gt;AideRSS 为 Google Reader 设计的 Firefox 扩展&lt;/a&gt;来辅助阅读。&lt;br /&gt;

&lt;br /&gt;

&lt;a rel=&quot;nofollow&quot; title=&quot;AideRSS&quot; href=&quot;http://www.aiderss.com/&quot; id=&quot;n2tn&quot;&gt;AideRSS&lt;/a&gt; 原本是一款在线的 feed 过滤工具。它通过分析 PageRank，文章评论和 Trackback 的数量，以及文章被 del.icio.us 和 Digg 用户收藏的次数等指标，计算出相应的 &lt;a rel=&quot;nofollow&quot; title=&quot;PostRank&quot; href=&quot;http://blog.aiderss.com/faq/#postrank&quot; id=&quot;b8mv&quot;&gt;AideRSS PostRank&lt;/a&gt;（从1.0到10），并以此为用户过滤 feeds 减少信息过载带来的困扰。而 AideRSS 的这个 Firefox 扩展将 PostRank 整合到 Google Reader 中，我们可以在每一篇文章的标题左侧看到相应的 PostRank，在末尾看到相应的评论、Trackback、del.icio.us 和 digg 收藏的具体数目。另外，我们还可根据 PostRank 的高低过滤出 Good，Great 和 Best 的文章来选择阅读。&lt;/p&gt;

&lt;br /&gt;

&lt;div&gt;&lt;a href=&quot;http://luliban.com/blog/uploaded_images/aiderss-screenshot.jpg&quot;&gt;&lt;img id=&quot;j3h2&quot; style=&quot;width: 450px; height: 355px;&quot; src=&quot;http://luliban.com/blog/uploaded_images/aiderss-screenshot-450.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;p&gt;
&lt;b&gt;几天使用下来，AideRSS 确实能提高一些阅读的命中率，特别是在读流量大更新快的 blogs 的时候，比如CrunchGear，LifeHacker 等。另外读那些只输出摘要的 feeds 的时候，比如新闻类的 feeds，del.icio.us 上的 linux tag 等，我也可以根据 PostRank 快速过滤掉一些文章。&lt;/b&gt;&lt;br /&gt;

&lt;br /&gt;

&lt;b&gt;另一方面，AideRSS 对草根 blogs 不会像&lt;a rel=&quot;nofollow&quot; title=&quot;豆瓣九点&quot; href=&quot;http://9.douban.com/&quot;&gt;豆瓣九点&lt;/a&gt;那么“势利眼”——死盯着订阅数不放，不用去担心 PostRank 会不会把草根的声音屏蔽了的问题。&lt;/b&gt;PostRank 的算法中，似乎流量较少的草根们反而更“容易”拿到高 PostRank。举例子来说，我的《&lt;a class=&quot;direct&quot; href=&quot;http://luliban.com/blog/2008/03/bloggerftp.html&quot; title=&quot;有备无患：为Blogger传统模板（FTP发布）添加标签云&quot;&gt;有备无患：为Blogger传统模板（FTP发布）添加标签云&lt;/a&gt;》只有4个 backlink，2条评论和2个 del.icio.us 收藏，被评到8.3分，而 LifeHacker 的《&lt;a rel=&quot;nofollow&quot; href=&quot;http://lifehacker.com/376705/bind-papers-together-without-staples-or-clips&quot; title=&quot;Bind Papers Together Without Staples or Clips [How To]&quot; &gt;Bind Papers Together Without Staples or Clips [How To]&lt;/a&gt;》有39条评论，7次 del.icio.us，5次 digg，却只有5.3分。&lt;br/&gt;

&lt;br/&gt;

虽然 AideRSS + Google Reader Firefox Extension 还在 private beta 阶段，虽然会拖慢 Google Reader 的响应速度（wyt：要通过 AideRSS 的服务器取数据），虽然还和 Firefox 上最流行的扩展之一 GreaseMonkey 有冲突（wyt：AideRSS 另外提供了一个 GM 脚本，实现和扩展同样的功能），它还是值得去试一试。不过，真正的结论还要等几个星期以后，看看我的 FRER 有没有因此而提高了。&lt;/p&gt;&lt;br /&gt;&lt;!-- Feedsky flare --&gt;&lt;a href=&quot;http://feed.feedsky.com/~flare/luliban?a=552c81ffe8909bbbfa2243b9f30c68d5&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://feed.feedsky.com/~flare/lu