<?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>dead fish</title>
	<atom:link href="http://www.thomaskeller.biz/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.thomaskeller.biz/blog</link>
	<description>only dead fish swim with the stream</description>
	<lastBuildDate>Fri, 03 Sep 2010 08:21:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Ich schäme mich</title>
		<link>http://www.thomaskeller.biz/blog/2010/09/03/798/</link>
		<comments>http://www.thomaskeller.biz/blog/2010/09/03/798/#comments</comments>
		<pubDate>Fri, 03 Sep 2010 08:15:55 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[German]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=798</guid>
		<description><![CDATA[Der 58-jährige Slawik C. &#8211; ein Aserbaidschaner, der in seinem Heimatland zur verfolgten armenischen Minderheit gehört &#8211; stirbt in deutscher Abschiebehaft nach 11 Jahren &#8220;Duldung&#8221; durch deutsche Behörden und vorbildlicher Integration in sein Wohnumfeld. Ich schäme mich &#8211; für das Land, in dem ich wohne und in dem ich ein Bürger bin, seit gestern noch [...]]]></description>
			<content:encoded><![CDATA[<p>Der 58-jährige Slawik C. &#8211; ein Aserbaidschaner, der in seinem Heimatland zur verfolgten armenischen Minderheit gehört &#8211; stirbt in deutscher Abschiebehaft nach 11 Jahren &#8220;Duldung&#8221; durch deutsche Behörden und vorbildlicher Integration in sein Wohnumfeld.</p>

<p>Ich schäme mich &#8211; für das Land, in dem ich wohne und in dem ich ein Bürger bin, seit gestern noch mehr als zuvor.</p>

<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="450" height="358" id="playerpanorama547" align="middle">
<param name="allowScriptAccess" value="always" />
<param name="allowFullScreen" value="true" />
<param name="quality" value="high" />
<param name="bgcolor" value="#000000" />
<param name="movie" value="http://www1.ndr.de/flash/mediathek/videoOnDemandPlayer.swf?file=mp4:2010/0902/TV-20100902-2312-4301.hi&#038;img=http://www.ndr.de/regional/zelle100_v-gallery.jpg&#038;len=08:00&#038;breitbild=true" />
<embed src="http://www1.ndr.de/flash/mediathek/videoOnDemandPlayer.swf?file=mp4:2010/0902/TV-20100902-2312-4301.hi&#038;img=http://www.ndr.de/regional/zelle100_v-gallery.jpg&#038;len=08:00&#038;breitbild=true" quality="high" bgcolor="#000000" width="450" height="358" name="player" align="middle" allowScriptAccess="always" allowFullScreen="true" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object></p>

<p>(<a href="http://daserste.ndr.de/panorama/archiv/2010/panoramaabschiebehaft101.html">Quelle</a>, <a href="http://www.haz.de/Hannover/Aus-der-Region/Im-Norden/Langenhagen/Slawik-C.-und-die-Sehnsucht-Deutscher-zu-sein">HAZ-Artikel</a>)</p>

<p>Dies ist für mich ein weiterer Grund, warum ich meine Zukunft auf Dauer nicht mehr in diesem Land sehe.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2010/09/03/798/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ACLs on a jailed ZFS volume with FreeBSD</title>
		<link>http://www.thomaskeller.biz/blog/2010/08/30/acls-on-a-jailed-zfs-volume-with-freebsd/</link>
		<comments>http://www.thomaskeller.biz/blog/2010/08/30/acls-on-a-jailed-zfs-volume-with-freebsd/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 19:52:53 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[Free Software]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=791</guid>
		<description><![CDATA[While setting up a couple of things on the new monotone server, which is bascially a FreeBSD jail on a physical server kindly provided by Lapo Luchini, I stumbled upon a quite basic use case: I needed to give one user group read and write access to files created and modified by another group. On [...]]]></description>
			<content:encoded><![CDATA[<p>While setting up a couple of things on the new monotone server, which is bascially a FreeBSD jail on a physical server kindly provided by Lapo Luchini, I stumbled upon a quite basic use case: I needed to give one user group read and write access to files created and modified by another group.</p>

<p>On a Linux system I&#8217;d have simply enabled POSIX ACLs for the volume and call</p>

<p><pre>
$ setfacl -m d:user:foo:rwx /path/to/directory
$ setfacl -m d:user:bar:rwx /path/to/directory
</pre></p>

<p>and voila, all new files and directories underknees the path would have received the default ACLs with read and write rights for the <code>foo</code> and <code>bar</code> user.</p>

<p>It turns out that on FreeBSD, which gained zfs ACL support in its 8.1 release recently, the call is quite similar &#8211; just that <code>NFSv4</code> ACLs are used instead of <code>POSIX</code> ACLs, which are a bit more powerful (read more on the <a href="http://blogs.sun.com/marks/entry/zfs_acls">topic here</a>):</p>

<p><pre>
$ setfacl -m user:foo:rwxp:fd:allow /path/to/directory
$ setfacl -m user:bar:rwxp:fd:allow /path/to/directory
</pre></p>

<p>Instead of <code>d:</code> for <code>default</code> which is used in the <code>POSIX</code> version, <code>fd</code> is used, which stands for <code>file_inherit</code> and <code>directory_inherit</code> and is exactly what we need. And while <code>POSIX</code> ACLs are add-only, you can either specify <code>:allow</code> or <code>:deny</code> to also explicitely deny access to a user or usergroup. Finally, you might have seen the little <code>p</code> which stands for the <code>append_data</code> right. This was needed for me in one case, so I added it here. It is actually one of many more rights beside the well-known <code>rwx</code> that <code>NFSv4</code> ACLs defines here &#8211; if you&#8217;re curious, just read more on the aforementioned link.</p>

<p>&#8220;So if everything works, what is the point of this blog?&#8221; you might ask. Well, unfortunately it did not all work out so nicely. One thing caused me some headaches which is actually dubbed a feature of FreeBSDs NFSv4 ACL implementation &#8211; namely that the <code>umask</code> (the create mask for new files) is taken into account on file creation, which leads to an unwanted recalculation of the default (inherited) ACLs. So if you have a file foo created by user <code>u1</code> and the ACLs should also give write access to user <code>u2</code>, then you might end up with something like this:</p>

<p><pre>
$ getfacl foo
   # file: foo
   # owner: u1
   # group: users
              user:u1:--x-----------:------:deny
              user:u1:rwxp----------:------:allow
              user:u2:rwxp----------:------:deny
              user:u2:rwxp----------:------:allow
               owner@:--x-----------:------:deny
               owner@:rw-p---A-W-Co-:------:allow
               group@:rwxp----------:------:deny
               group@:--------------:------:allow
            everyone@:rwxp---A-W-Co-:------:deny
            everyone@:------a-R-c--s:------:allow
</pre></p>

<p>The file was created with <code>rw- --- ---</code> (i.e. umask 077) which lead to a :deny rule for user <code>u2</code> and since deny rules take precendence over allow rules, <code>u2</code> gets no access to <code>foo</code>. I contacted the author of FreeBSD&#8217;s NFSv4 ACL implementation, Edward Tomasz Napierała, and thankfully he drawed a way out of the mess:</p>

<blockquote>
Your problem is umask.  When you create a file, ACL entries are inherited,
and then the new ACL is modified according to some (pretty complicated)
rules.  You probably want to disable that, so that entries are simply
inherited, without further messing and adding deny entries.  To do this,
set aclmode=passthrough and aclinherit=passthrough ZFS properties.
</blockquote>

<p>The only downside to this approach is that you cannot change these settings inside the jail, but only from the outside. Luckily, the host part is also under our control, so Lapo remounted the jail volume with the new settings, and voilá, the ACLs now work as expected.</p>

<p>You can learn something new every day.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2010/08/30/acls-on-a-jailed-zfs-volume-with-freebsd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mtn support for indefero got merged</title>
		<link>http://www.thomaskeller.biz/blog/2010/08/27/mtn-support-for-indefero-got-merged/</link>
		<comments>http://www.thomaskeller.biz/blog/2010/08/27/mtn-support-for-indefero-got-merged/#comments</comments>
		<pubDate>Fri, 27 Aug 2010 08:03:03 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[indefero]]></category>
		<category><![CDATA[monotone]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=787</guid>
		<description><![CDATA[It took us quite a while, but Loic d&#8217;Anterroches finally merged my monotone support fork back into indefero. Its expected that the upcoming 1.1 release of indefero is the first release which ships with mtn support. Most of the things I talked about in the earlier blog post have now been implemented, i.e. you are [...]]]></description>
			<content:encoded><![CDATA[<p>It took us quite a while, but Loic d&#8217;Anterroches <a href="http://projects.ceondo.com/p/indefero/source/commit/14d07a22e2a4688d4cd88229aa55ccbeefd61aef/">finally merged</a> my monotone support fork back into <a href="http://www.indefero.net">indefero</a>. Its expected that the upcoming 1.1 release of indefero is the first release which ships with mtn support.</p>

<p>Most of the things I talked about in <a href="http://www.thomaskeller.biz/blog/2010/04/29/monotone-plugin-for-indefero/">the earlier blog post</a> have now been implemented, i.e. you are now able to use remote_stdio to access remote databases or databases behind an usher instance. Furthermore, a forge-level control panel for usher and monotone public key support have been added.</p>

<p>The documentation has also been improved, there is a separate <a href="http://projects.ceondo.com/p/indefero/source/tree/master/doc/readme-monotone.mdtext">README file</a> which lets you get started and the documentation on the <a href="http://projects.ceondo.com/p/indefero/source/tree/master/src/IDF/conf/idf.php-dist">new IDF configuration variables</a> is also exhaustive.</p>

<p>What is kind of missing right now are support scripts for the forge-level setup of monotone. I plan to add these and even more documentation when I set up monotone&#8217;s new home server in the next couple of weeks. Yes, you&#8217;re reading right, monotone gets a different address, a fancier bug tracker and also a nicer revision browser (thanks to indefero) and if everything goes right, we&#8217;ll even offer monotone hosting support for selected projects.</p>

<p>Stay tuned for more updates!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2010/08/27/mtn-support-for-indefero-got-merged/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Monotone options rework</title>
		<link>http://www.thomaskeller.biz/blog/2010/08/21/monotone-options-rework/</link>
		<comments>http://www.thomaskeller.biz/blog/2010/08/21/monotone-options-rework/#comments</comments>
		<pubDate>Sat, 21 Aug 2010 21:59:43 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[monotone]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=774</guid>
		<description><![CDATA[As I promised earlier I&#8217;ll continue my little series of noteworthy changes and additions in the upcoming monotone release. What I&#8217;ll blog about today may sound as if it is merely &#8220;syntactic&#8221; sugar for the command line end user, but serves a greater purpose when its put in perspective: The introduction of overwritable and negatable [...]]]></description>
			<content:encoded><![CDATA[<p>As I promised earlier I&#8217;ll continue my little series of noteworthy changes and additions in the upcoming monotone release. What I&#8217;ll blog about today may sound as if it is merely &#8220;syntactic&#8221; sugar for the command line end user, but serves a greater purpose when its put in perspective: The introduction of overwritable and negatable options.</p>

<p>Lets start with a simple example: monotone creates a special type of certs if a user explicitely calls the <code>suspend</code> command to mark a particular branch &#8211; actually its head revision(s) &#8211; as end-of-life, or uninteresting. This is useful in case a certain feature branch has been merged back into the main branch and the feature branch name should no longer confuse other people. Since monotone cannot physically delete these no longer needed data due to its distributed nature, the internal revision machinery now simply ignores branches and revisions which have these kind of certs and basically hides them from the user, so they aren&#8217;t picked as update candidates when <code>update</code> is called and they also no longer show up in the list of branches (<code>list branches</code>).</p>

<p>Of course people might still want to see at some point of time what suspended branches are actually available, sometimes maybe to revive a dead development line or for other historical purposes. For this use case monotone has a global option <code>--ignore-suspend-certs</code>, which simply deactivates the automatic hiding and all commands behave as if no suspend certs exist at all. So long so good, but there was a nitty gritty use case problem with this (and other similar) functionality:</p>

<p>If a user permanently decided to ignore suspend certs, for example by adding a specific section in his global <code>get_default_command_options</code>, he could not easily deactivate or overwrite this setting again via command line. The same applied to long-running processes, like <code>automate stdio</code>: once a client triggered the list branches command there with the <code>--ignore-suspend-certs</code> option, the client was unable to switch this flag off in case he wanted to query only active branches with the next invocation.</p>

<p>Up until 0.48 only ugly workarounds existed, such as restarting the stdio process, deactivating the loading of hooks or temporarily commenting out the particular section in the lua file, but with the recent merge of the options branch, it became possible. Every revertable, boolean flag gained a corresponding cancel flag, which is most of the time just named <code>--no-&lt;orginal-flag-name-here&gt;</code>:</p>

<p><pre>
$ mtn ls branches --ignore-suspend-certs --no-ignore-suspend-certs
</pre></p>

<p><small>(Can you guess what this command will now actually do? Little hint: The last occurrence counts&#8230;)</small></p>

<p>But as I mentioned above, this is only half of the truth: Not all cancel flags are just prefixed with a &#8220;no-&#8221;, in some cases they also look completly different and in some cases they even made us rename the original option, to keep the flow of the UI syntax and to prevent the invention of ugly pseudo options (or do you think <code>--no-norc</code> is a good name for the cancel option of <code>--norc</code>?).</p>

<p>Before you scream &#8220;Oh my god, will I ever get used to this new options?! You broke monotone for me!&#8221; let me give you a few words of relief:</p>

<ol>
<li>For common options which have been changed or removed, there is a new deprecation functionality which points you at the new option syntax.</li>
<li>monotone&#8217;s inline command help will not only show you the full syntax of the original option, but also of the cancel option name.</li>
<li>Just as partial command names are completed, option names are now completed as well. If a certain prefix has multiple expansions, all possible options are listed with a short description. (For my little example above, the smallest unique prefix for the long `&#8211;ignore-suspend-certs` option is `&#8211;ignore-`, as there is also an option named `&#8211;ignored` available, for a completely different use case though.)</li>
<li>Finally, if you&#8217;re still puzzled by all the new and changed options and general calling syntax and you want a single page which you can just skim / search over for the thing you&#8217;re looking for, I&#8217;m pleased to tell you that the next monotone version will again have a manual page, but this time its auto-generated from the internal command tree and options. Maybe I&#8217;ll tell you a little bit more about this in one of the next blog posts, if not, just try it out with `mtn manpage` as soon as 0.99 hits the streets.</li>
</ol>

<p>I hope we&#8217;ll get a lot of feedback on this for the 0.99 release, as I firmly believe that this overhaul will make the functional and consistent foundations of monotone even stronger.</p>

<p>I also hope that we do not scare too many people away; we did this with purpose for 0.99 and not 1.0 or 1.1, so trust me, we don&#8217;t plan to mess around with the UI to this extent again anytime soon <img src='http://www.thomaskeller.biz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<p>Thanks for reading so far. Your comments are welcome on <a href="irc://irc.oftc.net/#monotone">irc</a> and via <a href="mailto:monotone-users@nongnu.org">mail</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2010/08/21/monotone-options-rework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Search and replace multiple lines across many files</title>
		<link>http://www.thomaskeller.biz/blog/2010/08/11/search-and-replace-multiple-lines-across-many-files/</link>
		<comments>http://www.thomaskeller.biz/blog/2010/08/11/search-and-replace-multiple-lines-across-many-files/#comments</comments>
		<pubDate>Wed, 11 Aug 2010 11:57:10 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=765</guid>
		<description><![CDATA[sed is usually my favourite tool to search and replace things from the command line, but sometimes Perl&#8217;s regexes are far more convenient to use. Recently I found out another reason why Perls -pi -e is superior over plain sed: when you want to change multiple lines in a document! Imagine you have hundreds of [...]]]></description>
			<content:encoded><![CDATA[<p>sed is usually my favourite tool to search and replace things from the command line, but sometimes Perl&#8217;s regexes are far more convenient to use. Recently I found out another reason why Perls <code>-pi -e</code> is superior over plain sed: when you want to change multiple lines in a document!</p>

<p>Imagine you have hundreds of source code files where somebody once had the great idea to add a <strong><em>version</em></strong> property into each class:</p>

<div class="geshi no java"><ol><li class="li1"><div class="de1"><span class="kw2">public</span> <span class="kw2">class</span> Foo</div></li>
<li class="li1"><div class="de1"><span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw2">private</span> <span class="kw2">static</span> <span class="kw2">final</span> <span class="kw3">String</span> ___version___ = <span class="st0">&quot;$Version:$&quot;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; </div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="co1">// other stuff</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#125;</span></div></li></ol></div>

<p>With Perl the line in question is easy to remove:</p>

<div class="geshi no bash"><ol><li class="li1"><div class="de1">$ <span class="kw1">for</span> <span class="kw2">file</span> <span class="kw1">in</span> $<span class="br0">&#40;</span><span class="kw2">find</span> . -name <span class="st0">&quot;*.java&quot;</span><span class="br0">&#41;</span>; <span class="kw1">do</span> \</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">cp</span> <span class="re1">$file</span> <span class="re1">$file</span>.bkp; <span class="kw2">perl</span> -pi -e \</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; <span class="st0">&quot;s/<span class="es0">\s</span>*public.+___version___.+<span class="es0">\n</span>//g&quot;</span> \</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="sy0">&lt;</span> <span class="re1">$file</span>.bkp <span class="sy0">&gt;</span> <span class="re1">$file</span>; <span class="kw2">rm</span> <span class="re1">$file</span>.bkp; <span class="kw1">done</span></div></li></ol></div>

<p>But, there is one problem: Perl processes each line of the file separately when it slurps in the file, which results in unwanted empty lines:</p>

<div class="geshi no java"><ol><li class="li1"><div class="de1"><span class="kw2">public</span> <span class="kw2">class</span> Foo</div></li>
<li class="li1"><div class="de1"><span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; </div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="co1">// other stuff</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#125;</span></div></li></ol></div>

<p>Then I stumbled upon <a href="http://www.debian-administration.org/articles/298">this article</a> and the solution is to set a special input separator to let Perl slurp in the file as a whole:</p>

<div class="geshi no bash"><ol><li class="li1"><div class="de1">$ <span class="kw1">for</span> <span class="kw2">file</span> <span class="kw1">in</span> $<span class="br0">&#40;</span><span class="kw2">find</span> . -name <span class="st0">&quot;*.java&quot;</span><span class="br0">&#41;</span>; <span class="kw1">do</span> \</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="kw2">cp</span> <span class="re1">$file</span> <span class="re1">$file</span>.bkp; <span class="kw2">perl</span> -p0777i -e \</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;<span class="st0">&quot;s/<span class="es0">\s</span>*public.+___version___.+<span class="es0">\n</span>(<span class="es0">\s</span>*<span class="es0">\n</span>)*/<span class="es0">\n</span>/g&quot;</span> \</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp;<span class="sy0">&lt;</span> <span class="re1">$file</span>.bkp <span class="sy0">&gt;</span> <span class="re1">$file</span>; <span class="kw2">rm</span> <span class="re1">$file</span>.bkp; <span class="kw1">done</span></div></li></ol></div>

<p>and voila, we get what we want:</p>

<div class="geshi no java"><ol><li class="li1"><div class="de1"><span class="kw2">public</span> <span class="kw2">class</span> Foo</div></li>
<li class="li1"><div class="de1"><span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="co1">// other stuff</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#125;</span></div></li></ol></div>

<p>Digging a little deeper what <code>-0777</code> actually means leads us to <code>perlrun(1)</code>:</p>

<blockquote>
The special value 00 will cause Perl to slurp files in paragraph mode. The value 0777 will cause Perl to slurp files whole because there is no legal byte with that value.
</blockquote>

<p>Another day saved &#8211; thanks to Perl!</p>

<p>And while we&#8217;re at it, have a look at Rakudo Star, the best Perl 6 compiler which was released just recently. Perl 6 is in my humble opinion one of the well-designed languages I&#8217;ve came across so far, so if you find some time, go over and read the last <a href="http://perl6advent.wordpress.com/2009/12/01/day-1-getting-rakudo/">christmas special</a>, its really worth it!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2010/08/11/search-and-replace-multiple-lines-across-many-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On monotone selectors</title>
		<link>http://www.thomaskeller.biz/blog/2010/08/10/on-monotone-selectors/</link>
		<comments>http://www.thomaskeller.biz/blog/2010/08/10/on-monotone-selectors/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 11:57:13 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Free Software]]></category>
		<category><![CDATA[monotone]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=750</guid>
		<description><![CDATA[This is the first post in a small series of posts which will show off some of the new functionality you can expect in the next major version of monotone. While there is no fixed release date set for it yet, we plan to release it in fall this year. If you look at the [...]]]></description>
			<content:encoded><![CDATA[<p>This is the first post in a small series of posts which will show off some of the new functionality you can expect in the next major version of monotone. While there is no fixed release date set for it yet, we plan to release it in fall this year. If you look at the <a href="http://monotone.ca/wiki/RoadMap/">roadmap</a> you see that most things have already been implemented and merged into mainline, so we&#8217;re definitely on plan <img src='http://www.thomaskeller.biz/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<p>Anyways, lets begin this little series with the selector rewrite Tim merged a couple of weeks ago. Selectors are one of the main concepts in monotone to pick revisions other than by their 40 byte long hash id and are therefor very useful to &#8220;navigate&#8221; between different development lines.</p>

<p>Monotone up until 0.48 knows already many selectors &#8211; you can select revisions by tag, by branch, by author, by custom cert values and so on. Selectors can be combined to calculate the intersection between two single sets, like &#8220;show me all revisions from author &#8216;Jon&#8217; on branch &#8216;my.project&#8217;&#8221; which would essentially look like this:
<pre>$ mtn automate select "a:jon/b:my.project"</pre>
The syntax for these selectors is all nice and simple &#8211; each selector is prefixed with a unique character and multiple selectors are concatenated with a single slash. While these old-style selectors solved many use cases, some however kept unresolved in the past and users from other DVCS like Darcs had a rather hard time figuring out how to accomplish a certain selection in monotone.</p>

<p>A particular good example is &#8220;how can I easily view the changes of a development branch since the last merge point?&#8221;. Up until now you either had to figure out manually the revision of the merge point by looking at the output of log or use some scary construct like the following:
<pre>$ mtn au common_ancestors $(mtn au select h:main.branch) \
    $(mtn au select h:) | mtn au erase_ancestors -@-</pre></p>

<h4>Enter selector functions</h4>

<p>Luckily, you don&#8217;t have to write these things anymore starting from 0.99 onwards. Give the new <em>selector functions</em> a warm applause!
<pre>$ mtn au select "lca(h:main.branch;h:feature.branch)"</pre>
In this example &#8220;lca&#8221; stands for the &#8220;least common ancestors&#8221; function which takes two arguments, i.e. two other selectors. The syntax is extra short in a workspace where an empty head selector <code>h:</code> defaults to the branch recorded in the workspace options, so if you&#8217;re in the <code>feature.branch</code> workspace, just type:
<pre>$ mtn au select "lca(h:main.branch;h:)"</pre>
Quite convenient, eh? This is not only short, but up to five times faster than the above complex command line. Of course the selector can be directly used in a call to diff or log, like so:
<pre>$ mtn diff -r "lca(h:main.branch;h:)"
$ mtn log --to children(lca(h:main.branch;h:))"</pre>
But huh, whats that nested <code>children</code> call you ask? Well, the <code>lca</code> function picks the merge point in the <em>main branch</em> and if the revision graph goes around that, log would otherwise happily log more parents (earlier revisions) on the feature branch. The call to <code>children</code> ensures that we pick the merge revision in the feature branch and therefor really stop logging at this revision.</p>

<h4>Test drive</h4>

<p>There are many more of these selector functions and explaining them all in detail is out of scope here, please have a look at &#8220;composite selectors&#8221; in the <a href="http://monotone.thomaskeller.biz/docbuild/html/Selectors.html#Selectors">nightly built manual</a>.
And if you want to have an early look at this and play around without having to compile it yourself &#8211; at least if you&#8217;re on openSUSE or Fedora &#8211; just download the binaries from <a href="http://monotone.thomaskeller.biz/autobuild/index.php">our nightly builds</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2010/08/10/on-monotone-selectors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL partitioning benchmark</title>
		<link>http://www.thomaskeller.biz/blog/2010/08/04/mysql-partitioning/</link>
		<comments>http://www.thomaskeller.biz/blog/2010/08/04/mysql-partitioning/#comments</comments>
		<pubDate>Wed, 04 Aug 2010 12:41:49 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[Free Software]]></category>
		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=735</guid>
		<description><![CDATA[I had a little research task today at work where I needed to evaluate which MySQL storage engine and technique would be the fastest to retrieve lots of (like millions) log data. I stumbled upon this post which explained the new horizontal partitioning features of MySQL 5.1 and what I read there made me curious [...]]]></description>
			<content:encoded><![CDATA[<p>I had a little research task today at work where I needed to evaluate which MySQL storage engine and technique would be the fastest to retrieve lots of (like millions) log data. I stumbled upon <a href="http://dev.mysql.com/tech-resources/articles/performance-partitioning.html">this post</a> which explained the new horizontal partitioning features of MySQL 5.1 and what I read there made me curious to test it out myself, also because the original author forgot to include a test with a (non-)partitioned, but indexed table.</p>

<p>This is my test setup: Linux 2.6.34, MySQL community server 5.1.46, Intel Pentium D CPU with 3.2GHz, 2GB RAM</p>

<h4>Test MyISAM tables</h4>

<p>The table definitions are copied and adapted from the aforementioned article:</p>

<div class="geshi no sql"><ol><li class="li1"><div class="de1"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> myi_no_part <span class="br0">&#40;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; c1 int <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span>,</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; c2 varchar<span class="br0">&#40;</span><span class="nu0">30</span><span class="br0">&#41;</span> <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span>,</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; c3 date <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#41;</span> engine<span class="sy0">=</span>MyISAM;</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> myi_no_part_index <span class="br0">&#40;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; c1 int <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span>,</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; c2 varchar<span class="br0">&#40;</span><span class="nu0">30</span><span class="br0">&#41;</span> <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span>,</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; c3 date <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span>,</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; <span class="kw1">INDEX</span><span class="br0">&#40;</span>c3<span class="br0">&#41;</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#41;</span> engine<span class="sy0">=</span>MyISAM;</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> myi_part <span class="br0">&#40;</span></div></li>
<li class="li1"><div class="de1">&nbsp; c1 int <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span>,</div></li>
<li class="li1"><div class="de1">&nbsp; c2 varchar<span class="br0">&#40;</span><span class="nu0">30</span><span class="br0">&#41;</span> <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span>,</div></li>
<li class="li1"><div class="de1">&nbsp; c3 date <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#41;</span> PARTITION <span class="kw1">BY</span> RANGE <span class="br0">&#40;</span>year<span class="br0">&#40;</span>c3<span class="br0">&#41;</span><span class="br0">&#41;</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#40;</span>PARTITION p0 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">1995</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p1 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">1996</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p2 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">1997</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p3 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">1998</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p4 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">1999</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p5 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">2000</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p6 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">2001</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p7 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">2002</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p8 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">2003</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p9 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">2004</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p10 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">2010</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p11 <span class="kw1">VALUES</span> LESS THAN MAXVALUE<span class="br0">&#41;</span> </div></li>
<li class="li1"><div class="de1">&nbsp;engine<span class="sy0">=</span>MyISAM;</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> myi_part_index <span class="br0">&#40;</span></div></li>
<li class="li1"><div class="de1">&nbsp; c1 int <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span>,</div></li>
<li class="li1"><div class="de1">&nbsp; c2 varchar<span class="br0">&#40;</span><span class="nu0">30</span><span class="br0">&#41;</span> <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span>,</div></li>
<li class="li1"><div class="de1">&nbsp; c3 date <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span>,</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw1">INDEX</span><span class="br0">&#40;</span>c3<span class="br0">&#41;</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#41;</span> PARTITION <span class="kw1">BY</span> RANGE <span class="br0">&#40;</span>year<span class="br0">&#40;</span>c3<span class="br0">&#41;</span><span class="br0">&#41;</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#40;</span>PARTITION p0 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">1995</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p1 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">1996</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p2 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">1997</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p3 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">1998</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p4 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">1999</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p5 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">2000</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p6 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">2001</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p7 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">2002</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p8 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">2003</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p9 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">2004</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p10 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">2010</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p11 <span class="kw1">VALUES</span> LESS THAN MAXVALUE<span class="br0">&#41;</span> </div></li>
<li class="li1"><div class="de1">&nbsp;engine<span class="sy0">=</span>MyISAM;</div></li></ol></div>

<h4>Test Archive tables</h4>

<p>Since MySQL&#8217;s Archive engine does only support one index which is primarily used for identifying the primary id, I left out the indexed versions for that:</p>

<div class="geshi no sql"><ol><li class="li1"><div class="de1"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> ar_no_part <span class="br0">&#40;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; c1 int <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span>,</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; c2 varchar<span class="br0">&#40;</span><span class="nu0">30</span><span class="br0">&#41;</span> <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span>,</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; c3 date <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#41;</span> engine<span class="sy0">=</span>Archive;</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> ar_part <span class="br0">&#40;</span></div></li>
<li class="li1"><div class="de1">&nbsp; c1 int <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span>,</div></li>
<li class="li1"><div class="de1">&nbsp; c2 varchar<span class="br0">&#40;</span><span class="nu0">30</span><span class="br0">&#41;</span> <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span>,</div></li>
<li class="li1"><div class="de1">&nbsp; c3 date <span class="kw1">DEFAULT</span> <span class="kw1">NULL</span>,</div></li>
<li class="li1"><div class="de1">&nbsp; <span class="kw1">INDEX</span><span class="br0">&#40;</span>c3<span class="br0">&#41;</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#41;</span> PARTITION <span class="kw1">BY</span> RANGE <span class="br0">&#40;</span>year<span class="br0">&#40;</span>c3<span class="br0">&#41;</span><span class="br0">&#41;</span></div></li>
<li class="li1"><div class="de1"><span class="br0">&#40;</span>PARTITION p0 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">1995</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p1 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">1996</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p2 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">1997</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p3 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">1998</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p4 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">1999</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p5 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">2000</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p6 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">2001</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p7 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">2002</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p8 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">2003</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p9 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">2004</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p10 <span class="kw1">VALUES</span> LESS THAN <span class="br0">&#40;</span><span class="nu0">2010</span><span class="br0">&#41;</span>,</div></li>
<li class="li1"><div class="de1">&nbsp;PARTITION p11 <span class="kw1">VALUES</span> LESS THAN MAXVALUE<span class="br0">&#41;</span> </div></li>
<li class="li1"><div class="de1">&nbsp;engine<span class="sy0">=</span>Archive;</div></li></ol></div>

<h4>Test data</h4>

<p>I re-used the procedure to create about 8 million test data records spread randomly over the complete partitioned area and subsequently copied the generated data to the other tables:</p>

<div class="geshi no sql"><ol><li class="li1"><div class="de1">delimiter //</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="kw1">CREATE</span> PROCEDURE load_part_tab<span class="br0">&#40;</span><span class="br0">&#41;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;begin</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; declare v int <span class="kw1">DEFAULT</span> <span class="nu0">0</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while v <span class="sy0">&lt;</span> <span class="nu0">8000000</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; do</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; <span class="kw1">INSERT</span> <span class="kw1">INTO</span> myi_no_part</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; <span class="kw1">VALUES</span> <span class="br0">&#40;</span>v,<span class="st0">&#39;testing partitions&#39;</span>,adddate<span class="br0">&#40;</span><span class="st0">&#39;1995-01-01&#39;</span>,<span class="br0">&#40;</span>rand<span class="br0">&#40;</span>v<span class="br0">&#41;</span>*<span class="nu0">36520</span><span class="br0">&#41;</span> mod <span class="nu0">3652</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; <span class="kw1">SET</span> v <span class="sy0">=</span> v + <span class="nu0">1</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; end while;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;end</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp;//</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">delimiter ;</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">call load_part_tab;</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1"><span class="kw1">INSERT</span> <span class="kw1">INTO</span> myi_no_part_index <span class="kw1">SELECT</span> * <span class="kw1">FROM</span> myi_no_part;</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&#8230;</div></li></ol></div>

<h4>Test query and the results</h4>

<p>I used the same query to retrieve data from all of the tables:</p>

<div class="geshi no sql"><ol><li class="li1"><div class="de1"><span class="kw1">SELECT</span> count<span class="br0">&#40;</span>*<span class="br0">&#41;</span> <span class="kw1">FROM</span> TABLE_NAME </div></li>
<li class="li1"><div class="de1"><span class="kw1">WHERE</span> c3 <span class="sy0">&gt;</span> date <span class="st0">&#39;1995-01-01&#39;</span> <span class="kw1">AND</span> c3 <span class="sy0">&lt;</span> date <span class="st0">&#39;1995-12-31&#39;</span>;</div></li></ol></div>

<p>and these were the results (mean values of several executions):</p>

<table border="1">
<tr>
<th>table</th>
<th>exec time</th>
</tr>
<tr>
<td>`myi_no_part`</td>
<td>~ 6.4s</td>
</tr>
<tr>
<td>`myi_no_part_index`</td>
<td>~ 1.2s</td>
</tr>
<td>`myi_part`</td>
<td><span style="color: green">~ 0.7s</span></td>

<tr>
<td>`myi_part_index`</td>
<td>~ 1.3s</td>
</tr>
<tr>
<td>`ar_no_part`</td>
<td><span style="color: red">~ 10.2s</span></td>
</tr>
<tr>
<td>`ar_part`</td>
<td>~ 1.1s</td>
</tr>
</table>

<p>These results were actually pretty suprising to me, for various reasons:</p>

<ul>
<li>I would not have thought that intelligent partitioning would beat an index on the particular column by saving the hard disk space for the index at the same time (roughly 1/3 of the total data size in this test case).</li>
<li>The values for `myi_no_part` were actually better than expected &#8211; I would have thought that these should be much worse, also if you compare them with the values from the author of the original article.</li>
<li>The archive engine adds actually nothing to the mix, but disadvantages. Maybe my test case is flawed because I &#8220;only&#8221; tested with 8 million rows, but one can clearly see that a partitionated MyISAM table beats a partitionated Archive table by more than 40%, so the usage of the Archive engine gives you no advantages, but only disadvantages, like being not able to delete records or add additional indexes.</li>
<li>Apparently partitioning and indexing the column in question is slightly <em>slower</em> instead of faster, however if one tries to use a subset of a partitioned table (like restricting to <code>where c3 > date '1995-06-01' and c3 < date '1995-08-31'</code>) it <em>is</em> faster - ~0.3s with index vs ~0.7s without index.</code></li>
</ul>

<h4>Conclusion</h4>

<p>MySQL's partitioning is a great new feature in 5.1 and should be used complementary to subtle and wise indexing.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2010/08/04/mysql-partitioning/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New local pre-commit hook in monotone</title>
		<link>http://www.thomaskeller.biz/blog/2010/07/19/new-local-pre-commit-hook-in-monotone/</link>
		<comments>http://www.thomaskeller.biz/blog/2010/07/19/new-local-pre-commit-hook-in-monotone/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 17:13:06 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[monotone]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=724</guid>
		<description><![CDATA[There was only one hook in monotone until now which could be &#8220;reused&#8221; to interact with the commit process and validate the changeset that should be committed, the validate_commit_message hook. But this was a bit clumsy as it was actually designed to validate the commit message (as the name suggests) and not the changeset, thus [...]]]></description>
			<content:encoded><![CDATA[<p>There was only one hook in monotone until now which could be &#8220;reused&#8221; to interact with the commit process and validate the changeset that should be committed, the <code>validate_commit_message</code> hook. But this was a bit clumsy as it was actually designed to validate the commit message (as the name suggests) and not the changeset, thus the hook was called <em>after</em> the commit message was entered in the editor (or was given with <code>--message</code> or <code>--message-file</code>).</p>

<p>Now monotone (from 0.99 onwards) gained a new commit hook which is called before the commit message processing takes place, but after the logic validated the changeset and branch to which it should be committed. Its named simply <code>validate_changes</code> and takes two parameters, the revision to be committed as full text (parsable in the hook via <code>parse_basic_io</code>) as the first and the name of the branch to which the revision should be committed as the second. Just as <code>validate_commit_message</code>, it is expected to return a tupel containing a boolean which denotes if the change is valid or not and an optional string which explains the reason if not and which is displayed to the committer afterwards.</p>

<p>With this new installment, it should feel natural e.g. to create a pre-commit hook which ensures that none of the patched or added sources contains Windows line endings:</p>

<p><pre>
function validate_changes(revdata, branchname)
  local parsed = parse_basic_io(revdata)
  for _,stanza in ipairs(parsed) do
    if stanza.name == "add_file" or
       stanza.name == "patch" then
      local file = stanza.values[1]
      if not guess_binary_file_contents(file) then
        local fp = assert(io.open(file, "r"))
        local contents = fp:read("*all")
        fp:close()
        if string.find(contents, "\r\n") then
          return false, "CRLF detected"
        end
      end
    end
  end
  return true, ""
end
</pre></p>

<p>Unfortunately its not yet possible to call <code>mtn_automate</code>, the lua interface to monotone&#8217;s automation commands, from hooks like this. Then we could have saved the <code>read("*all")</code> call and would only have to scan the output of <code>automate content_diff</code>, which should be a little faster than doing a full string search in lua for bigger files. We, i.e. the monotone devs, are <a href="http://thread.gmane.org/gmane.comp.version-control.monotone.devel/17881">aware of the problem</a> though and will come up with a solution sooner or later.</p>

<p>I hope this new hook will still be useful for some of you until then.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2010/07/19/new-local-pre-commit-hook-in-monotone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mailing list roundup</title>
		<link>http://www.thomaskeller.biz/blog/2010/07/14/mailing-list-roundup/</link>
		<comments>http://www.thomaskeller.biz/blog/2010/07/14/mailing-list-roundup/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 11:31:43 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[monotone]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=722</guid>
		<description><![CDATA[I&#8217;ve just set up a new mailing list specifically for monotone users, who find the (sometimes endless) developer discussions too boring or are annoyed of ticket spam. You can find the new list&#8217;s interface here. The plan is to do basic first level support on this list and move developer-relevant parts via cross-posting over to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just set up a <a href="http://lists.nongnu.org/mailman/listinfo/monotone-users">new mailing list</a> specifically for monotone users, who find the (sometimes endless) developer discussions too boring or are annoyed of ticket spam. You can find the new list&#8217;s interface <a href="http://lists.nongnu.org/mailman/listinfo/monotone-users">here</a>.</p>

<p>The plan is to do basic first level support on this list and move developer-relevant parts via cross-posting over to the old <a href="http://lists.nongnu.org/mailman/listinfo/monotone-devel">monotone-devel</a> list. While I&#8217;m already subscribed to the new list, I encourage a couple of other developers to subscribe there as well, in case I&#8217;m not available.</p>

<p>I also registered monotone-users and the pre-existing one for the <a href="http://lists.nongnu.org/mailman/listinfo/monotone-users">Debian packaging team</a> on Gmane, but it will take a bit more time until they set them up over there, so please be patient.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2010/07/14/mailing-list-roundup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Better late than never</title>
		<link>http://www.thomaskeller.biz/blog/2010/07/08/better-late-than-never/</link>
		<comments>http://www.thomaskeller.biz/blog/2010/07/08/better-late-than-never/#comments</comments>
		<pubDate>Thu, 08 Jul 2010 07:36:44 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[OOXML]]></category>
		<category><![CDATA[Standards]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=714</guid>
		<description><![CDATA[ISO finally revises the voting directives for open standards after the OOXML debacle in 2007 / 2008. One of the changes is that the national bodies should no longer vote with &#8220;Yes, with comments&#8221; if they encounter serious flaws and trust on the ballot resolution meeting to get their issues solved (which evidently did not [...]]]></description>
			<content:encoded><![CDATA[<p>ISO finally revises the voting directives for open standards after the OOXML debacle in 2007 / 2008. One of the changes is that the national bodies should no longer vote with &#8220;Yes, with comments&#8221; if they encounter serious flaws and trust on the ballot resolution meeting to get their issues solved (which evidently did not happen for OOXML), but should vote &#8220;No, with comments&#8221; instead.</p>

<p>Furthermore, if the &#8220;standard&#8221; receives more than 25% disapproval, it should now officially &#8220;be over&#8221; as well &#8211; if these rules would have been applied in the past, OOXML would not be an ISO certified standard as it is unfortunately today.</p>

<blockquote>There are also smaller, less substantial changes.  For example, the dedication to Jan van den Beld, the former head of Ecma, for his “unwavering dedication to the development and evolution of the JTC 1 procedures”, has been removed.   Ironically, both Ecma and Microsoft have indeed made long-term contributions to the evolution of Fast Track in JTC1, but probably not the way they intended.</blockquote>

<p>(<small><a href="http://www.robweir.com/blog/2010/07/iso-iec-jtc1-revises-directives.html">Source</a></small>)</p>

<p>Now the only paragraph I&#8217;m missing in the new rules obviously is a way to revoke a broken standard, but I guess this won&#8217;t happen. Lets just hope that OOXML sinks into insignificance in the next couple of years.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2010/07/08/better-late-than-never/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
