<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Oracle Berkeley DB 中国研发团队的博客 &#187; 程序设计</title>
	<atom:link href="http://www.bdbchina.com/category/%e7%a8%8b%e5%ba%8f%e8%ae%be%e8%ae%a1/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bdbchina.com</link>
	<description>Oracle Berkeley DB 中国研发团队的博客</description>
	<lastBuildDate>Thu, 15 Dec 2011 10:35:52 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Thread Local Storage Platform Issues and Dbstl&#8217;s Solutions</title>
		<link>http://www.bdbchina.com/2009/12/thread-local-storage-platform-issues-and-dbstls-solutions/</link>
		<comments>http://www.bdbchina.com/2009/12/thread-local-storage-platform-issues-and-dbstls-solutions/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 08:12:06 +0000</pubDate>
		<dc:creator>davidzhao</dc:creator>
				<category><![CDATA[Berkeley DB]]></category>
		<category><![CDATA[David Zhao]]></category>
		<category><![CDATA[程序设计]]></category>

		<guid isPermaLink="false">http://www.bdbchina.com/?p=772</guid>
		<description><![CDATA[This article talks about making use of thread local storage on various platforms.]]></description>
			<content:encoded><![CDATA[<p>1. Overview</p>
<p>Thread local storage(tls) is a feature provided by most modern operating<br />
systems(OS) that allow multiple threads within a process to have its own &#8220;global&#8221;<br />
data, but the scope of the &#8220;global&#8221; data is restricted within a thread<br />
itself, i.e. tls variables are thread wide global variables.</p>
<p>TLS can be useful if we want to store global data which are grouped by<br />
threads, each thread only accesses its own piece of data, and have no loss of<br />
concurrency. Without tls, we would have to store such data in a global data<br />
structure (process wide) and use locks to sychronize access to it.</p>
<p><span id="more-772"></span><br />
2. Two Ways to Support TLS</p>
<p>The support to tls feature includes two ways: compiler keyword support and<br />
thread library API support.</p>
<p>2.1 Compiler keyword support:</p>
<p>If we declare an integer variable P a tls variable on Windows, we can do it like<br />
this:</p>
<p>__declspec(thread) int P;</p>
<p>Or if we want to define a static data member S of class C as a tls variable so<br />
that each thread access its own copy of S when it accesses C::S, we will<br />
declare it like this:</p>
<p>class C {<br />
public:<br />
static __declspec(thread) int S;<br />
// The rest follow&#8230;<br />
};</p>
<p>template &lt;typename T&gt;<br />
class CT {<br />
public:<br />
static __declspec(thread) T* ST;<br />
// The rest follow&#8230;<br />
};</p>
<p>And define it like this:</p>
<p>__declspec(thread) int C::S = 0;</p>
<p>template &lt;typename T&gt;<br />
__declspec(thread) T* CT::ST = NULL;</p>
<p>2.2 Portability</p>
<p>Unfortunately, different compilers and OS have different keywords, for MSVC<br />
it is __declspec(thread); for gcc and icpc (intel c++ compiler), it&#8217;s __thread;<br />
and some other compilers like those on HPUX use __declspec(__thread).</p>
<p>So it takes some effort to<br />
write portable tls code that can run on multiple platforms using multiple<br />
compilers &#8212; we need to provide the correct tls keyword for the target<br />
platform and compiler.</p>
<p>A more terrible issue that makes writing such portable code harder is that<br />
in the above CT&lt;T&gt;::ST example, some<br />
compilers like icpc require the tls keyword only appear in the declaration,<br />
if CT&lt;T&gt;::ST&#8217;s definition also has the tls keyword, icpc can&#8217;t build the code.<br />
And having only a tls declaration is enough to make CT&lt;T&gt;::ST a tls variable.<br />
But icpc require tls keyword appear in C::S&#8217;s definition, strange enough.</p>
<p>However, some other compilers like the older ( &lt; 4.0) versions of gcc require<br />
the tls keyword<br />
appear in both the declaration and definition, otherwise although the build<br />
succeeds, the variable CT&lt;T&gt;::ST or C::S is not handled as a tls variable,<br />
thus multiple thread access will have races and result in undefined behaviors;</p>
<p>Newer versions of gcc will take CT&lt;T&gt;::ST and C::S as a tls variable once it&#8217;s<br />
declared as tls, whether or not the definition has tls keywords. This is also<br />
true for icpc if the class is not templated. Since icpc is trying to mimic gcc<br />
as much as possible, I think it&#8217;s icpc&#8217;s bug that it can&#8217;t accept a tls<br />
keyword in CT&lt;T&gt;::ST&#8217;s definition.</p>
<p>A portable implementation in dbstl implementation is to detect appropriate tls declaration and<br />
definition keywords when configuring, using the m4 scripts. We will iterate<br />
through the (&#8220;__declspec(thread)&#8221;, &#8220;__thread&#8221;, &#8220;__declspec(__thread)&#8221;, &#8220;&#8221;)<br />
array for a combination that builds the class C and CT, and exclude the<br />
(&#8220;&#8221;, &#8220;&#8221;) combination of course. Also note that the &#8220;&#8221; must be placed at last<br />
otherwise if the compiler is a older version of gcc, the tls keyword in<br />
definition will be blank, and we will get a non-tls variable instead; when we<br />
apply this technique, we will find icpc end up with no appropriate tls<br />
keyword combinations.</p>
<p>2.3 Thread API Support</p>
<p>Another way to use tls is through thread API. For example, in pthread, we<br />
first create a tls key, then use this key to get/set the thread-specific copy<br />
of the tls variable assocaited with the key for each thread.<br />
We create the tls key via the pthread_key_create call.<br />
And in order to avoid multiple initializations to the same key, we use<br />
pthread_once to make sure the pthread_key_create is called only once.</p>
<p>When we have the tls key, we can call pthread_setspecific to write to this<br />
thread&#8217;s tls variable, or call pthread_getspecific to read this<br />
thread&#8217;s tls variable.</p>
<p>Some platforms only has the thread API support, like Mac OSX; For others if they<br />
don&#8217;t have pthread API, or other thread library that support tls, they will<br />
need to have a tls keyword to support this feature.</p>
<p>2.4 TLS in Dbstl Implementation</p>
<p>In dbstl, we always prepared both choices, and make the choice when<br />
configuring &#8212; if the platform and compiler has tls keyword support, we use it;<br />
otherwise we use pthread tls API; If neither pthread API nor tls keywords<br />
are available, this platform won&#8217;t be able to use dbstl in multiple threads.</p>
<p>See the $(DB)/stl/dbstl_resource_manager.h/cpp for example code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdbchina.com/2009/12/thread-local-storage-platform-issues-and-dbstls-solutions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BDB在大规模云计算等中的应用</title>
		<link>http://www.bdbchina.com/2009/08/bdb%e5%9c%a8%e5%a4%a7%e8%a7%84%e6%a8%a1%e4%ba%91%e8%ae%a1%e7%ae%97%e7%ad%89%e4%b8%ad%e7%9a%84%e5%ba%94%e7%94%a8/</link>
		<comments>http://www.bdbchina.com/2009/08/bdb%e5%9c%a8%e5%a4%a7%e8%a7%84%e6%a8%a1%e4%ba%91%e8%ae%a1%e7%ae%97%e7%ad%89%e4%b8%ad%e7%9a%84%e5%ba%94%e7%94%a8/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 06:25:25 +0000</pubDate>
		<dc:creator>chaohuang</dc:creator>
				<category><![CDATA[Berkeley DB]]></category>
		<category><![CDATA[Berkeley DB JE]]></category>
		<category><![CDATA[Berkeley DB XML]]></category>
		<category><![CDATA[Chao Huang]]></category>
		<category><![CDATA[程序设计]]></category>
		<category><![CDATA[embedded]]></category>

		<guid isPermaLink="false">http://www.bdbchina.com/?p=470</guid>
		<description><![CDATA[
大家好，
像Facebook, linkedin, Google search, twitter等一些大规模分布式的应用上，往往需要部署成千上万的服务器来做集群，要求很高的响应时间和吞吐量，极佳的可扩展性。事实上，在这种分布式场合，传统的关系型数据库就不再合适了。而往往需要的只是一个按主键来访问的key/value 的数据库引擎，并且要求该引擎可以运行在普通硬件上，多平台上。
根据国外的反馈，Berkeley DB在相应场合的部署正越来越热，比如Amazon，Google，EMC等关键性服务上。又比如一些知名的，运行在分布式应用的开源产品上，如MemcacheDB, Project Voldemort, ThruDB, Amazon Dynamo等。
如果，国内有从事相关大规模云计算应用的朋友，欢迎留言。
另外，如果有兴趣从事该方向的朋友，也可以读读Amazon Dynamo的论文： http://www.allthingsdistributed.com/2007/10/amazons_dynamo.html。有问题，欢迎提问。
Berkeley DB 中国开发团队
]]></description>
			<content:encoded><![CDATA[<div class="f14 pr50">
<p>大家好，</p>
<p>像Facebook, linkedin, Google search, twitter等一些大规模分布式的应用上，往往需要部署成千上万的服务器来做集群，要求很高的响应时间和吞吐量，极佳的可扩展性。事实上，在这种分布式场合，传统的关系型数据库就不再合适了。而往往需要的只是一个按主键来访问的key/value 的数据库引擎，并且要求该引擎可以运行在普通硬件上，多平台上。</p>
<p>根据国外的反馈，Berkeley DB在相应场合的部署正越来越热，比如Amazon，Google，EMC等关键性服务上。又比如一些知名的，运行在分布式应用的开源产品上，如MemcacheDB, Project Voldemort, ThruDB, Amazon Dynamo等。</p>
<p>如果，国内有从事相关大规模云计算应用的朋友，欢迎留言。</p>
<p>另外，如果有兴趣从事该方向的朋友，也可以读读Amazon Dynamo的论文： <a href="http://www.allthingsdistributed.com/2007/10/amazons_dynamo.html" target="_blank"><span style="color: #000000;">http://www.allthingsdistributed.com/2007/10/amazons_dynamo.html</span></a>。有问题，欢迎提问。</p>
<p>Berkeley DB 中国开发团队</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.bdbchina.com/2009/08/bdb%e5%9c%a8%e5%a4%a7%e8%a7%84%e6%a8%a1%e4%ba%91%e8%ae%a1%e7%ae%97%e7%ad%89%e4%b8%ad%e7%9a%84%e5%ba%94%e7%94%a8/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>gcc4.4 issues</title>
		<link>http://www.bdbchina.com/2009/07/gcc44-issues/</link>
		<comments>http://www.bdbchina.com/2009/07/gcc44-issues/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 03:06:38 +0000</pubDate>
		<dc:creator>davidzhao</dc:creator>
				<category><![CDATA[Berkeley DB]]></category>
		<category><![CDATA[David Zhao]]></category>
		<category><![CDATA[程序设计]]></category>
		<category><![CDATA[bdb]]></category>
		<category><![CDATA[gcc]]></category>

		<guid isPermaLink="false">http://www.bdbchina.com/?p=346</guid>
		<description><![CDATA[各位读者，很抱歉这篇文章是英文的，我当初做笔记的时候，写成英文了，这样才可以在同事之间交流。 而现在确实没时间翻译过来了，还望大家理解，谢谢！
 
If your code builds well using gcc4.3 and below, it may not build with gcc4.4, which was released in April 2009. 
 
Following are some of the changes that violates c/c++ standard:
 
1. gcc4.4 does not by default #include stdio.h, or stdlib.h, no header files are by default included, all header files of [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: SimSun; color: #333333;" lang="ZH-CN">各位读者，很抱歉这篇文章是英文的，我当初做笔记的时候，写成英文了，这样才可以在同事之间交流。</span></span><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;" lang="ZH-CN"> </span></span><span class="apple-style-span"><span style="font-family: SimSun; color: #333333;" lang="ZH-CN">而现在确实没时间翻译过来了，还望大家理解，谢谢！</span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;"> </span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;">If your code builds well using gcc4.3 and below, it may not build with gcc4.4, which was released in April 2009. </span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;"> </span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;">Following are some of the changes that violates c/c++ standard:</span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;"> </span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;">1. gcc4.4 does not by default #include stdio.h, or stdlib.h, no header files are by default included, all header files of standard c/c++ libraries need to be explicitly included.</span></span></p>
<p><span id="more-346"></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;"> </span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;">2. More warning checks, e.g. if/else partitions. </span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;"> </span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;">This code snippet: </span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;; color: #333333;">if (a)</span></span></p>
<p class="MsoNormal" style="text-indent: 29.25pt;"><span class="apple-style-span"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;; color: #333333;">if (b)</span></span></p>
<p class="MsoNormal" style="text-indent: 29.25pt;"><span class="apple-style-span"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;; color: #333333;"><span> </span><span> </span>do something here;</span></span></p>
<p class="MsoNormal" style="text-indent: 29.25pt;"><span class="apple-style-span"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;; color: #333333;">else</span></span></p>
<p class="MsoNormal" style="text-indent: 29.25pt;"><span class="apple-style-span"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;; color: #333333;"><span> </span><span> </span>do something else here;</span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;; color: #333333;"> </span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;; color: #333333;">The above will cause warnings, instead you need this:</span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;; color: #333333;"> </span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;; color: #333333;">if (a) {</span></span></p>
<p class="MsoNormal" style="text-indent: 29.25pt;"><span class="apple-style-span"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;; color: #333333;">if (b)</span></span></p>
<p class="MsoNormal" style="text-indent: 29.25pt;"><span class="apple-style-span"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;; color: #333333;"><span> </span><span> </span>do something here;</span></span></p>
<p class="MsoNormal" style="text-indent: 29.25pt;"><span class="apple-style-span"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;; color: #333333;">else</span></span></p>
<p class="MsoNormal" style="text-indent: 29.25pt;"><span class="apple-style-span"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;; color: #333333;"><span> </span><span> </span>do something else here;</span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;; color: #333333;">}</span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-size: 10pt; font-family: &quot;Courier New&quot;; color: #333333;"> </span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;">3. Stricter enum checks.</span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;"> </span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;">Basically we can not rely on the rules to evaluate enum members to integers which were true before; we can not use the integer values of enum members, we can only use the literal enum members. For example, we can not use them to compare with integral values, or members of another enum type. We can only compare with other enum members of<span> </span>the same type for equality.</span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;"> </span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;">4. Use standard ansi c++ include</span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;"> </span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;">For C library header files, #include &lt;cstdio&gt;; rather than #include &lt;stdio.h&gt;; </span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;">And also need to &#8220;use namespace std;&#8221; because all C functions are put into the std namespace.</span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;"> </span></span></p>
<p class="MsoNormal"><span class="apple-style-span"><span style="font-family: &quot;Lucida Grande&quot;; color: #333333;">This item is not required now, but since it is standard c++ we should follow it and abandon the old fashion in case some day later our code fails to build with latest c++ compiler.</span></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdbchina.com/2009/07/gcc44-issues/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C++ Template Corner Cases</title>
		<link>http://www.bdbchina.com/2009/07/c-template-corner-cases/</link>
		<comments>http://www.bdbchina.com/2009/07/c-template-corner-cases/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 03:04:19 +0000</pubDate>
		<dc:creator>davidzhao</dc:creator>
				<category><![CDATA[David Zhao]]></category>
		<category><![CDATA[程序设计]]></category>
		<category><![CDATA[c++]]></category>

		<guid isPermaLink="false">http://www.bdbchina.com/?p=344</guid>
		<description><![CDATA[各位读者，很抱歉这篇文章是英文的，我当初做笔记的时候，写成英文了，这样才可以在同事之间交流。而现在确实没时间翻译过来了，还望大家理解，谢谢！
Following are some corner cases of C++ template features. A lot of the text is simply extracted from &#8220;C++ Templates: The Complete Guide&#8221;, with some of my personal understanding. These features are trivial and easily neglected, but you should have some impression to them in case you run into troubles caused by the neglect.
I made [...]]]></description>
			<content:encoded><![CDATA[<p>各位读者，很抱歉这篇文章是英文的，我当初做笔记的时候，写成英文了，这样才可以在同事之间交流。而现在确实没时间翻译过来了，还望大家理解，谢谢！</p>
<p>Following are some corner cases of C++ template features. A lot of the text is simply extracted from &#8220;C++ Templates: The Complete Guide&#8221;, with some of my personal understanding. These features are trivial and easily neglected, but you should have some impression to them in case you run into troubles caused by the neglect.</p>
<p>I made my notes in English, and I don&#8217;t bother to translate them into Chinese, forgive my laziness. <img src='http://www.bdbchina.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>0. use &#8220;typename&#8221; to extract type defined within a type parameter, like this: typename T::iterator itr; otherwise the &#8216;itr&#8217; is treated as a data member of T.</p>
<p>1. zero initialization<br />
When using a var x of type T, we MUST initialize it like this: T x = T(); so that when T is a primitive type, x can also be initialized with 0, or NULL (when T is a pointer type). Of course we must make sure<br />
when T is a class type, it has a default constructor. Simply using T x; can&#8217;t initialize x when T is a primitive type.<span id="more-344"></span></p>
<p>2. .template</p>
<p>The .template Construct<br />
A very similar problem was discovered after the introduction of typename. Consider the following example using the standard bitset type:</p>
<p>template&lt;int N&gt;<br />
void printBitset (std::bitset&lt;N&gt; const&amp; bs)<br />
{<br />
std::cout &lt;&lt; bs.template to_string&lt;char,char_traits&lt;char&gt;,<br />
allocator&lt;char&gt; &gt;();<br />
}<br />
The strange construct in this example is .template. Without that extra use of template, the compiler does not know that the less-than token (&lt;) that follows is not really &#8220;less than&#8221; but the beginning of a template argument list. Note that this is a problem only if the construct before the period depends on a template parameter. In our example, the parameter bs depends on the template parameter N.</p>
<p>3. char star string type at reference type parameter<br />
Suppose we have a string str: char str[32]; The type of &#8217;str&#8217; symbol is &#8220;a char string&#8221; and &#8220;of 32 chars long&#8221;. similarly the literal &#8220;abc&#8221; &#8217;s type is: &#8221; a char string&#8221; and &#8220;of 3 chars long&#8221;,<br />
that is, the &#8220;type&#8221; information consists of both &#8220;base type&#8221;, which is &#8220;char&#8221;, and &#8220;length&#8221;, which is 32 here. So<br />
such a string is of different type to a char* pointer, such as char*p; , a type conversion is done if passing a string literal as argument to a function with char* formal parameter.</p>
<p>template &lt;typename T&gt;<br />
inline T const&amp; max (T const&amp; a, T const&amp; b)<br />
{<br />
return a &lt; b ? b : a;<br />
}</p>
<p>So when we use max(&#8220;abc&#8221;, &#8220;def&#8221;) to call above function, it is OK. but if we use max(&#8220;abc&#8221;, &#8220;defg&#8221;) to call it, it is wrong, because &#8220;abc&#8221; and &#8220;defg&#8221; are of different types &#8212; the length is different. And automatical type conversion is not done for reference types here.</p>
<p>This means that the above array &#8217;str&#8217;, and string literals like &#8220;abc&#8221;, is not of the same type as &#8220;char *pstr;&#8221;, as most people may believe. Actually it takes a conversion to convert &#8217;str&#8217; array or the string literals to a &#8216;char*&#8217; type. However, during template argument deduction array-to-pointer conversion (often called decay) occurs only if the parameter does not have a reference type. Thus we have the above issue. And if we don&#8217;t use reference in above code, like this:<br />
template &lt;typename T&gt;<br />
inline T max (T a, T b)<br />
{<br />
return a &lt; b ? b : a;<br />
}</p>
<p>Both max(&#8220;abc&#8221;, &#8220;def&#8221;) and max(&#8220;abc&#8221;, &#8220;defg&#8221;) can build OK, since a automatic conversion from string literal to char* is done, so finally we have the same type &#8216;char*&#8217; as T.</p>
<p>4. template template types<br />
After reading the whole lot of text in the book, I realized that this is really a very particular feature, too complicated and restricted to use widely.<br />
Though, since it is a very recently added new C++ template feature, it can be used in your configure script to test whether your compiler conforms to<br />
C++ language standard. The piece of code in the book can directly be used in your m4 file for configure to use.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdbchina.com/2009/07/c-template-corner-cases/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Implement Interface Mechanism Using Templates</title>
		<link>http://www.bdbchina.com/2009/04/implement-interface-mechanism-using-templates/</link>
		<comments>http://www.bdbchina.com/2009/04/implement-interface-mechanism-using-templates/#comments</comments>
		<pubDate>Mon, 13 Apr 2009 09:44:55 +0000</pubDate>
		<dc:creator>davidzhao</dc:creator>
				<category><![CDATA[Berkeley DB]]></category>
		<category><![CDATA[David Zhao]]></category>
		<category><![CDATA[程序设计]]></category>

		<guid isPermaLink="false">http://www.bdbchina.com/?p=199</guid>
		<description><![CDATA[In this article I'd like to talk about how to implement the superset of interface mechanism using templates in C++ ---
using C++ templates, you can do a lot better than ordinary interface mechanism.]]></description>
			<content:encoded><![CDATA[<p><em>Sorry the format is poor, I will update it later. Or please see the same article on my blog at baidu which has a better format: http://hi.baidu.com/dazhao_dbblog/blog/item/a1f49efcee4fba1e09244d06.html</em></p>
<p>C++ template is really a powerful gun in the entire C++ artillery. It is an important part of the defining components that make C++ so powerful, yet so difficult to learn. There are many ways you can make mistakes when using C++, or using C++ templates, just like using any other powerful man-made systems. But if you make everything right, you can gain incredible power, flexibility, efficiency, performance, extendability and so on &#8211; anything you dream of in the software engineering world. So it is definitely worthwhile to make the effort to learn C++ well.</p>
<p>In this article I&#8217;d like to talk about how to implement the superset of interface mechanism using templates in C++ by using C++ templates, you can do a lot better than ordinary interface mechanism.<span id="more-199"></span></p>
<p>In C++ we don&#8217;t have an &#8220;interface&#8221; language component like Java, so we use pure abstract class to simulate it, and which is enough for a Java style ordinary interface. But if we use templates, we can gain a superset of  interface functionalities, then you will find how limited and naive the Java interface is.</p>
<p>Ordinary interfaces restrict any type which implements the methods required by an interface A to derive from the interface A, otherwise it is not suitable for the tasks declared to require A even if it has all the required methods, i.e. ability. The interface A is a tag imposed to the two parties of the contract the provider P has to have this tag A &#8212; to be a descendant of A &#8212; in order to work with the consumer T which requires a provider with the abilities defined in A, otherwise even if P has the ability required, it is not suitable and can&#8217;t be used. This is caused by the limitation that T has to express the requirement of abilities in the form of &#8220;You have to be a descendant of A&#8221;.</p>
<p>In Chinese, there is a saying: &#8220;王侯将相，宁有种乎!&#8221;, meaning &#8220;A king is not a king because he is born by a King! (Anyone who can do the king&#8217;s job can be a king!)&#8221; . As said above, P has to be a descendant of A in order to work with T, which is just a vivid example of this unfareness. This unfairness makes it very restricted and limited for software developers in many ways, let&#8217;s see some of them:</p>
<p>1. When you can&#8217;t derive P from the interface A<br />
When P is a written class built into a shared module (.dll, .so files), or for other reasons you will probably meet in any real world project, you just can&#8217;t derive P from A, and you can&#8217;t derive a new class from P in this case either, thus you can&#8217;t use an instance of P to work with T.</p>
<p>But if you are using templates, as long as you define the set of methods required by T in P, and T is also using templates to express the requirement, then you can always use an instance of P to work with an instance of T.</p>
<p>The way T express the requirement &#8220;You must have the set of methods defined in A&#8221; is: don&#8217;t say anything but simply assume the requirement is satisfied. And if not, there will be compiling errors.</p>
<p>Because of this flexibility, you can define methods required by several classes in P, but not adding any interface tags to P, and P will be suitable for all occasions where any subset of P&#8217;s set of methods are required.</p>
<p>2. Primitive types &#8212; technically unable to implement any interface<br />
Primitive types like int, double, char*, etc, can not derive from any interface or class, what if you want an interface to mediate the P and T? This is something I met several months ago.</p>
<p>My use case was: I wanted to do marshal and un-marshal of various types in order to store/retrieve them into/from a database in a consistent way. For each type T, I need a function to return an object&#8217;s size in bytes, a function to marshal an object of T (putting its bytes to store into a chunk of memory), and a function to unmarshal (by filling an object&#8217;s fields with a chunk of memory previously marshaled). The three types of functions all have default behaviors (sizeof operator for size measuring, memcpy for marshal and unmarshal). When no functions are provided, we can fall back to use default behaviors.</p>
<p>The types include primitive types as well as class/struct types, so obviously I can&#8217;t use ordinary interface. But I can do so using templates. Details as follows:</p>
<p>1. Define a TypeTraits&lt;T&gt; class template, make it a singleton.</p>
<p>2. In TypeTraits&lt;T&gt;, the three types of functions can be defined as three types of function pointer:</p>
<p>typedef size_t (*size_func_t)(const T&amp;)<br />
typedef void (*marshal_func_t)(void *dest, const T&amp; src);<br />
typedef void (*unmarshal_func_t)(T&amp;dest, const void*src);</p>
<p>3. Define data members of the three types as well as the get/set functions for the data members.</p>
<p>This way users can assign different functions for different types, or don&#8217;t assign at all but use default behavior if appropriate.</p>
<p>In places using this &#8220;INTERFACE&#8221;, we first check if the needed function is registered, if not, use default behavior, otherwise use the registered function.</p>
<p>This way, all types are well supported.</p>
<p>There are a lot of things we can do with templates very gracefully and easily, I will cover them in later articles.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdbchina.com/2009/04/implement-interface-mechanism-using-templates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DOS仿真阅读器</title>
		<link>http://www.bdbchina.com/2009/03/dos%e4%bb%bf%e7%9c%9f%e9%98%85%e8%af%bb%e5%99%a8/</link>
		<comments>http://www.bdbchina.com/2009/03/dos%e4%bb%bf%e7%9c%9f%e9%98%85%e8%af%bb%e5%99%a8/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 15:30:02 +0000</pubDate>
		<dc:creator>赵汝聪</dc:creator>
				<category><![CDATA[程序设计]]></category>
		<category><![CDATA[赵汝聪]]></category>

		<guid isPermaLink="false">http://www.bdbchina.com/?p=93</guid>
		<description><![CDATA[五年多前做了一个DOS下的电子小说阅读器。一晃五年过去了，几乎忘记了它的存在。上周忽然收到广告邮件：“DOS仿真阅读器做的很不错，现在已经有超过9939人下载过它&#8230;”，才猛然想起这位失散多年的小兄弟。今天下载人数突破了一万，貌似是个值得纪念的日子。虽然比同类大哥Adobe Reader相比实在是可怜巴巴，不过屈指一算，平均每天有五位素昧平生的用户下载，DOS又式微多年，也算是一个不大不小的意外。

先介绍一下我的战友：2002年寒假花400块钱在旧货市场淘到的二手Compaq 486笔记本，屏幕比华硕Eee PC还小，机身比15寸笔记本还壮硕。66MHz CPU，4M内存，250M硬盘(实际没有250M，中间有三四十M的坏块)。屏幕和机身的连接轴已经失效了，需要用一块有机玻璃恭恭敬敬地把它架起来。所幸软驱和并口还是好的，可以凑和着往里面灌东西。
用这么一台老古董，无非是玩玩DOS游戏，看看电子小说。老DOS用户都熟悉知名程序员云风写的一个牛掰的电子小说阅读软件C-View，支持N多的功能。唯一的遗憾就是全屏分行，按行滚动。阅读时眼睛或脖子需要不停地左右往复，实是累坏吾等老汉。

总而言之，看小说还是要那种仿书页样式的，这样才有看书的感觉。看的时候左一页，右一页，看完左页看右页，看完前页看后页&#8230;  可惜寻觅半天，在DOS下还是找不到合适的阅读器。那就只好自己写一个吧，所幸不难。猛蹲一阵图书馆和宿舍，炮制出来一个能工作的程序，从此终于可以用它来安详地看书了。

在华军上的简介(http://www.newhua.com/soft/22394.htm)：
唯一的DOS仿真书页样式阅读器,模拟左右翻页的书页样式。自带中文GB字库，无需汉字系统支持，无需EMS或XMS。硬件级的色彩调整,可由用户设定2 万多种颜色.可设定背景、 字体、页码等页面所有元素颜色。并提供四种调色方案的设定、保存和快速切换。文件选择采用磁盘目录列表选择，并配有预览功能。能打开任意大小的文本文件。

DOS仿真阅读器在电脑里保存了两年，直至05年本科毕业。至于陪伴了我三年的486笔记本，在毕业前夕转让给了师弟，也许现在这个老机器早已停止运转了吧。用它打穿的DOS游戏早已不计其数：大航海时代II、英杰传、炎龙骑士团、波斯王子、三国志IV、轩辕剑II&#8230;&#8230;嗯，又想起了扛着一盒软盘去学校机房拷游戏的时光。
]]></description>
			<content:encoded><![CDATA[<p>五年多前做了一个DOS下的电子小说阅读器。一晃五年过去了，几乎忘记了它的存在。上周忽然收到广告邮件：“DOS仿真阅读器做的很不错，现在已经有超过9939人下载过它&#8230;”，才猛然想起这位失散多年的小兄弟。今天下载人数突破了一万，貌似是个值得纪念的日子。虽然比同类大哥Adobe Reader相比实在是可怜巴巴，不过屈指一算，平均每天有五位素昧平生的用户下载，DOS又式微多年，也算是一个不大不小的意外。<br />
<span id="more-93"></span><br />
先介绍一下我的战友：2002年寒假花400块钱在旧货市场淘到的二手Compaq 486笔记本，屏幕比华硕Eee PC还小，机身比15寸笔记本还壮硕。66MHz CPU，4M内存，250M硬盘(实际没有250M，中间有三四十M的坏块)。屏幕和机身的连接轴已经失效了，需要用一块有机玻璃恭恭敬敬地把它架起来。所幸软驱和并口还是好的，可以凑和着往里面灌东西。</p>
<p>用这么一台老古董，无非是玩玩DOS游戏，看看电子小说。老DOS用户都熟悉知名程序员云风写的一个牛掰的电子小说阅读软件C-View，支持N多的功能。唯一的遗憾就是全屏分行，按行滚动。阅读时眼睛或脖子需要不停地左右往复，实是累坏吾等老汉。</p>
<p><img class="alignnone size-full wp-image-174" title="s1" src="http://www.bdbchina.com/wp-content/uploads/2009/03/s1.png" alt="s1" width="100%" /></p>
<p>总而言之，看小说还是要那种仿书页样式的，这样才有看书的感觉。看的时候左一页，右一页，看完左页看右页，看完前页看后页&#8230;  可惜寻觅半天，在DOS下还是找不到合适的阅读器。那就只好自己写一个吧，所幸不难。猛蹲一阵图书馆和宿舍，炮制出来一个能工作的程序，从此终于可以用它来安详地看书了。</p>
<p><img class="alignnone size-full wp-image-175" title="s2" src="http://www.bdbchina.com/wp-content/uploads/2009/03/s2.png" alt="s2" width="100%" /></p>
<p>在华军上的简介(http://www.newhua.com/soft/22394.htm)：</p>
<p>唯一的DOS仿真书页样式阅读器,模拟左右翻页的书页样式。自带中文GB字库，无需汉字系统支持，无需EMS或XMS。硬件级的色彩调整,可由用户设定2 万多种颜色.可设定背景、 字体、页码等页面所有元素颜色。并提供四种调色方案的设定、保存和快速切换。文件选择采用磁盘目录列表选择，并配有预览功能。能打开任意大小的文本文件。</p>
<p><img class="alignnone size-full wp-image-176" title="s3" src="http://www.bdbchina.com/wp-content/uploads/2009/03/s3.png" alt="s3" width="100%" /></p>
<p>DOS仿真阅读器在电脑里保存了两年，直至05年本科毕业。至于陪伴了我三年的486笔记本，在毕业前夕转让给了师弟，也许现在这个老机器早已停止运转了吧。用它打穿的DOS游戏早已不计其数：大航海时代II、英杰传、炎龙骑士团、波斯王子、三国志IV、轩辕剑II&#8230;&#8230;嗯，又想起了扛着一盒软盘去学校机房拷游戏的时光。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdbchina.com/2009/03/dos%e4%bb%bf%e7%9c%9f%e9%98%85%e8%af%bb%e5%99%a8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>代码规范</title>
		<link>http://www.bdbchina.com/2009/03/%e4%bb%a3%e7%a0%81%e8%a7%84%e8%8c%83/</link>
		<comments>http://www.bdbchina.com/2009/03/%e4%bb%a3%e7%a0%81%e8%a7%84%e8%8c%83/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 10:07:56 +0000</pubDate>
		<dc:creator>chaohuang</dc:creator>
				<category><![CDATA[Chao Huang]]></category>
		<category><![CDATA[程序设计]]></category>

		<guid isPermaLink="false">http://www.bdbchina.com/?p=148</guid>
		<description><![CDATA[没有规矩，不成方圆。有时候发现，读好的开源产品的代码，如Linux、JDK等，其感受如饮美酒，喜不自胜。然而最近读到一些国内客户和大学毕业生的代码，其感觉就像一个头有十个大，对比很强烈。
千里之行，始于足下。越是历久弥香的产品，越是要求严格，也就意味着每一行代码都很讲究。要做出世界一流的软件来，除了要遵循软件项目管理的种种规范（需求、设计、风险、测试等等），对于开发者的编码要求和规范也不少。
我想，在此谈谈我的一点浅见。对于一个合格的开发者而言，其编写每一行代码的时候，大致首先要考虑的地方有：
- 我遵循相关的代码规范了没有？
- 注释写了没有？注释写的简洁明了吗？
- 针对各种异常情况加以判断和处理了吗？
- 安全退出了吗？释放内存没？有没有内存泄漏？

下面分别简单说明一下。
- 我遵循相关的代码规范了没有？
1. 比如，Sun的Java代码规范要求缩进，貌似很多人注意到了。但是按80个字符折行，你注意到了吗？在咱们Berkeley DB Java版做开发甚至还要求每个函数体不超过一屏幕高。有人不理解，为什么？应为，只有这样，在各种屏幕/环境下看到的你的代码样式都是一致的。从而，方便别人审阅你的代码，也方便了自己。
2. 对变量，函数，类等命名时要遵循代码规范。举个反面例子，假设一个项目组成员10人，有人喜欢用getObject()来命名，有人喜欢readObject()，有人倾向retrieveObj()，有人用getInstance()&#8230; 其结局不言而喻。
- 注释写了没有？注释写的简洁明了吗？
举个例子，你要在程序中做排序。你决定实现最简单的冒泡排序。学过计算机的都知道，冒泡排序代价很昂贵，但是若排序的个体数目不大的时候（比如n&#60;10）却用起来不错。所以当你写代码的时候，就应该大致这样写注释：
/**
* We need to sort the elements, since that will allow us to easily index
* into the array. Since the number of elements is expected to be small, it
* is okay to use bubble sort. If the number of elements to be sorted is
* [...]]]></description>
			<content:encoded><![CDATA[<p>没有规矩，不成方圆。有时候发现，读好的开源产品的代码，如Linux、JDK等，其感受如饮美酒，喜不自胜。然而最近读到一些国内客户和大学毕业生的代码，其感觉就像一个头有十个大，对比很强烈。</p>
<p>千里之行，始于足下。越是历久弥香的产品，越是要求严格，也就意味着每一行代码都很讲究。要做出世界一流的软件来，除了要遵循软件项目管理的种种规范（需求、设计、风险、测试等等），对于开发者的编码要求和规范也不少。</p>
<p>我想，在此谈谈我的一点浅见。对于一个合格的开发者而言，其编写每一行代码的时候，大致首先要考虑的地方有：<br />
- 我遵循相关的代码规范了没有？<br />
- 注释写了没有？注释写的简洁明了吗？<br />
- 针对各种异常情况加以判断和处理了吗？<br />
- 安全退出了吗？释放内存没？有没有内存泄漏？<br />
<span id="more-148"></span></p>
<p>下面分别简单说明一下。<br />
- 我遵循相关的代码规范了没有？<br />
1. 比如，Sun的Java代码规范要求缩进，貌似很多人注意到了。但是按80个字符折行，你注意到了吗？在咱们Berkeley DB Java版做开发甚至还要求每个函数体不超过一屏幕高。有人不理解，为什么？应为，只有这样，在各种屏幕/环境下看到的你的代码样式都是一致的。从而，方便别人审阅你的代码，也方便了自己。<br />
2. 对变量，函数，类等命名时要遵循代码规范。举个反面例子，假设一个项目组成员10人，有人喜欢用getObject()来命名，有人喜欢readObject()，有人倾向retrieveObj()，有人用getInstance()&#8230; 其结局不言而喻。</p>
<p>- 注释写了没有？注释写的简洁明了吗？<br />
举个例子，你要在程序中做排序。你决定实现最简单的冒泡排序。学过计算机的都知道，冒泡排序代价很昂贵，但是若排序的个体数目不大的时候（比如n&lt;10）却用起来不错。所以当你写代码的时候，就应该大致这样写注释：<br />
/**<br />
* We need to sort the elements, since that will allow us to easily index<br />
* into the array. Since the number of elements is expected to be small, it<br />
* is okay to use bubble sort. If the number of elements to be sorted is<br />
* significant, then it would be appropriate to use a more efficient<br />
* sorting algorithm.<br />
*/</p>
<p>- 针对各种异常情况加以判断和处理了吗？<br />
假设有个功能模块，接受从输入流传过来的数据。在理想情况下，预期输入的可能是用户姓名，格式化的：（First, Middle, Last）。那么，我想程序开发者在实现这个功能的时候，应该考虑到，传过来的可能是西文字符集，中文字符集。同样，也有可能是不规则的姓名（First, Last, Middle），空，数字，超出越界（假设每个名字不超过128个字符）。当然，也有可能是内存地址（引用），二进制照片，不可见字符等等。该功能要robust，种种情况都应该要考虑到。</p>
<p>当然，这只是一个输入检查的情况。在程序运行时刻，还有可能遇到内存不够，并发读写等等情况。</p>
<p>- 安全退出了吗？释放内存没？有没有内存泄漏？<br />
安全退出了吗？是的，返回正确退出的信号量了。释放变量了吗？貌似也做了。是吗？接受Ctrl+c吗，结果是什么？</p>
<p>有时候，程序运行几天甚至更久，显示内存不够了，程序自动停止下来。是内存泄漏吗，怎么办？</p>
<p>Java 开发者发现，即便有Java提供的内存回收机制，有很多程序也有内存泄漏，最后导致生产环境应用down掉。</p>
<p>我个人认为：遵循一些编码规范，多测试，多积累经验，不断优化你的code是个不错的建议。</p>
<p>先写到这里, 欢迎有体会或者有兴趣的朋友和我交流哦&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdbchina.com/2009/03/%e4%bb%a3%e7%a0%81%e8%a7%84%e8%8c%83/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>数据库参考书</title>
		<link>http://www.bdbchina.com/2009/03/%e6%95%b0%e6%8d%ae%e5%ba%93%e5%8f%82%e8%80%83%e4%b9%a6/</link>
		<comments>http://www.bdbchina.com/2009/03/%e6%95%b0%e6%8d%ae%e5%ba%93%e5%8f%82%e8%80%83%e4%b9%a6/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 08:30:17 +0000</pubDate>
		<dc:creator>chaohuang</dc:creator>
				<category><![CDATA[Chao Huang]]></category>
		<category><![CDATA[程序设计]]></category>

		<guid isPermaLink="false">http://www.bdbchina.com/?p=145</guid>
		<description><![CDATA[给有志于数据库内核开发的朋友的参考书：
* Stanford大学教授Hector Garcia-Molina同志的书，比如prentice Hall出版的“Database System Implementation”。（Hector Garcia-Molina同志也是Oracle公司顾问团成员之一。)
* 数据库权威Jim Grey的书，比如“Transaction Processing: Concepts and Techniques”。
学习初期，可以考虑研究如下方向：
a) b-tree indexing
b) hash indexing (Linear hashing in particular)
c) logging and recovery
d) buffer management
e) concurrency control and locking
]]></description>
			<content:encoded><![CDATA[<p>给有志于数据库内核开发的朋友的参考书：</p>
<p>* Stanford大学教授Hector Garcia-Molina同志的书，比如prentice Hall出版的“Database System Implementation”。（Hector Garcia-Molina同志也是Oracle公司顾问团成员之一。)</p>
<p>* 数据库权威Jim Grey的书，比如“Transaction Processing: Concepts and Techniques”。</p>
<p><span id="more-145"></span>学习初期，可以考虑研究如下方向：</p>
<p>a) b-tree indexing<br />
b) hash indexing (Linear hashing in particular)<br />
c) logging and recovery<br />
d) buffer management<br />
e) concurrency control and locking</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdbchina.com/2009/03/%e6%95%b0%e6%8d%ae%e5%ba%93%e5%8f%82%e8%80%83%e4%b9%a6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XqUSEme &#8211; 基于XQuery/BDBXML的Firefox Add-on</title>
		<link>http://www.bdbchina.com/2009/03/xquseme-%e5%9f%ba%e4%ba%8exquerybdbxml%e7%9a%84firefox-add-on/</link>
		<comments>http://www.bdbchina.com/2009/03/xquseme-%e5%9f%ba%e4%ba%8exquerybdbxml%e7%9a%84firefox-add-on/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 07:56:13 +0000</pubDate>
		<dc:creator>chaohuang</dc:creator>
				<category><![CDATA[Berkeley DB XML]]></category>
		<category><![CDATA[Chao Huang]]></category>
		<category><![CDATA[程序设计]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://www.bdbchina.com/?p=139</guid>
		<description><![CDATA[Berkeley DB 开源社区的Brett Zamir基于XQuery/BDBXML做了一个Firefox的Add-on， 叫XqUSEme （https://addons.mozilla.org/en-US/firefox/addon/5515）。感兴趣的同学可以下载试试。
Brett Zamir在创建XqUSEme初期与Berkeley DB开发工程师的讨论在： http://forums.oracle.com/forums/thread.jspa?messageID=2239564。
有心的朋友，不知道有考虑过智能手机+浏览器+BDBXML的组合吗？欢迎和我讨论。
]]></description>
			<content:encoded><![CDATA[<p>Berkeley DB 开源社区的Brett Zamir基于XQuery/BDBXML做了一个Firefox的Add-on， 叫XqUSEme （<a href="https://addons.mozilla.org/en-US/firefox/addon/5515" target="_blank">https://addons.mozilla.org/en-US/firefox/addon/5515</a>）。感兴趣的同学可以下载试试。</p>
<p>Brett Zamir在创建XqUSEme初期与Berkeley DB开发工程师的讨论在： <a href="http://forums.oracle.com/forums/thread.jspa?messageID=2239564" target="_blank">http://forums.oracle.com/forums/thread.jspa?messageID=2239564</a>。</p>
<p>有心的朋友，不知道有考虑过智能手机+浏览器+BDBXML的组合吗？欢迎和我讨论。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdbchina.com/2009/03/xquseme-%e5%9f%ba%e4%ba%8exquerybdbxml%e7%9a%84firefox-add-on/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>利用stderr创建空白文本文件</title>
		<link>http://www.bdbchina.com/2009/03/%e5%88%a9%e7%94%a8stderr%e5%88%9b%e5%bb%ba%e7%a9%ba%e7%99%bd%e6%96%87%e6%9c%ac%e6%96%87%e4%bb%b6/</link>
		<comments>http://www.bdbchina.com/2009/03/%e5%88%a9%e7%94%a8stderr%e5%88%9b%e5%bb%ba%e7%a9%ba%e7%99%bd%e6%96%87%e6%9c%ac%e6%96%87%e4%bb%b6/#comments</comments>
		<pubDate>Tue, 03 Mar 2009 10:29:58 +0000</pubDate>
		<dc:creator>赵汝聪</dc:creator>
				<category><![CDATA[程序设计]]></category>
		<category><![CDATA[赵汝聪]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://www.bdbchina.com/?p=135</guid>
		<description><![CDATA[在Windows脚本里面创建空白文本文件真是困难重重。采用 echo &#62;tmp.txt是不行的，因为echo会可耻地输出&#8221;echo on&#8221;。再试试&#8221;echo off&#8221;+&#8221;echo on&#8221;的组合拳？依然毫无效果。猛然惊觉系统还有闲置的一条康庄大道stderr，使用之：
echo 2&#62; tmp.txt
stderr没有任何输出，自然产生一个空白文本文件。整个世界清静了&#8230;
]]></description>
			<content:encoded><![CDATA[<p>在Windows脚本里面创建空白文本文件真是困难重重。采用 echo &gt;tmp.txt是不行的，因为echo会可耻地输出&#8221;echo on&#8221;。再试试&#8221;echo off&#8221;+&#8221;echo on&#8221;的组合拳？依然毫无效果。猛然惊觉系统还有闲置的一条康庄大道stderr，使用之：</p>
<p>echo 2&gt; tmp.txt</p>
<p>stderr没有任何输出，自然产生一个空白文本文件。整个世界清静了&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdbchina.com/2009/03/%e5%88%a9%e7%94%a8stderr%e5%88%9b%e5%bb%ba%e7%a9%ba%e7%99%bd%e6%96%87%e6%9c%ac%e6%96%87%e4%bb%b6/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
Դ
