<?xml version="1.0"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">

<channel>
	<title>Openismus Blogs</title>
	<link>http://www.openismus.com</link>
	<language>en</language>
	<description>Openismus Blogs - http://www.openismus.com</description>

<item>
	<title>Murray Cumming: gtkmm 3.8</title>
	<guid>http://www.murrayc.com/?p=1905</guid>
	<link>http://www.murrayc.com/permalink/2013/05/07/gtkmm-3-8/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=gtkmm-3-8</link>
	<description>&lt;!-- AdSense Now! V3.23 --&gt;
&lt;!-- Post[count: 2] --&gt;
&lt;div class=&quot;adsense adsense-leadin&quot;&gt;&lt;!--
google_ad_client = &quot;ca-pub-7781900730613488&quot;;
/* murrayc.com */
google_ad_slot = &quot;2470604810&quot;;
google_ad_width = 160;
google_ad_height = 600;
//--&gt;
&lt;/div&gt;&lt;p&gt;I didn&amp;#8217;t get around to blogging about gtkmm 3.8 when I released it last month, partly because we had to fix a crasher bug and do a gtkmm .1 release before people noticed.&lt;/p&gt;
&lt;p&gt;Anyway, just a little while after GNOME 3.8 was released, we managed to release &lt;a href=&quot;https://mail.gnome.org/archives/gnome-announce-list/2013-April/msg00012.html&quot;&gt;gtkmm 3.8&lt;/a&gt; and &lt;a href=&quot;https://mail.gnome.org/archives/gnome-announce-list/2013-April/msg00026.html&quot;&gt;glibmm 2.36&lt;/a&gt;. There is quite a bit of work in these, almost all by José Alburquerque and Kjell Ahlstedt, as well as the usual few days of last-minute work by me to wrap remaining new API.&lt;/p&gt;
&lt;p&gt;I spend very little time on glibmm and gtkmm these days, and don&amp;#8217;t have much motivation to change that.&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s also a change that we expect in glib 2.38 that will &lt;a href=&quot;https://bugzilla.gnome.org/show_bug.cgi?id=697229&quot;&gt;break&lt;/a&gt; many installed applications that use gtkmm. We successfully begged the glib developers to add a special case for us in glib 2.36, but we have not found any way to avoid this for 2.38. So far our best option seems to be to do a new parallel-installed gtkmm (and glibmm) ABI, leaving the old (broken with glib 2.38) one behind, at least allowing applications to be changed slightly and then rebuilt.&lt;/p&gt;
&lt;p&gt;Personally, I have no great incentive to go through that pain.&lt;/p&gt;</description>
	<pubDate>Tue, 07 May 2013 13:49:15 +0000</pubDate>
</item>
<item>
	<title>Jens Georg: DLNA, client side</title>
	<guid>http://jensge.org/?p=857</guid>
	<link>http://jensge.org/2013/04/dlna-client-side/</link>
	<description>&lt;p&gt;While we were busy fixing the server and rendering side of DLNA with &lt;a href=&quot;http://rygel-project.org&quot; target=&quot;_blank&quot;&gt;Rygel&lt;/a&gt;, the guys at Intel OTC are fixing the Client side of DLNA with something called &lt;a href=&quot;https://01.org/dleyna/&quot; target=&quot;_blank&quot;&gt;dLeyna&lt;/a&gt;, a nice set of APIs to access and maipulate UPnP-AV and DLNA servers / renderers (such as Rygel, of course), so you can easily add DLNA support to your applications, including the obvious server browsing and render remote control, but also the more non-obvious like media pushing, synchronization, server-side playlists. They already prepared a cool set of demos (for example a &lt;a href=&quot;https://github.com/01org/telerender&quot; target=&quot;_blank&quot;&gt;Firefox extension&lt;/a&gt; to send images from your browser to your TV).&lt;/p&gt;
&lt;p&gt;So why is this better than using &lt;a href=&quot;http://gupnp.ogr&quot; target=&quot;_blank&quot;&gt;GUPnP&lt;/a&gt; for this? Let me show you some examples.&lt;/p&gt;
&lt;h2&gt;Controlling a renderer&lt;/h2&gt;
&lt;p&gt;Not much code to see here, you get the usual suspects of player control functions such as start, stop, etc. as well as methods to query device&amp;#8217;s capabilities as there are a lot of optional things on UPnP devices.&lt;/p&gt;
&lt;h2&gt;Uploading&lt;/h2&gt;
&lt;p&gt;Well, say you want to upload a file to a server. The &lt;a href=&quot;https://git.gnome.org/browse/gupnp-tools/tree/src/upload&quot; target=&quot;_blank&quot;&gt;code how to do that in GUPnP is  available in gupnp-tools&lt;/a&gt; and it&amp;#8217;s not exactly pretty. With dLeyna, on the other hand, it&amp;#8217;s a fewliner:&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;python&quot;&gt;&lt;span&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;span&gt;import&lt;/span&gt; &lt;span&gt;sys&lt;/span&gt;
&lt;span&gt;import&lt;/span&gt; mediaconsole &lt;span&gt;as&lt;/span&gt; mc
&amp;nbsp;
u &lt;span&gt;=&lt;/span&gt; mc.&lt;span&gt;UPNP&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;
d &lt;span&gt;=&lt;/span&gt; u.&lt;span&gt;server_from_udn&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;sys&lt;/span&gt;.&lt;span&gt;argv&lt;/span&gt;&lt;span&gt;&amp;#91;&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;&amp;#93;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;
d.&lt;span&gt;upload_to_any&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;sys&lt;/span&gt;.&lt;span&gt;argv&lt;/span&gt;&lt;span&gt;&amp;#91;&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;&amp;#93;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;sys&lt;/span&gt;.&lt;span&gt;argv&lt;/span&gt;&lt;span&gt;&amp;#91;&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;&amp;#93;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In DLNA land, this is called &amp;#8220;+UP+&amp;#8221;.&lt;/p&gt;
&lt;h2&gt;Playing a file&lt;/h2&gt;
&lt;p&gt;Or you want to show some media file you got on your device or app on a DLNA-capable TV? &lt;a href=&quot;https://github.com/phako/korva/tree/master/server/upnp&quot; target=&quot;_blank&quot;&gt;Korva is showing how you can do that with plain GUPnP&lt;/a&gt;, again with a lots of lines of code. dLeyna providing a nice and clean solution:&lt;/p&gt;

&lt;div class=&quot;wp_syntax&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre class=&quot;python&quot;&gt;&lt;span&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;span&gt;import&lt;/span&gt; &lt;span&gt;sys&lt;/span&gt;
&lt;span&gt;import&lt;/span&gt; rendererconosle &lt;span&gt;as&lt;/span&gt; rc
m &lt;span&gt;=&lt;/span&gt; rc.&lt;span&gt;Manager&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;
d &lt;span&gt;=&lt;/span&gt; m.&lt;span&gt;renderer_from_udn&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;sys&lt;/span&gt;.&lt;span&gt;argv&lt;/span&gt;&lt;span&gt;&amp;#91;&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;&amp;#93;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;
uri &lt;span&gt;=&lt;/span&gt; d.&lt;span&gt;host_file&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;sys&lt;/span&gt;.&lt;span&gt;argv&lt;/span&gt;&lt;span&gt;&amp;#91;&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;&amp;#93;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;
d.&lt;span&gt;stop&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;
d.&lt;span&gt;open_uri&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;uri&lt;span&gt;&amp;#41;&lt;/span&gt;
d.&lt;span&gt;play&lt;/span&gt;&lt;span&gt;&amp;#40;&lt;/span&gt;&lt;span&gt;&amp;#41;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And this is called &amp;#8220;+PU+&amp;#8221; in DLNA land.&lt;/p&gt;
&lt;p&gt;Behind the scenes, this is all GUPnP of course. Currently it consists of two DBus services, dleyna-renderer-service and dleyna-server-service, although other IPC mechanisms are on its way. What happens is that that these two services scan the network for available devices and making them available through a set of DBus interfaces, relieving you from the need of searching for devices yourself (and with that providing a device cache, relieving the network from UDP packet bursts), introspecting the devices for supported capabilities and methods and so on.&lt;/p&gt;
&lt;p&gt;If you execute the push script from above you get a python wrapper for the com.intel.dLeynaRenderer.Manager DBus interface, which is then locally looking for the DBus path matching the given UPnP UDN and returning a python object implementing the com.intel.dLeynaRenderer.PushHost and com.intel.dLeynaRenderer.RendererDevice interfaces.&lt;/p&gt;
&lt;p&gt;Then we temporarily host the file given on the command-line on dLeyna&amp;#8217;s internal HTTP server, stopping the currently running playback (Which translates to RenderingControl:Stop SOAP call), send the URI to the server (RenderingControl:SetAVTransportURI) and last but not least start the playback (RenderingControl:Play) which in the end starts the HTTP streaming from dleyna&amp;#8217;s internal HTTP server to (Rygel&amp;#8217;s) renderer.&lt;/p&gt;
&lt;p&gt;And it doesn&amp;#8217;t stop at the application level, there&amp;#8217;s even integration with HTML5 through cloudeebus and cloud-dLeyna.&lt;/p&gt;
&lt;p&gt;As a sidenote: You might ask how that relates to Grilo&amp;#8217;s UPnP-AV support or Korva. This is a very valid question. Grilo and Korva are doing very specific tasks while dLeyna aims to be a more complete SDK. It should be quite easy, for example, to port Grilo&amp;#8217;s UPnP-AV suppport to dLeyna.&lt;/p&gt;</description>
	<pubDate>Tue, 07 May 2013 09:55:17 +0000</pubDate>
</item>
<item>
	<title>Tristan Van Berkom: DoggFooding in Glade</title>
	<guid>http://blogs.gnome.org/tvb/?p=450</guid>
	<link>http://blogs.gnome.org/tvb/2013/04/26/doggfooding-in-glade/</link>
	<description>&lt;p&gt;I&amp;#8217;ve been meaning to write a short post showing what we&amp;#8217;ve been able to do with Glade since we introduced &lt;a href=&quot;http://blogs.gnome.org/tvb/2013/04/09/announcing-composite-widget-templates/&quot;&gt;composite widget templates&lt;/a&gt; in GTK+, the post will be as brief as possible since I&amp;#8217;m preoccupied with other things but here&amp;#8217;s a run over of what&amp;#8217;s changed in the &lt;a href=&quot;https://mail.gnome.org/archives/gnome-announce-list/2013-April/msg00027.html&quot;&gt;Dogg Food release&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Basically, after finally landing the composite template machinery (thanks to Openismus for giving me the time to do that), I couldn&amp;#8217;t resist going the extra mile in Glade, over the weekends and such, to leverage the great new features and do some redesign work in Glade itself.&lt;/p&gt;
&lt;p&gt;So please enjoy ! or don&amp;#8217;t and yell very loudly about how you miss the old editor design, and make suggestions &lt;img src=&quot;http://blogs.gnome.org/tvb/wp-content/mu-plugins/tango-smilies/tango/face-smile.png&quot; alt=&quot;:)&quot; class=&quot;wp-smiley&quot; /&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Glade Preferences Dialog&lt;/strong&gt;&lt;/p&gt;
&lt;div id=&quot;attachment_451&quot; class=&quot;wp-caption alignleft&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/04/glade-preferences-before.png&quot;&gt;&lt;img class=&quot; wp-image-451      &quot; alt=&quot;Preferences Dialog Before&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/04/glade-preferences-before.png&quot; width=&quot;165&quot; height=&quot;78&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Preferences Dialog Before&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;attachment_452&quot; class=&quot;wp-caption alignright&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/04/glade-preferences-after.png&quot;&gt;&lt;img class=&quot; wp-image-452   &quot; alt=&quot;Preferences Dialog After&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/04/glade-preferences-after.png&quot; width=&quot;168&quot; height=&quot;168&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Preferences Dialog After&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The old preferences dialog was a sort of lazy combo box, now that we have composite templates and create the interface using GtkBuilder, it was pretty easy to add the treeview and create a nicer interface for adding customized catalog paths.&lt;/p&gt;
&lt;p&gt;Also there are some new features and configurations in the dialog, since the new Dogg Food release we now have an Autosave feature, and we optionally save your old file.ui to a file.ui~ backup every time you save. There are also some configurations on what kind of warnings to show when saving your glade file (since it can be annoying if you already know there are deprecated widgets, or unrecognized widgets and have the dialog popup every time you save).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Glade Project Properties&lt;/strong&gt;&lt;/p&gt;
&lt;div id=&quot;attachment_454&quot; class=&quot;wp-caption alignleft&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/04/glade-project-properties-before.png&quot;&gt;&lt;img class=&quot; wp-image-454    &quot; alt=&quot;&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/04/glade-project-properties-before.png&quot; width=&quot;180&quot; height=&quot;145&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Project Properties Dialog Before&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;attachment_455&quot; class=&quot;wp-caption alignright&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/04/glade-project-properties-after.png&quot;&gt;&lt;img class=&quot; wp-image-455    &quot; alt=&quot;&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/04/glade-project-properties-after.png&quot; width=&quot;182&quot; height=&quot;173&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Project Properties Dialog After&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Refactoring out the project properties dialog into a separate source file, and implementing the UI with Glade makes the GladeProject code more readable, also the UI benefits again, notice the not so clear &amp;#8220;Execute&amp;#8221; button has been moved to be a secondary dialog button (with a tooltip explaining what it does).&lt;/p&gt;
&lt;p&gt;Also the new project attributes have been added to allow one to set the project&amp;#8217;s translation domain or Composite Template toplevel widget.&lt;/p&gt;
&lt;p&gt;Now that&amp;#8217;s just the beginning, let&amp;#8217;s walk through the new custom editors.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Button Editor&lt;/strong&gt;&lt;/p&gt;
&lt;div id=&quot;attachment_457&quot; class=&quot;wp-caption alignright&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/04/button-editor-after.png&quot;&gt;&lt;img class=&quot; wp-image-457   &quot; alt=&quot;GtkButton Editor After&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/04/button-editor-after.png&quot; width=&quot;195&quot; height=&quot;337&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;GtkButton Editor After&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;attachment_456&quot; class=&quot;wp-caption alignleft&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/04/button-editor-before.png&quot;&gt;&lt;img class=&quot; wp-image-456    &quot; alt=&quot;GtkButton Editor Before&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/04/button-editor-before.png&quot; width=&quot;190&quot; height=&quot;315&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;GtkButton Editor Before&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s where the fun starts, while we did have some custom editors before, they all had to be hand written, now I&amp;#8217;ve added some base classes making it much easier to design the customized property editors with Glade.&lt;/p&gt;
&lt;p&gt;First thing to notice is we have these check button property editors for some boolean properties which we can place wherever in the customized property editor layout (checkbuttons previously didnt make any sense in a layout where one always expects to see the title label on the left, and the property control on the right, in a table or grid layout).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Entry Editor Before&lt;/strong&gt;&lt;/p&gt;
&lt;div id=&quot;attachment_459&quot; class=&quot;wp-caption alignleft&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/04/entry-editor-before-top.png&quot;&gt;&lt;img class=&quot; wp-image-459    &quot; alt=&quot;GtkEntry Editor Before (top portion)&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/04/entry-editor-before-top.png&quot; width=&quot;190&quot; height=&quot;326&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;GtkEntry Editor Before (top portion)&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;attachment_460&quot; class=&quot;wp-caption alignright&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/04/entry-editor-before-bottom.png&quot;&gt;&lt;img class=&quot; wp-image-460    &quot; alt=&quot;GtkEntry Editor Before (bottom portion)&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/04/entry-editor-before-bottom.png&quot; width=&quot;190&quot; height=&quot;326&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;GtkEntry Editor Before (bottom portion)&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Entry Editor After&lt;/strong&gt;&lt;/p&gt;
&lt;div id=&quot;attachment_461&quot; class=&quot;wp-caption alignleft&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/04/entry-editor-after-top.png&quot;&gt;&lt;img class=&quot;wp-image-461  &quot; alt=&quot;GtkEntry Editor After (top portion)&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/04/entry-editor-after-top.png&quot; width=&quot;195&quot; height=&quot;302&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;GtkEntry Editor After (top portion)&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;attachment_462&quot; class=&quot;wp-caption alignright&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/04/entry-editor-after-bottom.png&quot;&gt;&lt;img class=&quot; wp-image-462     &quot; alt=&quot;GtkEntry Editor After (bottom portion)&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/04/entry-editor-after-bottom.png&quot; width=&quot;187&quot; height=&quot;266&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;GtkEntry Editor After (bottom portion)&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;All around better layout I think, also we save space by playing tricks with the tooltip-text / tooltip-markup properties for the icons. While in reality GTK+ has separate properties, we just add a &amp;#8220;Use Markup&amp;#8221; check to the tooltip editor and use that to decide whether to edit the normal tooltip text property, or the tooltip markup property.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Image Editor&lt;/strong&gt;&lt;/p&gt;
&lt;div id=&quot;attachment_463&quot; class=&quot;wp-caption alignleft&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/04/image-editor-before.png&quot;&gt;&lt;img class=&quot; wp-image-463   &quot; alt=&quot;GtkImage Editor Before&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/04/image-editor-before.png&quot; width=&quot;182&quot; height=&quot;214&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;GtkImage Editor Before&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;attachment_464&quot; class=&quot;wp-caption alignright&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/04/image-editor-after.png&quot;&gt;&lt;img class=&quot; wp-image-464   &quot; alt=&quot;GtkImage Editor After&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/04/image-editor-after.png&quot; width=&quot;187&quot; height=&quot;220&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;GtkImage Editor After&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here we economize on space a bit by putting the GtkMisc alignment and padding details down at the bottom, also we group the &amp;#8220;use-fallback&amp;#8221; property with the icon name setting, since the fallback property can only apply to images that are set by icon name.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Label Editor&lt;/strong&gt;&lt;/p&gt;
&lt;div id=&quot;attachment_465&quot; class=&quot;wp-caption alignleft&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/04/label-editor-before.png&quot;&gt;&lt;img class=&quot; wp-image-465   &quot; alt=&quot;GtkLabel Editor Before&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/04/label-editor-before.png&quot; width=&quot;187&quot; height=&quot;368&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;GtkLabel Editor Before&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;attachment_466&quot; class=&quot;wp-caption alignright&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/04/label-editor-after.png&quot;&gt;&lt;img class=&quot; wp-image-466    &quot; alt=&quot;GtkLabel Editor After&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/04/label-editor-after.png&quot; width=&quot;185&quot; height=&quot;301&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;GtkLabel Editor After&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Like the GtkImage Editor, we&amp;#8217;ve grouped the GtkMisc properties together near the bottom. We also have generally better grouping all around of properties, hopefully this will help the user find what they are looking for more quickly. Another interesting thing is that the mnemonic widget editor is insensitive if &amp;#8220;use-underline&amp;#8221; is FALSE, when &amp;#8220;use-underline&amp;#8221; becomes selected, the mnemonic widget property can be set directly to the right of the &amp;#8220;use-underline&amp;#8221; property.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Widget Editor / Common Tab&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Last but not least (of what we&amp;#8217;ve done so far) is a completely new custom editor for the &amp;#8220;Common&amp;#8221; tab (perhaps we can do away with the &amp;#8220;Common&amp;#8221; tab altogether&amp;#8230; use expanders where we currently have bold heading labels, now that we do it all with GtkBuilder script, sky is the limit really)&lt;/p&gt;
&lt;div id=&quot;attachment_467&quot; class=&quot;wp-caption alignleft&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/04/widget-editor-before-top.png&quot;&gt;&lt;img class=&quot; wp-image-467    &quot; alt=&quot;GtkWidget Editor Before (top portion)&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/04/widget-editor-before-top.png&quot; width=&quot;181&quot; height=&quot;265&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;GtkWidget Editor Before (top portion)&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;attachment_468&quot; class=&quot;wp-caption alignright&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/04/widget-editor-before-bottom.png&quot;&gt;&lt;img class=&quot; wp-image-468    &quot; alt=&quot;GtkWidget Editor Before (bottom portion)&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/04/widget-editor-before-bottom.png&quot; width=&quot;181&quot; height=&quot;265&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;GtkWidget Editor Before (bottom portion)&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Widget Editor After&lt;/strong&gt;&lt;/p&gt;
&lt;div id=&quot;attachment_469&quot; class=&quot;wp-caption alignleft&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/04/widget-editor-after.png&quot;&gt;&lt;img class=&quot; wp-image-469  &quot; alt=&quot;GtkWidget Editor After&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/04/widget-editor-after.png&quot; width=&quot;276&quot; height=&quot;438&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;GtkWidget Editor After&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here again we play some tricks with the tooltip, so that we don&amp;#8217;t have two separate property entries for &amp;#8220;tooltip-text&amp;#8221; and &amp;#8220;tooltip-markup&amp;#8221; but instead a simple switch deciding whether to set the tooltip as markup or not. The little &amp;#8220;Custom&amp;#8221; check button in there makes the tooltip editors insensitive and instead sets the &amp;#8220;has-tooltip&amp;#8221; property to TRUE, so that you can hook into the &amp;#8220;query-tooltip&amp;#8221; signal to create a custom tooltip window.&lt;/p&gt;
&lt;p&gt;Now while these are just the first iterations of the new editor designs and layouts, the really great news is that we can now use Glade to design the layouts of Glade&amp;#8217;s widget editors, so you can expect (and even request &lt;img src=&quot;http://blogs.gnome.org/tvb/wp-content/mu-plugins/tango-smilies/tango/face-wink.png&quot; alt=&quot;;-)&quot; class=&quot;wp-smiley&quot; /&gt; ) better designs in the future. Also, we&amp;#8217;re open to ideas, if you have any great ideas on how to make widget property editing more fun, more obvious, more usable&amp;#8230; please share them with us in bugzilla or on our mailing list.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Extra amendment&lt;/strong&gt;: Fitting images into blog post side by side has been a delicate exercise, it looks different in the editor, different at blogs.gnome.org, and again different on planet.gnome.org, just goes to show that I make for a terrible poster boy, not to mention I don&amp;#8217;t post quite that often&amp;#8230; anyway&amp;#8230; hope the formatting of this post is endurable at least, it&amp;#8217;s best viewed at blogs.gnome.org I think.&lt;/p&gt;</description>
	<pubDate>Fri, 26 Apr 2013 07:20:05 +0000</pubDate>
</item>
<item>
	<title>Tristan Van Berkom: Announcing Composite Widget Templates</title>
	<guid>http://blogs.gnome.org/tvb/?p=405</guid>
	<link>http://blogs.gnome.org/tvb/2013/04/09/announcing-composite-widget-templates/</link>
	<description>&lt;p&gt;Hello fellow hackers, today we bring you a new feature which I believe can very much improve the GTK+/GNOME developer story.&lt;/p&gt;
&lt;p&gt;This is a feature I&amp;#8217;ve been planning for a long time (I &lt;a href=&quot;http://blogs.gnome.org/tvb/2010/03/08/it-was-a-saturday-afternoon-patch/&quot;&gt;originally blogged&lt;/a&gt; about it &lt;a href=&quot;http://blogs.gnome.org/tvb/2010/03/14/composite-saga-continues/&quot;&gt;3 years ago&lt;/a&gt;) so I&amp;#8217;m very excited about it having finally landed in GTK+, it&amp;#8217;s my hope and ambition that this feature will help shape the future of user interface programming with GTK+.&lt;/p&gt;
&lt;p&gt;Before I continue, I have to thank &lt;a href=&quot;http://blogs.gnome.org/xjuan/&quot;&gt;Juan Pablo Ugarte&lt;/a&gt; for &lt;a href=&quot;http://blogs.gnome.org/xjuan/2012/07/13/embeding-gtkbuilder-ui-definitions-into-gobject-classes/&quot;&gt;keeping the&lt;/a&gt; &lt;a href=&quot;http://blogs.gnome.org/xjuan/2012/11/12/gtkbuilder-and-external-objects/&quot;&gt;dream alive&lt;/a&gt; and talking about this at &lt;a href=&quot;http://2012.guadec.org/node/43&quot;&gt;the last GUADEC&lt;/a&gt;. Also recognition must be given to &lt;a href=&quot;http://www.openismus.com/&quot;&gt;Openismus GmbH&lt;/a&gt; for sponsoring my full time work on this for the last few weeks, the time to completely focus on this task would not have been afforded me without them.&lt;/p&gt;
&lt;p&gt;Unfortunately this post will be a little terse, the one I had planned which is a bit more relaxed and has some comic relief will not be ready on time. So, at the risk of being taken seriously, let&amp;#8217;s continue with a brief overview of the APIs introduced to GTK+ and the actions taken.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What are Composite Widget Templates ?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Composite Widget Templates are an association of GtkWidget class data with GtkBuilder xml, which is to say that the xml which defines a composite widget is now a part of the definition of a widget class or type.&lt;/p&gt;
&lt;p&gt;This feature automates the creation of composite widgets without the need for directly accessing the GtkBuilder APIs and comes with a few features that help to bind a GtkWidget with it&amp;#8217;s GtkBuilder xml.&lt;/p&gt;
&lt;p&gt;As of yesterday, 23 composite widget classes in GTK+, from simple classes such as &lt;a href=&quot;https://git.gnome.org/browse/gtk+/commit/?id=36bacc4674dc76d197f69e173eef8858c6d98853&quot;&gt;GtkFontButton&lt;/a&gt; or &lt;a href=&quot;https://git.gnome.org/browse/gtk+/commit/?id=92a8c76b314effa8c43c3fae1291c500f93f8839&quot;&gt;GtkVolumeButton&lt;/a&gt; to more complex widget classes such as &lt;a href=&quot;https://git.gnome.org/browse/gtk+/commit/?id=bf909f56157311174d5d9089bdec954e7def8873&quot;&gt;GtkFileChooserDefault&lt;/a&gt; and &lt;a href=&quot;https://git.gnome.org/browse/gtk+/commit/?id=9accb95b9f1b12a2a69625d4638a308840df584d&quot;&gt;GtkPrintUnixDialog&lt;/a&gt; have all been ported to remove all manual user interface creation code, in favour of GtkBuilder xml.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;So, how can I use it ?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There are three or four new APIs added to GtkWidget which play on the class data, currently they will only be available in C, but if you have a little imagination, you can see how this can be very useful in higher level languages, by extending the syntax and adding some keywords (hint: &lt;em&gt;I have vala in mind as a top candidate&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;Before I go into the API details here, I would like to point out a &lt;a href=&quot;http://people.gnome.org/~tvb/composite-demo.tgz&quot;&gt;complete working example&lt;/a&gt; which I created today while writing this post. To give it a try, you need of course GTK+ master from today (or yesterday). For those who are interested I suggest you download that small tarball, and build it with one simple &amp;#8216;make&amp;#8217; command.&lt;/p&gt;
&lt;p&gt;First, lets start with an example of how to bind your template to your widget class:&lt;/p&gt;
&lt;pre&gt;&lt;span&gt;static&lt;/span&gt; &lt;span&gt;void&lt;/span&gt;
my_widget_class_init &lt;span&gt;(&lt;/span&gt;MyWidgetClass &lt;span&gt;*&lt;/span&gt;klass&lt;span&gt;)&lt;/span&gt;
&lt;span&gt;{&lt;/span&gt;
  GtkWidgetClass &lt;span&gt;*&lt;/span&gt;widget_class &lt;span&gt;=&lt;/span&gt; GTK_WIDGET_CLASS &lt;span&gt;(&lt;/span&gt;klass&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;

  &lt;span&gt;/* Setup the template GtkBuilder xml for this class&lt;/span&gt;
&lt;span&gt;   */&lt;/span&gt;
  gtk_widget_class_set_template_from_resource &lt;span&gt;(&lt;/span&gt;widget_class&lt;span&gt;,&lt;/span&gt; &lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;/org/foo/my/mywidget.ui&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;}&lt;/span&gt;

&lt;span&gt;static&lt;/span&gt; &lt;span&gt;void&lt;/span&gt;
my_widget_init &lt;span&gt;(&lt;/span&gt;MyWidget &lt;span&gt;*&lt;/span&gt;widget&lt;span&gt;)&lt;/span&gt;
&lt;span&gt;{&lt;/span&gt;
  &lt;span&gt;/* Initialize the template for this instance */&lt;/span&gt;
  gtk_widget_init_template &lt;span&gt;(&lt;/span&gt;GTK_WIDGET &lt;span&gt;(&lt;/span&gt;widget&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;So, to bind some GtkBuilder XML to a widget class, we need to call two functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;gtk_widget_class_set_template_from_resource() binds some GtkBuilder XML to the class data&lt;/li&gt;
&lt;li&gt;gtk_widget_init_template() initializes the template for a given instance, this is currently needed for the base C apis, but both could certainly be automated in a highlevel language.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Next, we have a function which creates an implicit relationship between some instance variables and some objects defined in the GtkBuilder XML:&lt;/p&gt;
&lt;pre&gt;&lt;span&gt;struct&lt;/span&gt; _MyWidgetPrivate
&lt;span&gt;{&lt;/span&gt;
  &lt;span&gt;/* This is the entry defined in the GtkBuilder xml */&lt;/span&gt;
  GtkWidget &lt;span&gt;*&lt;/span&gt;entry&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;

&lt;span&gt;static&lt;/span&gt; &lt;span&gt;void&lt;/span&gt;
my_widget_class_init &lt;span&gt;(&lt;/span&gt;MyWidgetClass &lt;span&gt;*&lt;/span&gt;klass&lt;span&gt;)&lt;/span&gt;
&lt;span&gt;{&lt;/span&gt;
  GtkWidgetClass &lt;span&gt;*&lt;/span&gt;widget_class &lt;span&gt;=&lt;/span&gt; GTK_WIDGET_CLASS &lt;span&gt;(&lt;/span&gt;klass&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
  GObjectClass &lt;span&gt;*&lt;/span&gt;gobject_class &lt;span&gt;=&lt;/span&gt; G_OBJECT_CLASS &lt;span&gt;(&lt;/span&gt;klass&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;

  &lt;span&gt;/* After having called gtk_widget_class_set_template_from_resource(), we can&lt;/span&gt;
&lt;span&gt;   * define the relationship of the private entry and the entry defined in the xml.&lt;/span&gt;
&lt;span&gt;   */&lt;/span&gt;
  gtk_widget_class_bind_child &lt;span&gt;(&lt;/span&gt;widget_class&lt;span&gt;,&lt;/span&gt; MyWidgetPrivate&lt;span&gt;,&lt;/span&gt; entry&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;

  g_type_class_add_private &lt;span&gt;(&lt;/span&gt;gobject_class&lt;span&gt;,&lt;/span&gt; &lt;span&gt;sizeof&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;MyWidgetPrivate&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;In the above code, we&amp;#8217;ve defined a &lt;em&gt;relationship &lt;/em&gt;between the MyWidgetPrivate pointer named &amp;#8216;entry&amp;#8217; and the object in the GtkBuilder XML of the same name &amp;#8216;entry&amp;#8217;. The entry will be available for access on the subclassed GtkWidget instance private data at any time after gtk_widget_init_template() was called, until the given widget is disposed (at which time the pointer will become NULL). GTK+ takes care of memory managing such automated pointers, so it is ensured to exist for the lifetime of your instances.&lt;/p&gt;
&lt;p&gt;Again, with highlevel bindings in mind, this could be implemented as some syntactic sugar in the actual declaration of the instance variable.&lt;/p&gt;
&lt;p&gt;Finally there is one more point of interest in the API which is &lt;em&gt;Callbacks&lt;/em&gt;. Functions in your widget class code can be specified as &lt;em&gt;Callbacks &lt;/em&gt;which serve as endpoints for any signal connections defined in the GtkBuilder XML.&lt;/p&gt;
&lt;pre&gt;&lt;span&gt;/* A callback handling a &quot;clicked&quot; event from a button defined in the GtkBuilder XML */&lt;/span&gt;
&lt;span&gt;static&lt;/span&gt; &lt;span&gt;void&lt;/span&gt;
my_widget_button_clicked &lt;span&gt;(&lt;/span&gt;MyWidget  &lt;span&gt;*&lt;/span&gt;widget&lt;span&gt;,&lt;/span&gt;
                          GtkButton &lt;span&gt;*&lt;/span&gt;button&lt;span&gt;)&lt;/span&gt;
&lt;span&gt;{&lt;/span&gt;
  g_print &lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;The button was clicked with entry text: &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
           gtk_entry_get_text &lt;span&gt;(&lt;/span&gt;GTK_ENTRY &lt;span&gt;(&lt;/span&gt;widget&lt;span&gt;-&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;priv&lt;span&gt;-&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;entry&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;}&lt;/span&gt;

&lt;span&gt;static&lt;/span&gt; &lt;span&gt;void&lt;/span&gt;
my_widget_class_init &lt;span&gt;(&lt;/span&gt;MyWidgetClass &lt;span&gt;*&lt;/span&gt;klass&lt;span&gt;)&lt;/span&gt;
&lt;span&gt;{&lt;/span&gt;
  GtkWidgetClass &lt;span&gt;*&lt;/span&gt;widget_class &lt;span&gt;=&lt;/span&gt; GTK_WIDGET_CLASS &lt;span&gt;(&lt;/span&gt;klass&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;

  &lt;span&gt;/* After having called gtk_widget_class_set_template_from_resource(), we can&lt;/span&gt;
&lt;span&gt;   * declare callback ports that this widget class exposes, to bind with &amp;lt;signal&amp;gt;&lt;/span&gt;
&lt;span&gt;   * connections defined in the GtkBuilder xml&lt;/span&gt;
&lt;span&gt;   */&lt;/span&gt;
  gtk_widget_class_bind_callback &lt;span&gt;(&lt;/span&gt;widget_class&lt;span&gt;,&lt;/span&gt; my_widget_button_clicked&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Note that all signal connections defined in composite templates have the composite widget instance as user data by default.&lt;/p&gt;
&lt;p&gt;In the above example code, my_widget_button_clicked() callback was declared with the assumption that the &amp;lt;signal&amp;gt; connection defined in the template was declared as &amp;#8216;swapped&amp;#8217;. Swapped signal connections are connections where the user data of the callback is returned first instead of the emitter. I think that this should be the default for composite widget callbacks as it blends in more naturally with normal class methods (where the class instance is always the first parameter).&lt;/p&gt;
&lt;p&gt;This detail might not apply directly to higher level languages, which could achieve the above by adding some syntactic sugar in the declaration of a &lt;em&gt;Callback &lt;/em&gt;method. Perhaps the instance will be implied as the &amp;#8216;self&amp;#8217; variable.&lt;/p&gt;
&lt;p&gt;I have also included some additional API to allow bindings to specify the &lt;a href=&quot;https://developer.gnome.org/gtk3/unstable/GtkBuilder.html#GtkBuilderConnectFunc&quot;&gt;GtkBuilderConnectFunc&lt;/a&gt; which should be used to make signal connections for a given widget class. I hope that bindings authors will contact me if they need any additional support in the GTK+ api to implement this.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Can I now use Glade to define my Composite Widget Templates ?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Of course silly ! That&amp;#8217;s the whole point right ?&lt;/p&gt;
&lt;p&gt;You&amp;#8217;ll need Glade master from today as well, however I should be rolling a development snapshot with full support for this later this week as well.&lt;/p&gt;
&lt;p&gt;All of GTK+&amp;#8217;s composite widget classes have been recreated &lt;em&gt;using Glade&lt;/em&gt;. Here is a screenshot of a GTK+ composite widget being edited in Glade:&lt;/p&gt;
&lt;div id=&quot;attachment_434&quot; class=&quot;wp-caption aligncenter&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/04/glade-editing-filechooser.png&quot;&gt;&lt;img class=&quot; wp-image-434  &quot; alt=&quot;Glade editing the GtkFileChooserDefault&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/04/glade-editing-filechooser.png&quot; width=&quot;506&quot; height=&quot;334&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Glade editing the GtkFileChooserDefault&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;Glade is still in it&amp;#8217;s early stages supporting this, so there is hardly any features added here. I hope to work towards a brighter future where Glade can understand a multitude of composite widget templates as components of a single project, which will open the doors for some really nice and useful features.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;All in all I have a lot to say about this work, but I&amp;#8217;ll cut this blog post short for now, however I may be posting followups in the near future.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m very satisfied with this work, and I hope you will enjoy creating user interfaces as composite widget classes.&lt;/p&gt;</description>
	<pubDate>Tue, 09 Apr 2013 11:05:58 +0000</pubDate>
</item>
<item>
	<title>Murray Cumming: More Maliit Keyboard Improvements: QtQuick2</title>
	<guid>http://www.murrayc.com/?p=1897</guid>
	<link>http://www.murrayc.com/permalink/2013/04/02/more-maliit-keyboard-improvements-qtquick2/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=more-maliit-keyboard-improvements-qtquick2</link>
	<description>&lt;p&gt;A few days ago I pushed 44 more commits to the &lt;a href=&quot;https://gitorious.org/maliit/maliit-plugins&quot;&gt;Maliit Plugins&lt;/a&gt; repository now that Canonical have published (in the &lt;a href=&quot;https://code.launchpad.net/%7Ephablet-team/phablet-extras/maliit-plugins&quot;&gt;Ubuntu Phablet project’s maliit-plugins Launchpad/Bazaar repository&lt;/a&gt;) that work that we (&lt;a href=&quot;http://www.openismus.com/&quot;&gt;Openismus&lt;/a&gt;) did for them.&lt;/p&gt;
&lt;p&gt;This brings the Maliit Keyboard into the QML/QtQuick2 world for Qt5, removing the use of QGraphicsView which is not really suitable for Qt5. This should also have some performance advantages and makes customization even easier.&lt;/p&gt;
&lt;p&gt;Michael Hasselmann blogged a &lt;a href=&quot;http://mikhas.posterous.com/maliit-status-update&quot;&gt;summary of the state of Maliit&lt;/a&gt; today. The recent work, along with the Wayland integration, has made Maliit more popular than ever.  But we still need to line up customers to fund the ongoing development, generally while creating custom features or solutions for them.&lt;/p&gt;</description>
	<pubDate>Tue, 02 Apr 2013 11:51:06 +0000</pubDate>
</item>
<item>
	<title>Michael Hasselmann: Maliit Status Update</title>
	<guid>http://mikhas.posterous.com/maliit-status-update</guid>
	<link>http://mikhas.posterous.com/maliit-status-update</link>
	<description>&lt;p&gt;
	&lt;p&gt;We&amp;rsquo;ve been busy! The result is our latest release, Maliit 0.99, with a &lt;a href=&quot;https://gitorious.org/maliit/maliit-framework/blobs/0.99.0/NEWS&quot;&gt;massive amount&lt;/a&gt; &lt;a href=&quot;https://gitorious.org/maliit/maliit-plugins/blobs/0.99.0/NEWS&quot;&gt;of changes&lt;/a&gt;. While the framework has mostly seen code cleanups (&lt;code&gt;:~/source/maliit/fw$ git diff 0.94.0..0.99.0 --stat: 389 files changed, 3612 insertions(+), 30081 deletions(-)&lt;/code&gt;), we&amp;rsquo;ve been adding tons of features to the reference plugins (&lt;code&gt;:~/source/maliit/plugins$ git diff 0.94.0..0.99.0 --stat: 324 files changed, 32499 insertions(+), 12799 deletions(-)&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;After (finally!) getting official Debian and Ubuntu packages, the next big step is our Maliit 1.0 release, which we expect sometime later this year.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://lists.maliit.org/pipermail/maliit-discuss-maliit.org/2013-March/000298.html&quot;&gt;Maliit 0.99&lt;/a&gt; works with applications using GTK+2/3 or Qt4/5, though Qt4 still works best. Maliit&amp;rsquo;s framework and reference plugins strictly require Qt5 as build dependency, allowing us to get rid of Qt4 and Xlib legacy code. Maliit can run on Wayland but at this point only EFL applications support Wayland input methods. For Qt5 applications wanting to use Maliit together with Wayland, a Qt5 platform plugin for Wayland input methods would be needed.&lt;/p&gt;

&lt;h1&gt;Who is using Maliit?&lt;/h1&gt;

&lt;p&gt;The best Maliit showcase is still the Nokia N9. No other device got anywhere near to the demonstrated input method integration level. The haptic feedback of its virtual keyboard remains unchallenged. I think it&amp;rsquo;s a major success for our old Harmattan text input method team that we see Maliit being used in other projects. It was hard work to get to this point and yet it feels as if this was only the beginning of Maliit as an open-source project.&lt;/p&gt;

&lt;p&gt;We have the friendly folks beind the OLPC project who were one of the first to go with Maliit. Few of us will probably make the new XO their primary device and therefore, won&amp;rsquo;t see the results of the collaboration. But from the very beginning, they worked with us in the open, provided official Fedora packages and helped us test-driving the then-new styling engine of Maliit Keyboard. The XO is one of the use-cases where Maliit has to run without a compositing window manager, which made them an early adopter of our windowed mode.&lt;/p&gt;

&lt;p&gt;Plasma Active is another project that &amp;mdash; for its size &amp;mdash; invested significant development time improving and testing Maliit&amp;rsquo;s reference plugins. They&amp;rsquo;ve been (and hopefully remain!) a huge help whenever we faced problems with QML. I wish we could find a sponsor however to work on improving their input method integration, which is the &amp;ldquo;invisible&amp;rdquo; and challenging part that easily gets forgotten.&lt;/p&gt;

&lt;p&gt;Ubuntu Touch is choosing Maliit as well. Canonical sponsored significant work in Maliit Keyboard, especially in terms of Qt5 support and replacing QGraphicsView with QtQuick2.&lt;/p&gt;

&lt;p&gt;SailfishOS is happy user of Maliit, too. They are the main consumers of our 0.80 branches that still offer full support for Qt4 and X11. We always considered 0.80 our latest &amp;ldquo;stable&amp;rdquo; release branch, so it&amp;rsquo;s good to know that at least someone is also using it.&lt;/p&gt;

&lt;p&gt;OpenEmbedded has integrated Maliit into their meta layer. This makes it easier to build custom Linux distros for embedded with Maliit on board. My understanding of OpenEmbedded is still limited at this point so I cannot explain all the real benefits this collaboration provides. Luckily there&amp;rsquo;s the always friendly Samuel Stritzel who&amp;rsquo;s following our official mailing list, waiting to answer all your OpenEmbedded related questions.&lt;/p&gt;

&lt;p&gt;Gnome3. Just kidding. But once Gnome3 &lt;a href=&quot;https://live.gnome.org/Wayland/Gaps&quot;&gt;properly integrates with Wayland input methods&lt;/a&gt;, we can just plug in Maliit, too. Of course to be of any interest for Gnome3, we need to demonstrate working CJK input methods too. Luckily, we got the opportunity to just do that: &lt;a href=&quot;http://jpetersen.org/videos/ibus-wayland.mp4&quot;&gt;IBus working with Wayland input methods&lt;/a&gt;. If things pan out I&amp;rsquo;ll be talking about this at &lt;a href=&quot;http://2013.gnome.asia/&quot;&gt;GNOME.Asia&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I would like to get the chance to improve input method support for Firefox and Chrome/Chromium. There is &lt;a href=&quot;https://bugs.maliit.org/show_bug.cgi?id=89&quot;&gt;one nasty bug&lt;/a&gt; around password fields that&amp;rsquo;s been quite a blocker for us. Some day, we&amp;rsquo;ll hopefully be able to convince the browser guys to just &amp;ldquo;do the right thing&amp;rdquo;.&lt;/p&gt;

&lt;p&gt;And then there&amp;rsquo;s yours project of course. You just didn&amp;rsquo;t tell me about it yet ;&amp;ndash;)&lt;/p&gt;

&lt;h1&gt;Architecture&lt;/h1&gt;

&lt;p&gt;There is an influx of new developers showing interest in Maliit which is why I feel that reiterating the basic architecture behind Maliit doesn&amp;rsquo;t hurt.&lt;/p&gt;

&lt;p&gt;Maliit is split into three parts: &lt;a href=&quot;https://gitorious.org/maliit/maliit-framework&quot;&gt;framework&lt;/a&gt;, &lt;a href=&quot;https://gitorious.org/maliit/maliit-plugins&quot;&gt;reference plugins&lt;/a&gt; and input method modules (&lt;a href=&quot;https://gitorious.org/maliit/maliit-inputcontext-gtk&quot;&gt;GTK+&lt;/a&gt;, &lt;a href=&quot;https://gitorious.org/maliit/maliit-inputcontext-qt4&quot;&gt;Qt4&lt;/a&gt;, &lt;a href=&quot;https://qt.gitorious.org/qt/qtbase/trees/stable/src/plugins/platforminputcontexts/maliit&quot;&gt;Qt5&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The framework provides maliit-server, a process that can load reference plugins (such as VKBs) and allows applications to connect to it through input method modules. The input method modules are UI toolkit specific and are loaded dynamically by the applications. For each UI toolkit Maliit wishes to support, a separate input method module is required.&lt;/p&gt;

&lt;p&gt;Input method modules and framework are designed as client-server architecture, with applications behaving as clients. The default IPC is QDBus but it can be replaced by other mechanisms, for instance the Wayland IPC.&lt;/p&gt;

&lt;p&gt;In a follow-up blog post I will provide an outlook of where Maliit goes next and which parts of it we might have to rethink, now that the leviathan of Linux DEs is quickly moving towards Wayland.&lt;/p&gt;

&lt;h1&gt;People&lt;/h1&gt;

&lt;p&gt;Those are the people who have contributed to Maliit, but you wouldn&amp;rsquo;t know if you only checked commit messages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Łukasz Zemczak, Thomas Möricke and Kevin Wright: You guys have been great. Would work together again.&lt;/li&gt;
&lt;li&gt;Iain Lane, Michał Zajac, Peter Robinson: Without you, we still wouldn&amp;rsquo;t have proper Debian/(K)Ubuntu/Fedora packaging. Thanks!&lt;/li&gt;
&lt;li&gt;Samuel Stritzel: Thanks for bringing Maliit to OpenEmbedded! Hopefully we&amp;rsquo;ll see more use of your work soon.&lt;/li&gt;
&lt;li&gt;Simon Schampijer, Daniel Drake, Gary Martin, Jennifer Amaya and Martin Langhoff: Thanks for the opportunity to work on OLPC. I know most of us are not in the target audience which makes it hard for you guys to motivate others to help you. Your work is important, please never give up.&lt;/li&gt;
&lt;li&gt;Pekka Vuorela: I am just glad to have you back in the team. Maliit just isn&amp;rsquo;t the same without you.&lt;/li&gt;
&lt;li&gt;Aaron Seigo, Marco Martin: Thanks for all your enthusiasm about Maliit and Plasma Active. Your motivation is infectious.&lt;/li&gt;
&lt;li&gt;Jan Arne Petersen, Krzesimir Nowak: I am impressed by your motivation and dedication that you &lt;em&gt;still&lt;/em&gt; have for input methods, even though none of us ever planned to become an &amp;ldquo;input method expert&amp;rdquo;.&lt;/li&gt;
&lt;/ul&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://mikhas.posterous.com/maliit-status-update&quot;&gt;Permalink&lt;/a&gt; 

	| &lt;a href=&quot;http://mikhas.posterous.com/maliit-status-update#comment&quot;&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;</description>
	<pubDate>Tue, 02 Apr 2013 11:22:00 +0000</pubDate>
</item>
<item>
	<title>Jens Georg: Certification time</title>
	<guid>http://jensge.org/?p=843</guid>
	<link>http://jensge.org/2013/04/certification-time/</link>
	<description>&lt;p&gt;For the second time (at least that we know of) software based on &lt;a href=&quot;http://gupnp.org&quot; target=&quot;_blank&quot;&gt;GUPnP&lt;/a&gt; has been successfully certified by the &lt;a href=&quot;http://www.upnp.org&quot; target=&quot;_blank&quot;&gt;UPnP Forum&lt;/a&gt;. Cloud-&lt;a href=&quot;http://01.org/dleyna&quot; target=&quot;_blank&quot;&gt;dLeyna&lt;/a&gt;, providing UPnP-AV/DLNA client APIs to HTML5, has achieved UPnP certification recently: &lt;a href=&quot;https://lists.01.org/pipermail/dleyna/2013-March/000115.html&quot;&gt;https://lists.01.org/pipermail/dleyna/2013-March/000115.html&lt;/a&gt;&lt;/p&gt;</description>
	<pubDate>Tue, 02 Apr 2013 09:51:32 +0000</pubDate>
</item>
<item>
	<title>Mathias Hasselmann: Direct Read Access for Evolution Addressbooks in LibreOffice</title>
	<guid>http://taschenorakel.de/mathias/2013/03/13/eds-direct-access-libreoffice/</guid>
	<link>http://taschenorakel.de/mathias/2013/03/13/eds-direct-access-libreoffice/</link>
	<description>&lt;p&gt;With Tristan just landing his work on &lt;a href=&quot;https://blogs.gnome.org/tvb/2013/01/15/getting-your-contacts-right-now/&quot;&gt;direct-read-access for EDS 3.8&lt;/a&gt; we
at &lt;a href=&quot;http://openismus.com&quot;&gt;Openismus&lt;/a&gt; started to look for use-cases of DRA outside the customer work we did. A first project that came into mind was
&lt;a href=&quot;http://www.libreoffice.org/&quot;&gt;LibreOffice&lt;/a&gt;: It provides a connectivity driver for Evolution's address books. Basically this component is to support standard letters. Now mass printing letters isn't exactly dominated by the address book's reading performance, but to the user the addressbook appears like any other database, so it surely can used for more interesting tasks. Also the EDS function LibreOffice uses for accessing addressbooks got deprecated with EDS 3.8, so we gave it a try.&lt;/p&gt;
&lt;p&gt;Downloading and building LibreOffice was a simple walk thanks to &lt;a href=&quot;https://wiki.documentfoundation.org/Development/Native_Build&quot;&gt;LibreOffice's great build instructions&lt;/a&gt;. Somewhat interested in build systems I was positively surprised when seeing LibreOffice's sophisticated build system that's entirely based on Autoconf and pure GNU make. The relevant code was easy to find and understand, so I patched it quickly. Getting environment variables and D-Bus configuration right for testing was the biggest effort. After being sufficiently confident about the code, I did a quick push to a new &lt;a href=&quot;https://gerrit.libreoffice.org/#/q/project:core+branch:master+topic:evoab-dra,n,z&quot;&gt;gerrit topic branch&lt;/a&gt;. Shortly later the code was reviewed and merged. Nice experience.&lt;/p&gt;
&lt;p&gt;So what do you get from this patch: Accessing Evolution address books from LibreOffice should be more efficient now, as we eliminated a few layers of complexity for reading. This also should reduce worries about GLib main loops or threads interacting badly with LibreOffice, as direct-read-access skips D-Bus and just runs the backend drivers.&lt;/p&gt;
&lt;p&gt;Still the database wizard doesn't list all available Evolution address books: There are local, LDAP and Groupwise address books, but Google address books are missing for instance. Additionally only the first address book of each backend is available. Looking at the database wizard now to fix this, and getting a first impression of the older code's complexity.&lt;/p&gt;</description>
	<pubDate>Wed, 13 Mar 2013 09:54:00 +0000</pubDate>
</item>
<item>
	<title>Murray Cumming: Maliit Keyboard Improvements</title>
	<guid>http://www.murrayc.com/?p=1893</guid>
	<link>http://www.murrayc.com/permalink/2013/03/04/maliit-keyboard-improvements/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=maliit-keyboard-improvements</link>
	<description>&lt;p&gt;On Friday I pushed 194 commits to the &lt;a href=&quot;https://gitorious.org/maliit/maliit-plugins&quot;&gt;Maliit Plugins&lt;/a&gt; repository, adding new features, bugfixes, cleanups and tests to the &lt;a href=&quot;http://www.maliit.org/&quot;&gt;Maliit&lt;/a&gt; Keyboard. This is some of the work &lt;a href=&quot;http://www.openismus.com/&quot;&gt;Openismus&lt;/a&gt; has done for &lt;a href=&quot;http://www.canonical.com/&quot;&gt;Canonical&lt;/a&gt; over the last few months which we are now allowed to upstream. This includes hard work by &lt;a href=&quot;http://mikhas.posterous.com/&quot;&gt;Michael Hasselmann&lt;/a&gt;, &lt;a href=&quot;http://krnowak.blogspot.com/&quot;&gt;Krzesimir Nowak&lt;/a&gt;, &lt;a href=&quot;http://blog.jpetersen.org/&quot;&gt;Jan Arne Petersen&lt;/a&gt; and &lt;a href=&quot;http://www.jonnor.com/&quot;&gt;Jon Nordby&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Our work on the underlying &lt;a href=&quot;https://gitorious.org/maliit/maliit-framework&quot;&gt;Maliit Framework&lt;/a&gt; for Canonical was published upstream as we did it. We believe we&amp;#8217;ll be able to upstream more of our Maliit Plugins work in the future.&lt;/p&gt;
&lt;p&gt;Versions of these Maliit Plugins commits were published a few days ago in the &lt;a href=&quot;https://code.launchpad.net/~phablet-team/phablet-extras/maliit-plugins&quot;&gt;Ubuntu Phablet project&amp;#8217;s maliit-plugins Launchpad/Bazaar repository&lt;/a&gt;. It also contains commits (not by us) on maliit-plugins&amp;#8217; &lt;a href=&quot;https://wiki.maliit.org/Plugins#Nemo_Keyboard&quot;&gt;Nemo Keyboard&lt;/a&gt;, mostly for integration with the Ubuntu Touch platform (and its use of Android&amp;#8217;s Surface Flinger). The recent Ubuntu Touch preview is using a version of that Nemo Keyboard, though we believe that&amp;#8217;s meant as a temporary solution. A properly integrated Maliit Keyboard should behave significantly better.&lt;/p&gt;
&lt;p&gt;Anyway, these commits add these features to the Maliit Keyboard:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Auto-capitalization&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Styling&lt;/strong&gt;, such as a black underline for the current word and a red underline for a word with an error, though its up to the toolkit exactly how it shows this.&lt;/li&gt;
&lt;li&gt;Word prediction, error correction, etc are now available when &lt;strong&gt;editing previously-entered words&lt;/strong&gt;, instead of just the next word, taking into account the surrounding words.&lt;/li&gt;
&lt;li&gt;Users can &lt;strong&gt;add words to the dictionary&lt;/strong&gt; with a long press on the space key.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;More settings&lt;/strong&gt; to enable/disable auto-capitalization, auto-correction, word prediction, error correction, audio feedback and whether the word ribbon should be disabled in portrait mode.&lt;/li&gt;
&lt;li&gt;Applications can specify &lt;strong&gt;text and icons for actions keys&lt;/strong&gt;, such as Done, Go, Login, etc.&lt;/li&gt;
&lt;li&gt;Keyboard themes can now specify &lt;strong&gt;fonts&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;a href=&quot;https://gitorious.org/maliit/maliit-plugins/blobs/master/NEWS&quot;&gt;maliit-plugins NEWS&lt;/a&gt; file gives more details.&lt;/p&gt;
&lt;p&gt;Many of these features were already in the old MeeGo Keyboard (used by the Nokia N9) which had to be dropped last year because of its libmeegotouch dependency and its need for proprietary plugins to achieve these features.&lt;/p&gt;
&lt;p&gt;We hope to have all this in an official Maliit release soon.&lt;/p&gt;</description>
	<pubDate>Mon, 04 Mar 2013 10:45:54 +0000</pubDate>
</item>
<item>
	<title>Murray Cumming: The Warmth Of Other Suns</title>
	<guid>http://www.murrayc.com/?p=1890</guid>
	<link>http://www.murrayc.com/permalink/2013/03/01/the-warmth-of-other-suns/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=the-warmth-of-other-suns</link>
	<description>&lt;p&gt;I have really enjoyed Isabella Wilkerson&amp;#8217;s &lt;a href=&quot;http://isabelwilkerson.com/the-book/&quot;&gt;The Warmth of Other Suns&lt;/a&gt;, which I &amp;#8220;read&amp;#8221; via &lt;a href=&quot;http://www.audible.com/pd/ref=sr_1_1?asin=B004RC37C0&amp;qid=1361783867&quot;&gt;Robin Miles&amp;#8217; excellent Audible narration&lt;/a&gt;. It&amp;#8217;s about the Great Migration of black people in the USA from the South to cities in the North and West, from the 20s to the 70s, told mostly via three personal stories in parallel.&lt;/p&gt;
&lt;p&gt;This is a huge part of American history that gets very little attention in popular culture, despite the wealth of supporting material due to it being such recent history. It&amp;#8217;s full of incredible stories of personal courage and adventure. People escaped awful injustices that should not be forgotten. They were often prevented from leaving rural towns in the South, where they were given no choice but to work hard for little pay, at regular risk of violent assault and death. For many, escaping seems to have been almost as hard as for people escaping the Eastern block during the Soviet era. But, unlike defectors, their escapes were not celebrated in the US.&lt;/p&gt;
&lt;p&gt;What&amp;#8217;s really forgotten is how hard it was for people to settle once they escaped. They had more opportunities but these were still limited and blacks were initially prevented from living in some neighborhoods or taking many jobs. This is yet another dramatic chapter to peoples&amp;#8217; stories.&lt;/p&gt;
&lt;p&gt;New distinctive communities were founded, and they should be celebrated by telling the stories of the people who built them. When I was in New York City over the summer, I found some time to visit Harlem at short notice with my young son. We walked around to get a feel for the place, and tried to join a &lt;a href=&quot;http://www.harlemheritage.com/&quot;&gt;Harlem Heritage Tour&lt;/a&gt;, but none were happening that day. It&amp;#8217;s a small organization that I&amp;#8217;d love to try again, but I cannot understand why no business has funded a massive tourist destination in Harlem that could be one of the big attractions on the &lt;a href=&quot;http://www.citypass.com/new-york&quot;&gt;New York CIty Pass &lt;/a&gt;along with the Empire State Building, Ellis Island, the Museum of Natural History, etc.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
	<pubDate>Fri, 01 Mar 2013 10:31:11 +0000</pubDate>
</item>
<item>
	<title>Murray Cumming: glibmm 2.35.8</title>
	<guid>http://www.murrayc.com/?p=1886</guid>
	<link>http://www.murrayc.com/permalink/2013/02/21/glibmm-2-35-8/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=glibmm-2-35-8</link>
	<description>&lt;p&gt;I found a little time to do the &lt;a href=&quot;http://git.gnome.org/browse/glibmm/commit/?id=8a3f2733ede5871ad98157a96c1ceb73794ebf2d&quot;&gt;first glibmm release in a few months&lt;/a&gt;. Kjell Allstedt and José Alburquerque have pushed so many commits, fixing several awkward bugs, that I had to get it out there. It includes almost no commits from me.&lt;/p&gt;
&lt;p&gt;Now to try rolling a gtkmm tarball.&lt;/p&gt;</description>
	<pubDate>Thu, 21 Feb 2013 11:41:42 +0000</pubDate>
</item>
<item>
	<title>Murray Cumming: OnlineGlom: MySQL support</title>
	<guid>http://www.murrayc.com/?p=1870</guid>
	<link>http://www.murrayc.com/permalink/2013/02/15/onlineglom-mysql-support/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=onlineglom-mysql-support</link>
	<description>&lt;p&gt;Of and on over the last couple of weeks, I have added MySQL support to &lt;a href=&quot;http://www.glom.org/wiki/index.php?title=Development/OnlineGlom&quot;&gt;OnlineGlom&lt;/a&gt;, like I recently &lt;a href=&quot;http://www.murrayc.com/permalink/2013/01/15/glom-experimental-mysql-support/&quot;&gt;added&lt;/a&gt; to Glom itself. Now it works and is in git master. When I have the time I&amp;#8217;ll try it out with Google&amp;#8217;s Cloud SQL (MySQL) in Google&amp;#8217;s App Engine.&lt;/p&gt;
&lt;p&gt;As with regular Glom, most of the work was getting the self-hosting tests to work with MySQL &amp;#8211; to start the MySQL instances, create the databases, fill them with data, test them and shut them down. The rest of the support was mostly covered already by &lt;a href=&quot;http://www.jooq.org/&quot;&gt;JOOQ&lt;/a&gt; but I had to make sure it always knew what SQL dialect to use.&lt;/p&gt;</description>
	<pubDate>Fri, 15 Feb 2013 14:40:26 +0000</pubDate>
</item>
<item>
	<title>Murray Cumming: Rygel Documentation</title>
	<guid>http://www.murrayc.com/blog/?p=1809</guid>
	<link>http://www.murrayc.com/permalink/2013/02/13/rygel-documentation/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rygel-documentation</link>
	<description>&lt;p&gt;Over the last few months, I have worked on &lt;a href=&quot;http://rygel-project.org/&quot;&gt;Rygel&lt;/a&gt;&amp;#8216;s documentation, along with &lt;a href=&quot;http://krnowak.blogspot.de/&quot;&gt;Krzesimir Nowak&lt;/a&gt; and &lt;a href=&quot;http://jensge.org/&quot;&gt;Jens Georg &lt;/a&gt;here at Openismus. Most of that work is now finished. It&amp;#8217;s been a great investment of time that should be of real benefit to the project.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ve massively improved &lt;a href=&quot;https://live.gnome.org/Rygel/#Developer_Features&quot;&gt;Rygel&amp;#8217;s (C) API documentation&lt;/a&gt;, which was rather bare after Rygel&amp;#8217;s initial split into shared libraries. We had to investigate how the current plugins use the API, and sometimes improved the API in response. (The very latest API documentation improvements will be online soon, when we do a new Rygel release.)&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ve added both simple and real-world examples, linking to them from sections in the API documentation and describing how those examples work. Those real-world examples are standalone GStreamer-0.10-based versions of the regular Rygel media engine and of its media-export server plugins, plus a GStreamer-0.10 version of the standalone renderer example.The original code for these (now using GStreamer-1.0) was in Vala, like the rest of Rygel, so we had to convert them to C. To maintain functionality, we chose to clean up the horribly-obfuscated C code generated by Vala. That took us a few frustrating weeks to finish but we got it done.&lt;/p&gt;
&lt;p&gt;The new &lt;a href=&quot;https://live.gnome.org/Rygel/Integration&quot;&gt;Rygel Integration&lt;/a&gt; page provides an overview of the APIs that platforms should find interesting, linking to the various documents that we&amp;#8217;ve created during this effort. That Integration page is part of a complete overhaul of Rygel&amp;#8217;s wiki project pages to make them more attractive and useful.&lt;/p&gt;
&lt;p&gt;To help with maintenance of Rygel itself, we now have a &lt;a href=&quot;https://live.gnome.org/Rygel/Architecture&quot;&gt;Rygel Architecture&lt;/a&gt; page with descriptions of Rygel&amp;#8217;s program flow in various situations, and a &lt;a href=&quot;https://live.gnome.org/Rygel/Architecture%20Diagram&quot;&gt;Rygel architecture diagram&lt;/a&gt; showing how the various parts of Rygel work together.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
	<pubDate>Wed, 13 Feb 2013 17:49:54 +0000</pubDate>
</item>
<item>
	<title>Tristan Van Berkom: Where did my memory go ? – A detective story</title>
	<guid>http://blogs.gnome.org/tvb/?p=390</guid>
	<link>http://blogs.gnome.org/tvb/2013/02/12/where-did-my-memory-go-a-detective-story/</link>
	<description>&lt;p&gt;Here, is yet another &lt;a href=&quot;http://blogs.gnome.org/tvb/2013/02/04/an-exercise-in-memory-consumption-analysis/&quot;&gt;follow up post&lt;/a&gt; on &lt;a href=&quot;http://blogs.gnome.org/tvb/2013/01/15/getting-your-contacts-right-now/&quot;&gt;EDS memory consumption&lt;/a&gt;. For the last few days I&amp;#8217;ve been tracking where memory is spent in EDS and our benchmarking tools, and it was a very interesting experience.&lt;/p&gt;
&lt;p&gt;And I&amp;#8217;m not just saying that ! it was very trying and it&amp;#8217;s still a bit of an unsolved mystery to me (so please feel free to step in with your theories on the unsolved parts !).&lt;/p&gt;
&lt;p&gt;It all started when Michael asked me to explain the funny spikes in the memory usage graph presented in the previous post. The first thing I did was to produce a more &amp;#8220;bumpy&amp;#8221; graph by disabling the slice allocator, yielding what is in some ways a more accurate account of actual memory usage:&lt;/p&gt;
&lt;div id=&quot;attachment_391&quot; class=&quot;wp-caption aligncenter&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-12800-always-malloc.png&quot;&gt;&lt;img class=&quot; wp-image-391  &quot; alt=&quot;Memory usage measured for 12,800 contacts with G_SLICE=always-malloc&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-12800-always-malloc.png&quot; width=&quot;593&quot; height=&quot;244&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Memory usage measured for 12,800 contacts with G_SLICE=always-malloc&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;Interestingly, I say &amp;#8220;in some ways&amp;#8221; above because; one of the elements that we have to consider is memory fragmentation; memory management is generally more optimal and less fragmented when the slice allocator is active.&lt;/p&gt;
&lt;p&gt;What we are looking at above is a left to right graph of overall memory usage; measured after each and every operation that we run on the addressbook. Each &amp;#8220;dot&amp;#8221; can be associated to one of the various latency tests that we run for each and every build of EDS (indicated in the legend).&lt;/p&gt;
&lt;p&gt;First of all let&amp;#8217;s demystify the &amp;#8220;curious humps&amp;#8221; which occur mostly to the &amp;#8220;Custom Light&amp;#8221; (light blue) benchmarks but are also noticeable in other benchmarks. These &amp;#8220;humps&amp;#8221; occur for four dots at a time, particularly when performing suffix searches on contact fields that are not stored in the summary SQLite tables for quick searches.&lt;/p&gt;
&lt;p&gt;This phenomenon is partly attributable to the fact that all contacts in the addressbook need to be individually examined (and the vcards individually parsed) when the given contact field is not stored in the SQLite tables individually (or what we refer to in EDS terms as &amp;#8220;the summary&amp;#8221;). I&amp;#8217;m not really very concerned by these &amp;#8220;spikes&amp;#8221;; obviously the memory is reclaimed later on, however it is curious that this happens specifically for suffix matching and not for prefix matching (presumably lot&amp;#8217;s of extra string duplications and normalizations are needed for the case insensitive suffix matching routines).&lt;/p&gt;
&lt;p&gt;Now that that&amp;#8217;s out of the way, it leads us to some of the&amp;#8230;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;More interesting parts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I was at first not satisfied with only this explanation, sure, it kindof explains the &amp;#8220;funny humps&amp;#8221; in the benchmark progress but&amp;#8230; by taking a closer look at what else is actually happening&amp;#8230; I needed a better explanation.&lt;/p&gt;
&lt;p&gt;The portions of the presented memory usage graphs that interest me more are the memory growth observable over the course of the first four dots, as well as the curious memory growth that also occurs at the very end of the benchmarks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;So what is happening in these stages ?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;First of all, it&amp;#8217;s positive news to know that the number of automatically generated vcards used for testing are already in memory before the benchmarks start at all, in the above graph that represents 12,800 vcards all in memory before the first benchmark is measured. And then&amp;#8230;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The addressbook is initialized and created, so at the point of measuring the very first dot, we have 12,800 vcards in memory &lt;em&gt;and &lt;/em&gt;an initialized EBookClient on the client side &lt;em&gt;and&lt;/em&gt; an addressbook counterpart (SQLite database created and active SQLite connection) in the server side memory&lt;/li&gt;
&lt;li&gt;Next, at the second dot we&amp;#8217;ve created 12,800 EContact objects in memory&amp;#8230; the 12,800 EContacts &lt;em&gt;and &lt;/em&gt;12,800 vcard strings remain in memory throughout the benchmark progress. This second dot is about 45MB higher on the scale than the first dot, so it&amp;#8217;s pretty safe to say that 12,800 EContact objects cost roughly 45MB of resident memory which will not be reclaimed for the duration of the benchmark progress.&lt;/li&gt;
&lt;li&gt;The third dot is measured directly after adding all the contacts to the addressbook, here we start to see some divergence in memory usage; notice that this costs roughly 25MB extra for EBookClient based benchmarks, but only about 5MB for EBook based benchmarks. Being a bit naive, I overlooked this detail at the beginning of the investigation&amp;#8230; one of the notable differences in the EBook apis is that it was lacking in batch commands. So the major difference here is that EBook tests add contacts one by one over D-Bus, while the EBookClient tests add contacts in batches of 3200 contacts at a time.&lt;/li&gt;
&lt;li&gt;This fourth dot, is after fetching &lt;strong&gt;all contacts&lt;/strong&gt; at once from the addressbook. Here is where I became seriously alarmed. For normal clients, this shows an approximate &lt;em&gt;30MB growth in memory consumption&lt;/em&gt;. So where did my memory go ? A simple case of amnesia ?! Note though, that the Direct Read Access (red) benchmark hardly increases in memory for a fetch of 12,800 contacts, good show.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Naturally, feeling embarrassed about the consequences of the evil fourth dot&amp;#8230; I frantically started my search for memory leaks&amp;#8230; first I blamed the obscure nature of C++ code and it&amp;#8217;s attempts to hide memory management behind smart pointers&amp;#8230;I tried to pin it as a memory leak in the actual benchmarking code (after all, I did just lose 30MB of memory&amp;#8230; it must have gone somewhere&amp;#8230; right ?)&amp;#8230; but after some tracing around, I found that those returned contacts, stored by smart pointers or not, were properly finalized and freed, leaving me with this uncomfortable mystery still on my hands.&lt;/p&gt;
&lt;p&gt;While most of my memory leak hunt revolved around explaining the 30MB memory overhead incurred from dot 3 to dot 4, I should mention that the last memory jump was also suspicious. This last memory jump (which seems to vary between a 10MB to 25MB increase depending on the benchmark type) is incurred by deleting all contacts in the addressbook. So how about that ? I&amp;#8217;ve just deleted all the contacts, and now I&amp;#8217;m using MORE memory than before ?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The following day&amp;#8230;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;#8230; I ran the benchmarks in loops, for some I&amp;#8217;ll share below because this is how I eventually solved the mystery case, I also ran the benchmarks (server and client) under valgrind, ran some various test cases with the server and test cases running under valgrind. But the alleged memory leak was not to be tracked. Some testing of the benchmarks running in a loop seemed to indicate that there was some memory growth over time, not very much so, but enough to make me believe there must be some leak and be determined to find out.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Finally, today&amp;#8230;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;#8230; I let my laptop chug along and loop the benchmarks (at least some of them) with a huge 12,800 contact count (that takes time), so let&amp;#8217;s share those enlightening results here:&lt;/p&gt;
&lt;div id=&quot;attachment_392&quot; class=&quot;wp-caption aligncenter&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-12800-1.png&quot;&gt;&lt;img class=&quot; wp-image-392&quot; alt=&quot;&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-12800-1.png&quot; width=&quot;593&quot; height=&quot;239&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Memory usage while benchmarking 12,800 contacts in the first iteration&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;attachment_393&quot; class=&quot;wp-caption aligncenter&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-12800-2.png&quot;&gt;&lt;img class=&quot; wp-image-393  &quot; alt=&quot;Memory usage benchmarking 12,800 contacts in the second iteration&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-12800-2.png&quot; width=&quot;593&quot; height=&quot;237&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Memory usage benchmarking 12,800 contacts in the second iteration&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;attachment_394&quot; class=&quot;wp-caption aligncenter&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-12800-3.png&quot;&gt;&lt;img class=&quot; wp-image-394  &quot; alt=&quot;Memory usage benchmarking 12,800 contacts in the third iteration&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-12800-3.png&quot; width=&quot;593&quot; height=&quot;237&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Memory usage benchmarking 12,800 contacts in the third iteration&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;These results would be better viewed from left to right instead of one on top of the other, but you get the idea. Just consider that the last dot in the first chart happens directly before the first dot in the following chart, and so on.&lt;/p&gt;
&lt;p&gt;So, after viewing this data&amp;#8230; we can see that in the second and third graph, memory we presumed to be lost, is eventually returned to the system (in other words, it was indeed only a case of temporary amnesia, and not a more severe degrading case of alzheimer&amp;#8217;s)&amp;#8230; This is very reassuring, numerous runs with valgrind also show no real evidence of memory leakage, which is also reassuring evidence that our EDS is leak free.&lt;/p&gt;
&lt;p&gt;But, that still doesn&amp;#8217;t really explain&amp;#8230;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where is that memory actually going ?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;At this point I can only give you my best guess, but all of the clues seem to point towards D-Bus traffic:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;At the second &amp;#8220;dot&amp;#8221; where contacts are added to the addressbook, EBook APIs adding only a single contact at a time seems to cost much much less than using EBookClient apis and adding the contacts in batches of 3200 contacts at a time.&lt;/li&gt;
&lt;li&gt;At the third &amp;#8220;dot&amp;#8221; where a brute &amp;#8220;fetch all contacts&amp;#8221; call is made to the addressbook, we can see a huge increase in memory consumption all except for when using Direct Read Access mode. So when fetching a list of 12,800 contacts &lt;strong&gt;not &lt;/strong&gt;using D-Bus, we don&amp;#8217;t suffer from memory loss.&lt;/li&gt;
&lt;li&gt;In the last suspicious &amp;#8220;dot&amp;#8221;, where we delete all contacts from the addresssbook at once, all benchmark types seem to suffer significant memory loss. In this case the client is sending a list of 12,800 contact UIDs over D-Bus to the addressbook (in Direct Read Access as well, since deleting contacts is a write operation).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My best guess ? this is all due to zero-copy IPC transfers implemented by D-Bus.&lt;/p&gt;
&lt;p&gt;In other words (if you&amp;#8217;ve read up to this point you probably don&amp;#8217;t need any explanation), instead of the sender writing chunks of data to a socket, and the receiver reading bytes from a socket; the sender is owning some shared memory which is accessed directly by the receiver.&lt;/p&gt;
&lt;p&gt;This shared memory is probably managed by the D-Bus daemon itself, so it would make sense that the daemon not release the shared memory straight away but instead reserve some head room in the case that further transfers might reuse that memory.&lt;/p&gt;
&lt;p&gt;So how come the fourth dot where a batch of 12,800 vcards are passed to the client, is not reused by the last dot where all contacts are deleted ? &amp;#8230; Because, when contacts are fetched the shared memory owner would have to be the sender, which is the addressbook server. However when contacts are deleted, it is the EBookClient user process which sends a list of 12,800 UIDs, in this case the owner of the shared memory should be the other, client process.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ll probably need to pursue some extra verifications to be sure, but this best guess is very compelling to me at this time.&lt;/p&gt;
&lt;p&gt;In conclusion, this was a really interesting exercise, which I don&amp;#8217;t hope to repeat very often&amp;#8230; but I did learn a few things and it did put some things into perspective. First and foremost; measuring memory usage, when compared to just tracking and plugging leaks, is quite another story&amp;#8230; a lot more tricky and probably not an exact science.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;ve got this far, I hope you&amp;#8217;ve enjoyed this detective story&amp;#8230; I did enjoy it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Amendments&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s probably bad form but I&amp;#8217;ll just add this here, my theory is obviously false. As I&amp;#8217;ve been informed (already) that D-Bus does not implement any such zero-copy mechanisms with shared memory&amp;#8230; so there is still a huge memory fluxuation, definitely related to D-Bus usage, which I can&amp;#8217;t readily explain.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
	<pubDate>Tue, 12 Feb 2013 13:47:44 +0000</pubDate>
</item>
<item>
	<title>Murray Cumming: Trying Google Apps For Education</title>
	<guid>http://www.murrayc.com/?p=1868</guid>
	<link>http://www.murrayc.com/permalink/2013/02/07/trying-google-apps-for-education/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=trying-google-apps-for-education</link>
	<description>&lt;p&gt;At Liam&amp;#8217;s new Kindergarten, I&amp;#8217;m responsible for the computer stuff. So I thought I&amp;#8217;d make things easier by using &lt;a href=&quot;http://www.google.com/enterprise/apps/education/&quot;&gt;Google Apps, which is free for educational institutions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;My aims were to have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Official email accounts, without the bother of managing our own email server. (Google Mail)&lt;/li&gt;
&lt;li&gt;Mailing lists (or groups) so we can send mail to one parents@ email address instead of copy/pasting long CC lists.&lt;/li&gt;
&lt;li&gt;An online calendar that we could use to show official events, which could show up on peoples&amp;#8217; iPhones and Android phones. (Google Calendar)&lt;/li&gt;
&lt;li&gt;A shared space for official documents. (Google Drive)&lt;/li&gt;
&lt;li&gt;Private photo galleries. They can&amp;#8217;t be public because people don&amp;#8217;t like pictures of their children being online. (Google&amp;#8217;s PicasaWeb, I hoped)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I was really looking forward to playing with this stuff, hoping that it would quickly do useful things, and hoping that it would be easier for non-technical people to administer when I&amp;#8217;m not around. But I&amp;#8217;ve been rather disappointed.&lt;/p&gt;
&lt;p&gt;The various problems lead to me having to choose between two options, both of them inadequate:&lt;/p&gt;
&lt;h3&gt;Option 1: Domain users&lt;/h3&gt;
&lt;p&gt;In this scenario, I would add someone@ourdomain.com accounts for all of the parents.&lt;/p&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We would be able to see all contact details for parents and teachers in the &amp;#8220;Directory&amp;#8221;. That would be available on peoples&amp;#8217; Android phones, too, and maybe on iPhones.&lt;/li&gt;
&lt;li&gt;We could use PicasaWeb to share photos and view them as galleries.&lt;/li&gt;
&lt;li&gt;System administration would generally be easier. The simplicity makes&lt;br /&gt;
it easier to avoid sharing something publicly by accident.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We would give everyone an @ourdomain.com Google account. That would give them a @ourdomain.com email address, using GMail, which would be useless to them. Parents would each have to manually set up GMail to forward to their personal email address, though I could tell them how to do that.&lt;br /&gt;
(You could send email to &lt;a href=&quot;mailto:someparent@peschool.de&quot;&gt;some.parent@ourdomain.com&lt;/a&gt;, but when they replied, you would see them replying from their &lt;a href=&quot;mailto:someparent@hotmailorsomething.com&quot;&gt;some.parent@hotmailorsomething.com &lt;/a&gt;email address.)&lt;/li&gt;
&lt;li&gt;If parents already have a Google account, they would need to switch between them in the web browser. That&amp;#8217;s fairly easy using Google&amp;#8217;s multiple sign-in, but that does not work well right now. Sometimes you&amp;#8217;ll find yourself using the other account suddenly.&lt;br /&gt;
It&amp;#8217;s a particular problem for Google Apps that don&amp;#8217;t support multiple-sign in, but real people do use those apps. For instance:&lt;/li&gt;&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;If you click on a link to a PicasaWeb album, you&amp;#8217;ll just be told that the album doesn&amp;#8217;t exist, until you log out, log in as the other user, and try again. That is beyond the abilities of the typical user.&lt;/li&gt;
&lt;li&gt;Google Checkout, used when buying from Google Play, will offer a choice of users to log in as, but I&amp;#8217;ve regularly seen it ignore your choice and continue as the wrong user.&lt;/li&gt;
&lt;li&gt;When going to the GMail site, if you are logged in as a user with no gmail email address, it will offer to create one for you with a &amp;#8220;Add Gmail to your Google Account&amp;#8221; page. If you try to switch users to the user with a GMail account, it will just take you back to the same page for the previous user.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Option 2: Non-domain group members&lt;/h3&gt;
&lt;p&gt;In this scenario, I would not add someone@ourdomain.com accounts for all of the parents.&lt;/p&gt;
&lt;p&gt;Instead I would add their regular email addresses as members of groups such as parents@ourdomain.com. The various Google Apps seem to allow sharing to group email addresses, understanding that that means sharing to the group&amp;#8217;s members, though that&amp;#8217;s not documented or hinted at.&lt;/p&gt;
&lt;p&gt;The parents would have to create Google accounts for these non-Google email addresses, which is still possible via this link to &lt;a href=&quot;https://accounts.google.com/newaccount&quot;&gt;create a Google account without being forced to have a Google email account&lt;/a&gt;, though that link might not work in future. (&lt;strong&gt;Update&lt;/strong&gt; from 2013/04: Indeed, it doesn&amp;#8217;t work now, so you have to &lt;a href=&quot;http://support.google.com/accounts/bin/answer.py?hl=en&amp;answer=61177&quot;&gt;disable the gmail email address&lt;/a&gt; after creating the Google account.)&lt;/p&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;People could use their existing Google accounts and existing email addresses.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We could not use Google&amp;#8217;s contacts system to share a list of contacts. We&amp;#8217;d have to maintain a separate list on a web page. It wouldn&amp;#8217;t be available in the normal way on an Android or iPhone phone.&lt;br /&gt;
This just isn&amp;#8217;t possible with Google Apps unless all the people have domain accounts, with domain email addresses. Google recommend the use of 3rd-party web applications that let you manually sync address books every now and then, but that&amp;#8217;s not good enough.&lt;/li&gt;
&lt;li&gt;We could not use PicasaWeb to share photos. We could use Google Drive&lt;br /&gt;
instead, but this doesn&amp;#8217;t offer a gallery view showing sets of photos&lt;br /&gt;
with back/forward, etc.&lt;br /&gt;
This is because PicasaWeb does not support sharing to a Google Apps group. You can only share to users in your domain, or you can share via an obfuscated, but public, URL.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;For now, I find that Google&amp;#8217;s multiple sign in is so awful that I cannot risk asking people to deal with it and cannot risk having to support them with it. Therefore, I have to live with sharing photos via Google Drive instead of PicasaWeb, and having no shared contacts list.&lt;/p&gt;
&lt;p&gt;I feel that we wouldn&amp;#8217;t have this problem if Google Apps really supported domains rather than just using redirects. For instance, I&amp;#8217;d like to use email at mail.ourdomain.com, instead of typing that into my browser&amp;#8217;s address bar only to be taken to mail.google.com/mail/u/0/?shva=1#inbox . A real domain would have its own users and there would be no conflict with regular Google users. Obviously that would be harder for Google to do.&lt;/p&gt;
&lt;p&gt;Things would also be simpler if PicasaWeb supported multiple-sign in, and if it supported sharing to groups. Or if Google Drive allowed image files to be viewed via PicasaWeb. It&amp;#8217;s to be expected that educational institutions will want to share photos privately. I wanted to use that as an attractive way to get people into the system.&lt;/p&gt;
&lt;p&gt;It should also be expected that educational institutions, like many organizations, want to deal with people who will never have an official email address for that organization.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
	<pubDate>Thu, 07 Feb 2013 13:21:20 +0000</pubDate>
</item>
<item>
	<title>Michael Hasselmann: FOSDEM 2013</title>
	<guid>http://mikhas.posterous.com/fosdem-2013</guid>
	<link>http://mikhas.posterous.com/fosdem-2013</link>
	<description>&lt;p&gt;
	&lt;p&gt;I am back from &lt;a href=&quot;https://fosdem.org/2013/&quot;&gt;FOSDEM&lt;/a&gt; and I am always surprised how quickly it&amp;rsquo;s all over. Would you believe that I only got to attend two talks again, one of them being my own about Wayland input methods?&lt;/p&gt;

&lt;h2&gt;Friday Feb 1st&lt;/h2&gt;

&lt;p&gt;I arrived Friday evening, this time by train. Since I bought my first BahnCard ever in August last year, I am slowly convinced now that flying is just a huge waste of time and should be the last possibility to consider, not the first. Even though I spend much more time on the train than I would on the airplane I still travel more relaxed. Others claim to be super-productive on trains. I am happy enough if I get to braindump my thoughts into my notebook (the dead-tree variant) and then read a book (more dead-tree) to forget about work for once.&lt;/p&gt;

&lt;p&gt;Another trick for better conferencing is to arrive (or leave) 1-2 days earlier (later), as this helps catching up with sleep and allows to process thoughts or just do some random stuff not related to conferencing, say, going to a museum or gallery. It allows me to be reckless to myself during the conference without needing one week to recover.&lt;/p&gt;

&lt;p&gt;But back to that Friday evening: I was very happy that &lt;a href=&quot;https://plus.google.com/100920064738447422284/posts&quot;&gt;Quim&lt;/a&gt; could make it to our dinner at the Kabash. I knew he had a busy schedule for the next days and that I probably wouldn&amp;rsquo;t be able to meet him in Berlin. I think he enjoys working for Wikimedia even though he now has to pay for phone calls and 3G. We also had people from Igalia, Digia and Intel OTC joining. We enjoyed great food and nice conversations, then headed off to the beer event. This one has become crazily crowded. It&amp;rsquo;s nigh impossible to find people you know. Meeting new people is also a challenge. The entire concept of what should be a simple meet&amp;amp;greet is lost these days.&lt;/p&gt;

&lt;h2&gt;Saturday Feb 2nd&lt;/h2&gt;

&lt;p&gt;Jens and I arrived around 10am at the campus on Saturday, probably a first for both of us to be so early. It was so empty you could think they&amp;rsquo;d cancelled FOSDEM but that quickly changed of course. I had zero slides done by then and no motivation to do them either. I went to &lt;a href=&quot;https://fosdem.org/2013/schedule/event/onlineaccounts/&quot;&gt;Dave&amp;rsquo;s talk&lt;/a&gt; and it was nice to see him and &lt;a href=&quot;http://blog.mardy.it/&quot;&gt;Mardy&lt;/a&gt; working on a relevant project again. As expected, GOA is dead in the water by now and work will most likely continue with accounts-sso. I realized that I would have to recycle an older talk for some slides, something I loathe to do.&lt;/p&gt;

&lt;p&gt;Somewhere in between I had to meet some OpenEmbedded guys to debug Maliit on their custom hardware, but we didn&amp;rsquo;t get much further than realizing that dlopen() didn&amp;rsquo;t work properly.&lt;/p&gt;

&lt;p&gt;Funniest thing that happened that Saturday was probably rasterman, timj and thiago &lt;a href=&quot;https://plus.google.com/108138837678270193032/posts/aoJSdjd49En&quot;&gt;trashing-talking about the kernel&lt;/a&gt; when they could have told each other how much their toolkits suck!&lt;/p&gt;

&lt;p&gt;Biggest reveal of the day, however, was that &lt;a href=&quot;http://uk.linkedin.com/in/robtaylor78&quot;&gt;Rob Taylor&lt;/a&gt; toured with the Darkness in his crazier years.&lt;/p&gt;

&lt;p&gt;Jens was unlucky with his &lt;a href=&quot;https://fosdem.org/2013/schedule/event/hands_on_dlna/&quot;&gt;hands-on DLNA talk&lt;/a&gt;, but I blame it on the room (Lameere). I remember that my talk there last year was crap, too. None of his prepared demos worked and people started to leave the room. I felt bad for him because I the was one who pushed him into giving the talk. Mark took over the second half and surprisingly, all of his &lt;a href=&quot;https://01.org/dleyna/&quot;&gt;dLeyna demos&lt;/a&gt; worked. He got applause (and rightfully so) for each of them.&lt;/p&gt;

&lt;p&gt;I only had two hours left by then for &lt;a href=&quot;https://fosdem.org/2013/schedule/event/waylandinput/&quot;&gt;my talk&lt;/a&gt; &lt;a href=&quot;http://taschenorakel.de/files/michael/fosdem2013/wayland-input-methods/wayland-input-methods.pdf&quot;&gt;(slides)&lt;/a&gt;. Meeting more people all the time didn&amp;rsquo;t exactly help with my preparations. I was close to call &lt;a href=&quot;http://libv.livejournal.com/&quot;&gt;Luc&lt;/a&gt; (organizer of the Xorg DevRoom) and ask him to cancel my talk. I am glad I didn&amp;rsquo;t because it turned out that worrying about my talk for the whole day was the best way to get back into the topic. You have to understand that Wayland input methods is a yesteryears project for me, all the hard thoughtwork as been done already and I have been mostly working on new projects since August last year. I think the talk was well received by the audience (at least the room was packed). However, I cheated by simplifying and ignoring the actual complexity of input methods a bit.&lt;/p&gt;

&lt;p&gt;It was already getting late and by the time we arrived in Brussels center it was about time to head to the Gnome party. Same place at last year, but by around 11pm we had occupied the whole building. I didn&amp;rsquo;t even know half the guys. Gut feeling tells me this is a side effect of the UX hackfest that happend before, but I would like to believe that the Gnome community is growing again. It was great to see Gnome legends such as Federico or Alp attending, I think both of whom I had last (and first) seen in 2008.&lt;/p&gt;

&lt;h2&gt;Sunday Feb 3rd&lt;/h2&gt;

&lt;p&gt;I thought I&amp;rsquo;d be able to attend a couple of talks on Sunday, but I got stuck talking to people interested in actually working open-source DLNA stacks. I got invited to join the Xorg dinner in the evening, with half of the people being BSD guys. Xorg? BSD? I was fearing for my sanity. Some other embarassment might better be left unmentioned in this blog but the food and wine at least was great! Afterwards we ended up at Delirium again (where else …). At 2am we had to move to the Absinthe bar right next to Delirum. Wiser men than me (such as &lt;a href=&quot;http://hoegsberg.blogspot.com&quot;&gt;krh&lt;/a&gt; and &lt;a href=&quot;https://github.com/robclark&quot;&gt;Rob Clark&lt;/a&gt;, who now works for Red Hat!) left before, however. And so we ended up with more beer and several shots of Absinthe until the wee morning hours. Jon made the mistake at that point to ask me about my honest opinion (I actually don&amp;rsquo;t know why he tagged along with the Xorg hackers for so long), he might regret that by now. Wrong time, wrong place. Happens.&lt;/p&gt;

&lt;h2&gt;Monday Feb 4th&lt;/h2&gt;

&lt;p&gt;I had to checkout at 11am and get my train at 2:30pm. How I managed to get up by 11:15am I still don&amp;rsquo;t know. But luckily I was able to meet with &lt;a href=&quot;http://www.flickr.com/photos/kitty-kat/&quot;&gt;Kat&lt;/a&gt;, &lt;a href=&quot;http://amigadave.com/&quot;&gt;Dave&lt;/a&gt;, &lt;a href=&quot;https://launchpad.net/~gz&quot;&gt;Martin&lt;/a&gt; &amp;amp; &lt;a href=&quot;https://live.gnome.org/TobiasMueller&quot;&gt;Tobias&lt;/a&gt; for some &lt;a href=&quot;http://www.flickr.com/photos/14202311@N00/3298742383/&quot;&gt;waffle &amp;amp; chocolate&lt;/a&gt; breakfast. This was a much better FOSDEM ending than last year.&lt;/p&gt;

&lt;p&gt;Tobias chose the same ICE train as me. Poor him, he had no idea what was coming for him: He had to endure my satirical reality talk from Brussels to Cologne. Both of us had to change trains then, with him heading off to Hamburg and me returning to Berlin. I wish I could have made it back a couple hours earlier now because I missed &lt;a href=&quot;https://plus.google.com/112600856203361414399/posts/jG2WuxcqQXe&quot;&gt;Quim&amp;rsquo;s presentation&lt;/a&gt; in the Wikimedia office.&lt;/p&gt;

&lt;p&gt;Exhausted but happy, I finally arrived at home on Monday night.&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://mikhas.posterous.com/fosdem-2013&quot;&gt;Permalink&lt;/a&gt; 

	| &lt;a href=&quot;http://mikhas.posterous.com/fosdem-2013#comment&quot;&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;</description>
	<pubDate>Wed, 06 Feb 2013 08:05:00 +0000</pubDate>
</item>
<item>
	<title>Tristan Van Berkom: An exercise in memory consumption analysis</title>
	<guid>http://blogs.gnome.org/tvb/?p=358</guid>
	<link>http://blogs.gnome.org/tvb/2013/02/04/an-exercise-in-memory-consumption-analysis/</link>
	<description>&lt;p&gt;Hi again.&lt;/p&gt;
&lt;p&gt;This is a follow up on my recent post on &lt;a href=&quot;http://blogs.gnome.org/tvb/2013/01/15/getting-your-contacts-right-now/&quot;&gt;features and improvements to the Evolution Data Server&lt;/a&gt; that we&amp;#8217;ve been working on at Openismus. Note that the previous post explains what we&amp;#8217;ve done in greater detail, some of this post might not make sense without reading the aforementioned post.&lt;/p&gt;
&lt;p&gt;As I was asked to write a more complete report on how each of our patch sets effect memory consumption in EDS, I went ahead and ran some further comparisons. As usual, Mathias&amp;#8217; &lt;a href=&quot;http://taschenorakel.de/mathias/2012/06/20/performance-and-memory-usage-of-evolution-data-server/&quot;&gt;benchmarks&lt;/a&gt; saved the day (while the original benchmark suite only generates memory consumption comparisons for a single run of contacts, I was easily able to produce charts for each individual run and compare them separately).&lt;/p&gt;
&lt;p&gt;Actually I had postponed this post since I was hoping to update our final &lt;a href=&quot;https://bugzilla.gnome.org/show_bug.cgi?id=686681&quot;&gt;patch set for Direct Read Access&lt;/a&gt; apis before reporting my findings. It seems however that currently EDS master is in a period of transition and so I&amp;#8217;ll postpone the new patch submissions until some temporary regressions in EDS are fixed (the code which does work with EDS master is however available &lt;a href=&quot;http://git.gnome.org/browse/evolution-data-server/log/?h=openismus-work-master&quot;&gt;on the branch&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Memory Usage Report&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In order to get a grasp of the impacts on memory consumption that each patch set incurs, I&amp;#8217;ve added two additional benchmarks to our normal set of benchmarks.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;No BDB&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This is a custom build of EDS gnome-3-6 branch with the removal of the BDB usage in the local file backend.&lt;/p&gt;
&lt;p&gt;At this point there is no extra table in the SQLite to handle multi-valued vCard attributes, it&amp;#8217;s simply a comparison of storing the vCard data in the BDB vs SQLite only.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Custom Light&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This is a special run of our regular openismus-work branch, but with only the &amp;#8220;Full Name&amp;#8221; configured and indexed in the summary.&lt;/p&gt;
&lt;p&gt;So this benchmark is a light-weight summary with considerably less columns (and one less table) used in the SQLite.&lt;/p&gt;
&lt;p&gt;I ran this variation in the suspicion that SQLite might require significantly more memory with the additional multi-value table created to handle multi-valued attributes such as E_CONTACT_TEL.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Benchmark Results&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Note that the RSS and VMS memory snapshots are taken by way of observing the /proc/$pid/status file for both the EDS server process and client benchmark process directly after stopping the clock for each benchmark in the suite. So a given value in the charts presented below is based on the &amp;#8220;VmRSS&amp;#8221; value of the server process added to the &amp;#8220;VmRSS&amp;#8221; value of the client process.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;First, let&amp;#8217;s show the results, or at least some of them, to put our deductions into context:&lt;/p&gt;
&lt;div id=&quot;attachment_359&quot; class=&quot;wp-caption aligncenter&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-rss-00050.png&quot;&gt;&lt;img class=&quot; wp-image-359   &quot; alt=&quot;50 Contacts&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-rss-00050.png&quot; width=&quot;474&quot; height=&quot;190&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;50 Contacts&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&amp;#8230; Skipping a few results here in the interest of avoiding clutter &amp;#8230; lets jump directly to 400 contacts &amp;#8230;&lt;/p&gt;
&lt;div id=&quot;attachment_362&quot; class=&quot;wp-caption aligncenter&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-rss-00400.png&quot;&gt;&lt;img class=&quot; wp-image-362  &quot; alt=&quot;memory-usage-rss-00400&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-rss-00400.png&quot; width=&quot;474&quot; height=&quot;190&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;400 Contacts&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;attachment_364&quot; class=&quot;wp-caption aligncenter&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-rss-00800.png&quot;&gt;&lt;img class=&quot; wp-image-364   &quot; alt=&quot;800 Contacts&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-rss-00800.png&quot; width=&quot;474&quot; height=&quot;190&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;800 Contacts&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;attachment_365&quot; class=&quot;wp-caption aligncenter&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-rss-01600.png&quot;&gt;&lt;img class=&quot; wp-image-365   &quot; alt=&quot;1600 Contacts&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-rss-01600.png&quot; width=&quot;474&quot; height=&quot;190&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;1600 Contacts&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;attachment_366&quot; class=&quot;wp-caption aligncenter&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-rss-03200.png&quot;&gt;&lt;img class=&quot; wp-image-366   &quot; alt=&quot;3200 Contacts&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-rss-03200.png&quot; width=&quot;474&quot; height=&quot;190&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;3200 Contacts&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;attachment_367&quot; class=&quot;wp-caption aligncenter&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-rss-06400.png&quot;&gt;&lt;img class=&quot; wp-image-367   &quot; alt=&quot;6400 Contacts&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-rss-06400.png&quot; width=&quot;474&quot; height=&quot;190&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;6400 Contacts&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;attachment_368&quot; class=&quot;wp-caption aligncenter&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-rss-12800.png&quot;&gt;&lt;img class=&quot; wp-image-368   &quot; alt=&quot;12800 Contacts&quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/02/memory-usage-rss-12800.png&quot; width=&quot;474&quot; height=&quot;191&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;12800 Contacts&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;And now, some of the conclusions I came to while observing the results&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;BDB Removal&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When compared to the unmodified EDS 3.6 branch, we can observe that the BDB removal reduces memory consumption for most reasonably sized address books. Up until we run the benchmark for 3,200 contacts, memory consumption is less without BDB&amp;#8230; with 3,200 contacts and higher, memory consumption is increased by removing the BDB.&lt;/p&gt;
&lt;p&gt;Without an in depth understanding of SQLite internals, I think we can deduce that the SQLite starts to require more memory to handle databases with &amp;gt;= 3,200 rows&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Custom Light&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This benchmark basically disproved my suspicion.&lt;/p&gt;
&lt;p&gt;While using exactly the same code-base as the &amp;#8220;EDS Custom&amp;#8221; and &amp;#8220;EDS Custom DRA&amp;#8221; benchmarks; Using more indexes and tables in the SQLite does not seem to incur much of a difference in terms of memory consumption.&lt;/p&gt;
&lt;p&gt;While the output is certainly different, as specially with large addressbooks, I don&amp;#8217;t see much of a noticeable pattern here.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;EDS Custom&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This benchmark is basically the openismus-work branch with fully customized indexes for better performance in telephone number lookups.&lt;/p&gt;
&lt;p&gt;When comparing this one to the unmodified EDS 3.6 benchmark, we can observe that memory consumption is slightly less using the custom EDS code than stock EDS 3.6.&lt;/p&gt;
&lt;p&gt;When comparing this to the removal of BDB, we can notice that, as specially for small addressbooks, the base memory requirement of the EDS Custom is significantly higher than with only the BDB removal.&lt;/p&gt;
&lt;p&gt;This second point is easily explainable, since removal of BDB alone reduces the overall memory footprint of EDS. The custom EDS benchmarks, without actually leveraging the Direct Read Access mode still links against the EDataBook library. Essentially this replaces the memory footprint overhead incurred by linking to BDB with a different overhead incurred by linking directly with EDataBook.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;EDS Custom DRA&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This benchmark is particularly interesting.&lt;/p&gt;
&lt;p&gt;For smaller addressbooks the Direct Read Access mode indeed costs more resident memory than any other benchmark. This can be attributed at least partly to the penalty of loading an EDataBook into memory on the client side. Consequently, loading the EDataBook also loads the backend module in the client process, meaning we also have a running EBookBackendFile in the client as well as client side linkage and usage of the SQLite library.&lt;/p&gt;
&lt;p&gt;However, once we approach addressbooks with 1600 contacts and more, the overall resident memory consumption starts to even out. Direct Read Access mode actually costs significantly less than any other benchmark for addressbooks as large as 6400 contacts and more.&lt;/p&gt;
&lt;p&gt;These results are a bit harder to explain. My theory is that since the EDS server process essentially goes to sleep after adding the initial contacts. All queries thereafter require no interaction with the EDS server process.&lt;/p&gt;
&lt;p&gt;Some things to consider here are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; The cost in memory of constantly waking up the EDS process to handle a query&lt;/li&gt;
&lt;li&gt;The cost of server side heap allocations used to deliver the results over D-Bus&lt;/li&gt;
&lt;li&gt;The cost of client side heap allocations used to receive results over D-Bus&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Overall Memory Consumption differences&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In summary, we can conclude that after all measures taken to improve performance of contact fetches in EDS; the Direct Read Access mode is the single element which makes a tradeoff in terms of memory consumption versus speed.&lt;/p&gt;
&lt;p&gt;Without the Direct Read Access patches, memory consumption as well as time to fetch contacts has seen a net improvement. With Direct Read Access enabled we see that for smaller address books an additional memory overhead is required, while with larger addressbooks (larger than 3,200 contacts); overall resident memory usage has seen a significant improvement as well.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
	<pubDate>Mon, 04 Feb 2013 12:20:55 +0000</pubDate>
</item>
<item>
	<title>Murray Cumming: The Quantum Universe</title>
	<guid>http://www.murrayc.com/blog/?p=1825</guid>
	<link>http://www.murrayc.com/permalink/2013/01/30/the-quantum-universe/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=the-quantum-universe</link>
	<description>&lt;p&gt;I managed to finish a book for the first time in 2 years. My second child is now 2 years old, in case you find it odd that I&amp;#8217;m proud of having read an actual book. Parents of small children will understand.&lt;/p&gt;
&lt;p&gt;It took several tries to finish &lt;a href=&quot;http://www.amazon.com/gp/product/0306819643/ref=as_li_ss_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0306819643&amp;linkCode=as2&amp;tag=murrayswebpages&quot;&gt;The Quantum Universe&lt;/a&gt;, partly because I had to go back over several of the earlier explanations before moving forward. I&amp;#8217;m a big fan of Brian Cox&amp;#8217;s TV shows, but not so much a fan of the co-author&amp;#8217;s &lt;a href=&quot;http://www.guardian.co.uk/profile/jeff-forshaw&quot;&gt;Jeff Forshaw&amp;#8217;s articles in the Guardian&lt;/a&gt;, though I find most popular science journalism rather insubstantial.&lt;/p&gt;
&lt;p&gt;In the end, I had to accept that several explanations in the book just weren&amp;#8217;t good enough. It seems to have been rushed, probably to capitalize on Brian Cox&amp;#8217;s current fame, without anybody taking the time to check that all the text actually makes sense. It must be hard to find editors who are brave enough to say when they don&amp;#8217;t understand.&lt;/p&gt;
&lt;p&gt;It also got unnecessarily hand-wavy at times. And I didn&amp;#8217;t like how on the one hand it rightly discussed observed experimental behavior of the quantum world as being predictable via the maths, but then went on to describe that maths as being a mechanism that causes other effects rather than just being consistent with the observed effects. That feels like anthropomorphizing the maths, before we&amp;#8217;ve really figured out if we have the most general model to think about things. I&amp;#8217;m thinking particularly of the epilogue about how Pauli&amp;#8217;s Exclusion Principle explains how electrons limit the mass of white dwarf starts. Maybe I&amp;#8217;d find it more justified if there was some proper explanation of the exclusion principle, assuming there is one, but the book skips over that.&lt;/p&gt;
&lt;p&gt;Like many people, I found the clocks analogy to be a distraction. I&amp;#8217;d rather just see the maths used to explain probability waves and their wave interference. Plenty of people are afraid of maths, but the clocks explanation mostly just gives the false impression of understanding, while annoying people who are comfortable with a little calculus. Without the equations, I don&amp;#8217;t feel like I&amp;#8217;m on solid ground.&lt;/p&gt;
&lt;p&gt;Reading it on the Kindle wasn&amp;#8217;t particularly pleasant, because I had to flick backwards and forwards between the text and the diagrams. But as far as I can tell, the real book is not laid out much better. Again, I guess the book would have a more approachable layout if it wasn&amp;#8217;t rushed.&lt;/p&gt;
&lt;p&gt;As you can tell, I&amp;#8217;m not qualified to judge this book properly. That&amp;#8217;s because I am the target audience. I still feel a lack of understanding of quantum and particle physics that bothers me deep down. I hope to find the time to read &lt;a href=&quot;http://www.amazon.com/gp/product/0306447908/ref=as_li_ss_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0306447908&amp;linkCode=as2&amp;tag=murrayswebpages&quot;&gt;Ramamurti Shankar&amp;#8217;s Principles of Quantum Mechanics&lt;/a&gt; instead, to solve the problem properly. I&amp;#8217;ve already enjoyed some of his &lt;a href=&quot;http://oyc.yale.edu/physics&quot;&gt;Fundamentals of Physics&lt;/a&gt; lecture videos that Yale have made available online.&lt;/p&gt;</description>
	<pubDate>Wed, 30 Jan 2013 08:49:27 +0000</pubDate>
</item>
<item>
	<title>Murray Cumming: OnlineGlom: Slightly Saner Logins</title>
	<guid>http://www.murrayc.com/blog/?p=1821</guid>
	<link>http://www.murrayc.com/permalink/2013/01/29/onlineglom-slightly-saner-logins/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=onlineglom-slightly-saner-logins</link>
	<description>&lt;p&gt;The &lt;a href=&quot;http://www.glom.org/wiki/index.php?title=Development/OnlineGlom#Demos&quot;&gt;OnlineGlom demo&lt;/a&gt; does not require a login. However, the code does let you set up a server that requires a login, and I noticed that a successful login for one person became a login for everybody else. So after the first login, it was as if no login was required for anybody. Yes, really. Of course, this would not do.&lt;/p&gt;
&lt;p&gt;So I fixed that, I think, learning some things about Java Servlet sessions along the way. This text is mostly for my own reference, and so that people can tell me how wrong I am, because I&amp;#8217;d like to know about that.&lt;/p&gt;
&lt;h3&gt;In the server-side code&lt;/h3&gt;
&lt;p&gt;Java servlets already set a JSESSIONID cookie in the browser, but you &lt;a href=&quot;http://stackoverflow.com/questions/3092363/how-can-i-load-java-httpsession-from-jsessionid/3092495#comment18933262_3092495&quot;&gt;shouldn&amp;#8217;t try to use that cookie to maintain a login across browser sessions&lt;/a&gt;. Instead, I now &lt;a href=&quot;https://gitorious.org/online-glom/gwt-glom/commit/84acb98ac876eea66b037f36733df9024fe2b2b2&quot;&gt;set and get a custom Cookie&lt;/a&gt;, in the server code, using &lt;a href=&quot;http://docs.oracle.com/javaee/6/api/javax/servlet/http/Cookie.html&quot;&gt;&lt;span class=&quot;diff-content&quot;&gt;javax.servlet.http.Cookie&lt;/span&gt;.&lt;/a&gt; &lt;a href=&quot;http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpSession.html#getId%28%29&quot;&gt;HttpSession.getId()&lt;/a&gt; conveniently provides a unique-enough session ID for me to use in the Cookie. This &lt;a href=&quot;http://code.google.com/p/google-web-toolkit-incubator/wiki/LoginSecurityFAQ&quot;&gt;page about Cookies with GWT&lt;/a&gt; seems to suggest setting the cookie in the client-side JavaScript code, using &lt;a href=&quot;http://google-web-toolkit.googlecode.com/svn/javadoc/1.6/com/google/gwt/user/client/Cookies.html&quot;&gt;com.google.gwt.user.client.Cookies&lt;/a&gt;, but that sounds rather wrong.&lt;/p&gt;
&lt;p&gt;I now store the username and password (Yes, that&amp;#8217;s not good, so keep reading), associated with the session ID, &lt;a href=&quot;https://gitorious.org/online-glom/gwt-glom/commit/5b2462e3e1e67f88fc8e3b741a97cb57ac1a2da6&quot;&gt;in a structure that&amp;#8217;s associated with the ServletContext&lt;/a&gt;, via the &lt;a href=&quot;http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html#setAttribute%28java.lang.String,%20java.lang.Object%29&quot;&gt;javax.servlet.ServletContext.setAttribute(&lt;/a&gt;) method. I get the ServletContext via the &lt;a href=&quot;http://docs.oracle.com/javaee/6/api/javax/servlet/ServletConfig.html#getServletContext%28%29&quot;&gt;ServletConfig.getServletContext()&lt;/a&gt; method. I believe that this single instance is available to the entire web &amp;#8220;app&amp;#8221;, and it seems to work across my various servlets. For instance, if I login to view a regular page, the images servlet can also then provide images to show in the page. I&amp;#8217;d really like to know if this is not the right thing to do.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;However&lt;/strong&gt;, it still stores your PostgreSQL username and password in memory, so it can use it again if you have the cookie from your last successful login. It does not store the password on disk, but that is still not good, because it could presumably still allow someone to steal all the passwords after a breakin, which would then endanger users who use the same password on other website. I cannot easily avoid this because it&amp;#8217;s the PostgreSQL username and password that I&amp;#8217;m using for login. PostgreSQL does store a hash rather than the plaintext password, but still &lt;a href=&quot;http://www.postgresql.org/message-id/1355673270.18581.7.camel@murrayc-ThinkPad-X220&quot;&gt;requires the plaintext password to be supplied&lt;/a&gt; to it. I think I&amp;#8217;ll have to generate PostgreSQL passwords and hide them behind a separate login username/password. Those passwords will still be stored in plaintext, but we won&amp;#8217;t be storing the password entered by the user. I&amp;#8217;d like to make this generic enough that I can use other authentication systems, such as Google&amp;#8217;s for App Engine.&lt;/p&gt;
&lt;p&gt;To avoid session hijacking, I made the cookie &amp;#8220;secure&amp;#8221;, meaning that it may only be provided via a secure protocol, such as HTTP. I believe this also means that client (javascript) code is not allowed to read it, so it can only be read by the server via HTTP(S). I did that with the &lt;a href=&quot;http://docs.oracle.com/javaee/6/api/javax/servlet/http/Cookie.html#setSecure%28boolean%29&quot;&gt;javax.servlet.http.Cookie.setSecure()&lt;/a&gt; method, though I had to make a &lt;a href=&quot;https://gitorious.org/online-glom/gwt-glom/commit/4149279001acf32b38240fbc3456c68f22864e76&quot;&gt;build change to make that available&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The login servlet now &lt;a href=&quot;https://gitorious.org/online-glom/gwt-glom/commit/f1ac487e38756a86e1f2c6be80e840c8d9b161d5&quot;&gt;checks that it has been called via HTTPS&lt;/a&gt;, by using the ServletRequest.isSecure() method, and uses HTTPS when testing via mvn gwt:run. It refuses to do any authentication if HTTPS was not used, logging an error on the server.&lt;/p&gt;
&lt;h3&gt;In the client side code&lt;/h3&gt;
&lt;p&gt;I &lt;a href=&quot;https://gitorious.org/online-glom/gwt-glom/commit/e7e54f4bba80376a1b7870ce075d3c51be58543d&quot;&gt;added a check for what protocol is used&lt;/a&gt;. If it&amp;#8217;s not https then I warn that login cannot work. This does not add any security, but it&amp;#8217;s a helpful hint.&lt;/p&gt;
&lt;p&gt;Actually, the &lt;strong&gt;entire site must therefore be served via HTTPS&lt;/strong&gt;, not just the login page, or we would violate the &lt;a href=&quot;http://en.wikipedia.org/wiki/Same_origin_policy&quot;&gt;Same Origin Policy&lt;/a&gt; by mixing protocols, which the browser would rightfully complain about. At this point I noticed that most serious sites with logins now use HTTPS for their entire site. For instance, Google, Amazon, Facebook. This seems like a good simple rule, though I wonder if many projects don&amp;#8217;t enforce it just to make debugging easier.&lt;/p&gt;
&lt;p&gt;I also converted the popup login dialog &lt;a href=&quot;https://gitorious.org/online-glom/gwt-glom/commit/a8d3e9f0c5b28ee2087f0db224e6d1d7839e2595&quot;&gt;into a proper login page&lt;/a&gt;, making sure that it &lt;a href=&quot;https://gitorious.org/online-glom/gwt-glom/commit/ee9b1044595448a5fd842897205d6947cf13c61f&quot;&gt;takes the user to the desired page&lt;/a&gt; afterwards.&lt;/p&gt;</description>
	<pubDate>Tue, 29 Jan 2013 13:08:46 +0000</pubDate>
</item>
<item>
	<title>Jens Georg: Rygel progress in current master</title>
	<guid>http://jensge.org/?p=834</guid>
	<link>http://jensge.org/2013/01/rygel-progress-in-current-master/</link>
	<description>&lt;p&gt;It&amp;#8217;s been a while since I last blogged about Rygel. Many things have happened since, mainly in features and documentation.&lt;/p&gt;
&lt;h2&gt;Features&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Exchangeable media engines: We&amp;#8217;ve loosened the dependency on GStreamer a bit. While it is still our first-class transcoding and general media handling library, it is now possible to substitute it with other media processing libraries. &lt;a href=&quot;http://git.gnome.org/browse/rygel/tree/src/media-engines/simple&quot; target=&quot;_blank&quot;&gt;A simple example is included in the source&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Change tracking. This is a feature introduced in the UPnP content directory specification version 3. It allows clients to, well, track the changes that happen on the server in detail for synchronization purposes. It&amp;#8217;s implemented in the framework and as a demonstration in the MediaExport plug-in.&lt;/li&gt;
&lt;li&gt;GStreamer 1.0 support. As the rest of GNOME, we transitioned to GStreamer 1.0.&lt;/li&gt;
&lt;li&gt;Playlist support. Rygel now generates playlists for containers on-the-fly and the renderer framework supports automatic playback of them. The only format that&amp;#8217;s supported currently is one of the two formats defined by DLNA, DIDL_S, which is just the same format that is used by UPnP AV to describe the media content on a server.&lt;/li&gt;
&lt;li&gt;Playspeed support. A renderer now can announce that it supports different speeds and directions than normal forward playback.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;API&lt;/h2&gt;
&lt;p&gt;There was another split-up into a renderer framework library and a specific implementation of a renderer using GStreamer which again may be used in your own programs. This is mainly due to the aforementioned change in media backend flexibility.&lt;/p&gt;
&lt;p&gt;Otherwise we&amp;#8217;re working on making the API easier to use from C and other languages through introspection.&lt;/p&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;p&gt;There&amp;#8217;s been a lot of effort into extending our sparse documentation. It is currently concentrating on the &lt;a href=&quot;http://developer.gnome.org/librygel-core/unstable/&quot; target=&quot;_blank&quot;&gt;API&lt;/a&gt; &lt;a href=&quot;http://developer.gnome.org/librygel-server/unstable/&quot; target=&quot;_blank&quot;&gt;side&lt;/a&gt; &lt;a href=&quot;http://developer.gnome.org/librygel-renderer/unstable/&quot; target=&quot;_blank&quot;&gt;of&lt;/a&gt; &lt;a href=&quot;http://developer.gnome.org/librygel-renderer-gst/unstable/&quot; target=&quot;_blank&quot;&gt;things&lt;/a&gt; but will be extended to a higher level as well soon.&lt;/p&gt;
&lt;h2&gt;Misc&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;There is an &lt;a href=&quot;http://git.gnome.org/browse/rygel/tree/examples/fullscreen-renderer.c&quot; target=&quot;_blank&quot;&gt;example&lt;/a&gt; now that implements a DLNA renderer which is running in full-screen&lt;/li&gt;
&lt;li&gt;There are &lt;a href=&quot;http://git.gnome.org/browse/rygel/tree/examples/service&quot; target=&quot;_blank&quot;&gt;several examples&lt;/a&gt; for the most common init systems to run Rygel as a system service if wanted&lt;/li&gt;
&lt;li&gt;A load of bugfixes&lt;/li&gt;
&lt;/ul&gt;</description>
	<pubDate>Mon, 21 Jan 2013 09:46:59 +0000</pubDate>
</item>
<item>
	<title>Tristan Van Berkom: Meritocracy</title>
	<guid>http://blogs.gnome.org/tvb/?p=352</guid>
	<link>http://blogs.gnome.org/tvb/2013/01/21/meritocracy/</link>
	<description>&lt;p&gt;I&amp;#8217;m posting this here, while I would have replied to Taryn Fox&amp;#8217;s blog but couldn&amp;#8217;t do it without subscribing to something&amp;#8230;.&lt;/p&gt;
&lt;p&gt;(I&amp;#8217;m throwing away all of the text I wrote yesterday and starting over, I&amp;#8217;ll instead try to write something shorter).&lt;/p&gt;
&lt;p&gt;First and foremost, please remember that GNOME projects are indeed mostly volunteer driven, except for a few projects in GNOME which may be dominated at times by developers all working at a given company (and in those corner cases, the meritocracy approach may not apply as strictly).&lt;/p&gt;
&lt;p&gt;In most cases, the maintainer is the only one that actually cares about the given project enough to weather the storm. Example, if I had not been so determined to make something out of Glade for a number of years in my spare time&amp;#8230; believe me that the project would have died, in the same way that if Juan Pablo did not take care of Glade these last couple years, nobody else would have taken charge for the long term. I know this because I see the flood of contributors who come and go, the ones who stay the course and show dedication are few and far between. It&amp;#8217;s only fair that we afford a special level of trust to those who work hard and stay the course.&lt;/p&gt;
&lt;p&gt;Yes there are things that can be improved, hopefully we can all take criticism and try not to hurt people&amp;#8217;s feelings etc etc, but please consider the cruel alternatives to meritocracy.&lt;/p&gt;
&lt;p&gt;The alternative to meritocracy as I see it are those &amp;#8220;Pay to get in Boys Clubs&amp;#8221;, what I mean by &amp;#8220;Boys Club&amp;#8221; is you know&amp;#8230; those people who&amp;#8217;s daddy was rich or knew the right people, and so were able to go to the most reputable universities and have all the opportunities that others did not. Now let me stress that not all members of these clubs have an arrogant sense of self entitlement, however sadly some of them do in my experience, also most corporate human resource departments are unconditionally biased to hire only people who hold some kind of university degree (or even, those who hold a degree from a first world country).&lt;/p&gt;
&lt;p&gt;Meritocracy helps us to level the playing field, it gives a chance to those of us who grew up in a cardboard box or in a third world country, to prove that they can indeed make just as worthy contributions as those of us who attended one of these rich kid clubs/universities and also get the same recognition, provided they at least did their homework (whether the walls of that home were made of brick, wood, or only cardboard).&lt;/p&gt;
&lt;p&gt;This is something worth fighting for, worth protecting.&lt;/p&gt;</description>
	<pubDate>Mon, 21 Jan 2013 03:43:48 +0000</pubDate>
</item>
<item>
	<title>Murray Cumming: Glom: Experimental MySQL Support</title>
	<guid>http://www.murrayc.com/blog/?p=1816</guid>
	<link>http://www.murrayc.com/permalink/2013/01/15/glom-experimental-mysql-support/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=glom-experimental-mysql-support</link>
	<description>&lt;p&gt;Glom uses PostgreSQL and doesn&amp;#8217;t try to offer the user a choice of anything else. That&amp;#8217;s because it does what Glom needs, there&amp;#8217;s no need to confound the user with an incomprehensible choice, and I&amp;#8217;ve no wish to maintain multiple sets of code. It&amp;#8217;s hard enough keeping up with changes in PostgreSQL, though Glom&amp;#8217;s regression tests help.&lt;/p&gt;
&lt;p&gt;However, I played around with adding MySQL support as a build-time alternative via the &amp;#8211;enable-mysql configure option. The basic stuff now works both in the UI and in the regression tests. Those tests can now run each self-hosting database test with all 3 backends.&lt;/p&gt;
&lt;p&gt;This is mostly just so I could learn about MySQL, so I can reimplement it in Java for OnlineGlom. That would let me use Google&amp;#8217;s Cloud SQL, which is based on MySQL. The main work has been figuring out how to initialize a MySQL database store on disk and then start and stop MySQL instances. It&amp;#8217;s even more funky than with PostgreSQL. I did need an addition to libgda to &lt;a href=&quot;https://bugzilla.gnome.org/show_bug.cgi?id=691069&quot;&gt;support non-standard MySQL port numbers&lt;/a&gt; but, as usual, &lt;a href=&quot;http://blogs.gnome.org/vivien/&quot;&gt;Vivien Malerba&lt;/a&gt; fixed that for me quickly. There&amp;#8217;s also the rather huge problem that &lt;a href=&quot;https://bugs.launchpad.net/ubuntu/+source/mysql-5.5/+bug/1095370&quot;&gt;AppArmor on Ubuntu prevents us from starting MySQL&lt;/a&gt; with anything but the standard database data, and we can&amp;#8217;t expect the user to go editing AppArmor config files. At least with MySQL 5.6, it should be possible to &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.6/en/mysql-install-db.html#option_mysql_install_db_random-passwords&quot;&gt;start a MySQL instance without it having no password for a few seconds&lt;/a&gt;, as is necessary with MySQL 5.5. I need to start and stop custom instances so I can run tests automatically.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve committed it to Glom&amp;#8217;s git master, and its in the 1.23.3 release, just in case anyone wants to improve it. There are some TODO_MySQL comments in the tests where we expect something to fail with MySQL. For instance, I have not added support for editing the MySQL users and groups. And there are likely to be problems with keeping data when changing field types, which doesn&amp;#8217;t seem to be tested thoroughly for any backend. libgda is also &lt;a href=&quot;https://bugzilla.gnome.org/show_bug.cgi?id=691099&quot;&gt;missing some support for binary field types&lt;/a&gt;, needed for Glom&amp;#8217;s image fields.&lt;/p&gt;
&lt;p&gt;Over the years, various people have complained about Glom not using MySQL. Here is your chance to actually work on that, with tests to show if your work is enough.&lt;/p&gt;</description>
	<pubDate>Tue, 15 Jan 2013 12:09:32 +0000</pubDate>
</item>
<item>
	<title>Tristan Van Berkom: Getting your contacts…  Right Now!</title>
	<guid>http://blogs.gnome.org/tvb/?p=333</guid>
	<link>http://blogs.gnome.org/tvb/2013/01/15/getting-your-contacts-right-now/</link>
	<description>&lt;p&gt;Hi all, hope you&amp;#8217;ve spent a pleasant holiday season.&lt;/p&gt;
&lt;p&gt;As promised, here is another post describing what new tricks we&amp;#8217;ve been teaching EDS (Evolution Data Server) this year at Openismus.&lt;/p&gt;
&lt;p&gt;Before I go through all the details, a little context is in order. Last year &lt;a href=&quot;http://taschenorakel.de/mathias/&quot;&gt;Mathias&lt;/a&gt; created a nifty &lt;a href=&quot;http://taschenorakel.de/mathias/2012/06/20/performance-and-memory-usage-of-evolution-data-server/&quot;&gt;benchmark tool&lt;/a&gt; for EDS allowing us to track performance improvements and regressions of the Evolution Data Server across releases and branches. Mathias, with his prior experience and knowledge of EDS was able to make some educated guesses on where we could save some milliseconds, all in the interest of providing an EDS that is stable/reliable in terms of performance and also useful in a variety of platforms and scenarios (not only as the backend of the Evolution Mail client on Desktops).&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ve come a long way on this, so first let me describe the major changes that we&amp;#8217;ve made and then I&amp;#8217;ll move on to show you the results.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Removing Berkeley DB&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Historically, Evolution&amp;#8217;s local addressbook used Berkeley DB to store &lt;a href=&quot;http://en.wikipedia.org/wiki/VCard&quot;&gt;VCards&lt;/a&gt; for all contacts. Over time some optimizations were made, originally an in-memory &amp;#8220;summary&amp;#8221; was maintained holding some of the contact data in order to speed up queries to the addressbook. This was eventually replaced with an SQLite implementation of the quick search &amp;#8220;summary&amp;#8221; data. In the end that left us with a two step query for fetching contacts from the addressbook; an initial query to the SQLite to find any UID which match the query terms and then another query to the BDB fetching the actual VCard data for that contact.&lt;/p&gt;
&lt;p&gt;Removing the BDB implementation and storing all contact data in the SQLite instead naturally makes queries faster, not to mention there is considerably less flash wear as we only have one DB persisting contact data now instead of two. Additionally we&amp;#8217;ve also observed that the old BDB code fails (crashes, even) with an out of memory condition in some cases such as deleting more than 6400 contacts at once, this is all handled much cleaner using SQLite exclusively.&lt;/p&gt;
&lt;p&gt;This has landed in EDS&amp;#8217;s git master a couple of months ago and should be available in the next release.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Configurable Summary Fields&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Summary Fields in EDS refer to the VCard fields for a given addressbook which should be elected for fast results. They are stored separately in an SQLite table so that contacts can be queried without parsing the complete contact VCard data for every contact.&lt;/p&gt;
&lt;p&gt;This list has always been hard coded and tailored to the needs of the Evolution Mail client (the list basically consisted of the contact name fields plus a hand full of email fields which Evolution is accustomed to using). This would of course be appropriate for an email client but falls short for applications that have different needs such as hand phones, which require extremely fast results for queries by phone number.&lt;/p&gt;
&lt;p&gt;So we&amp;#8217;ve now introduced a set of APIs which allow configuration of the summary fields of a given addressbook at addressbook creation time. This allows us to choose which fields are stored in the summary and which of those fields should be indexed for extra fast retrieval.&lt;/p&gt;
&lt;p&gt;As a side effect of this, we now also support multi valued VCard attributes to be stored in the summary (i.e. list of emails or list of addresses).&lt;/p&gt;
&lt;p&gt;This has also landed in EDS master some time ago and will be available in the next EDS stable release.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Direct Read Access&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One of the more intrusive changes is the Direct Read Access mode. Mathias foresaw that we would gain significant performance simply by delivering query results directly to the client instead of squishing them into the socket and pushing them arduously through the D-Bus byte by byte (or probably 8192 bytes at a time&amp;#8230;). I have to admit that I was a little sceptical about this change but after benchmarking the direct read access approach I was able to notice a serious performance gain.&lt;/p&gt;
&lt;p&gt;Our fastest queries using the previously described configurable summary fields return in roughly 4-7 milliseconds.&lt;/p&gt;
&lt;p&gt;The same queries in Direct Read Access mode are quite consistently 0.2 or 0.3 milliseconds.&lt;/p&gt;
&lt;p&gt;In other words; for the simplest queries where the EDS server can fetch the results very fast, we waste the grand majority of our time serializing/deserializing VCard data and tinkering on the D-Bus socket.&lt;/p&gt;
&lt;p&gt;This has not yet landed in EDS master, so I&amp;#8217;ll keep you posted &lt;img src=&quot;http://blogs.gnome.org/tvb/wp-content/mu-plugins/tango-smilies/tango/face-wink.png&quot; alt=&quot;;-)&quot; class=&quot;wp-smiley&quot; /&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How fast can I get my contacts ?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In conclusion, let&amp;#8217;s go over the results of our benchmarks and compare.&lt;/p&gt;
&lt;p&gt;First a few details regarding the results we&amp;#8217;re looking at:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;EDS 3.6 &amp;#8211; This is stable EDS 3.6.2 without any of the above modifications, it&amp;#8217;s important to note that this version still uses Berkeley DB as well as SQLite to store contacts. Furthermore, the stock 3.6.2 does not take advantage of SQLite indexes.&lt;/li&gt;
&lt;li&gt;Custom &amp;#8211; Built from our EDS 3.6 based work branch (called &amp;#8216;openismus-work&amp;#8217;) this build has Berkeley DB removed and configures the summary with a custom summary configuration.&lt;/li&gt;
&lt;li&gt;Custom DRA &amp;#8211; Built from our EDS 3.6 based work branch; this build additionally enables Direct Read Access, using the same configuration for summary fields as the &amp;#8216;Custom&amp;#8217; build uses.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For both &amp;#8216;Custom&amp;#8217; and &amp;#8216;Custom DRA&amp;#8217;, the customized summary is configured as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Full Name: In the summary and indexed for prefix searches&lt;/li&gt;
&lt;li&gt;Given Name: In the summary and indexed for prefix searches&lt;/li&gt;
&lt;li&gt;Family Name: In the summary and indexed for prefix searches&lt;/li&gt;
&lt;li&gt;Telephone Number: In the summary and indexed for prefix &amp;amp; suffix searches&lt;/li&gt;
&lt;/ul&gt;
&lt;div id=&quot;attachment_336&quot; class=&quot;wp-caption aligncenter&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/01/filter-by-exact-full-name.png&quot;&gt;&lt;img class=&quot; wp-image-336   &quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/01/filter-by-exact-full-name.png&quot; alt=&quot;&quot; width=&quot;382&quot; height=&quot;237&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Query for exact match of the full name attribute&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;In EDS 3.6 stable, the full name attribute is indeed stored in the SQLite summary. Notice that for small addressbooks (less than 200 contacts) the results are similar to EDS Custom. However with the customized summary fields we&amp;#8217;ve also ensured that the SQLite indexes are getting used properly; this is what ensures the performance doesn&amp;#8217;t degrade too much with larger addressbooks.&lt;/p&gt;
&lt;p&gt;The red (DRA) line is EDS doing the same thing but avoiding the arduous tinkering with D-Bus messaging.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phone Numbers&lt;/strong&gt;&lt;/p&gt;
&lt;div id=&quot;attachment_337&quot; class=&quot;wp-caption aligncenter&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/01/filter-by-long-phone-number-prefix.png&quot;&gt;&lt;img class=&quot; wp-image-337   &quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/01/filter-by-long-phone-number-prefix.png&quot; alt=&quot;&quot; width=&quot;382&quot; height=&quot;281&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Query for prefix match of phone number&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;Since we&amp;#8217;ve configured EDS to optimize the phone number field of a given contact for prefix &amp;amp; suffix searches, we can now use phone number queries at reliable speed. In other words you can again use EDS on your hand phone to implement your contacts database and kittens wont be sacrificed.&lt;/p&gt;
&lt;p&gt;The reason why this takes an extremely long time with EDS 3.6 is that the contacts have no quick search information ready at hand, this means we must iterate through all of the contacts in the Berkeley DB and parse the VCards for each, extract all of the phone numbers and compare one by one.&lt;/p&gt;
&lt;p&gt;Since we optimized for suffix searches, we get similar results for a suffix search:&lt;/p&gt;
&lt;div id=&quot;attachment_338&quot; class=&quot;wp-caption aligncenter&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/01/filter-by-long-phone-number-suffix.png&quot;&gt;&lt;img class=&quot; wp-image-338   &quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/01/filter-by-long-phone-number-suffix.png&quot; alt=&quot;&quot; width=&quot;382&quot; height=&quot;281&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Query for suffix match of phone number&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Memory Usage&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We also have in place some monitoring of memory usage:&lt;/p&gt;
&lt;div id=&quot;attachment_339&quot; class=&quot;wp-caption aligncenter&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/01/memory-usage-vms.png&quot;&gt;&lt;img class=&quot; wp-image-339   &quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/01/memory-usage-vms.png&quot; alt=&quot;&quot; width=&quot;522&quot; height=&quot;202&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Virtual Memory Usage&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div id=&quot;attachment_340&quot; class=&quot;wp-caption aligncenter&quot;&gt;&lt;a href=&quot;http://blogs.gnome.org/tvb/files/2013/01/memory-usage-rss.png&quot;&gt;&lt;img class=&quot; wp-image-340   &quot; src=&quot;http://blogs.gnome.org/tvb/files/2013/01/memory-usage-rss.png&quot; alt=&quot;&quot; width=&quot;522&quot; height=&quot;202&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Resident Memory Usage&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;These are basically just memory usage snapshots taken over the course that the benchmarks run.&lt;/p&gt;
&lt;p&gt;The &amp;#8220;Custom&amp;#8221; setup takes slightly more memory to run than EDS 3.6, this is presumably because we maintain more indexes with the SQLite version. Unsurprisingly, the Direct Read Access mode takes significantly more memory; this is because the direct read access mode uses two SQLite connections (one for the server and one for the client to make direct read calls).&lt;/p&gt;
&lt;p&gt;This concludes this Tuesday&amp;#8217;s episode of &amp;#8220;Getting your contacts Right Now!&amp;#8221;&lt;/p&gt;
&lt;p&gt;Stay Tuned &lt;img src=&quot;http://blogs.gnome.org/tvb/wp-content/mu-plugins/tango-smilies/tango/face-wink.png&quot; alt=&quot;;-)&quot; class=&quot;wp-smiley&quot; /&gt; &lt;/p&gt;</description>
	<pubDate>Tue, 15 Jan 2013 10:27:12 +0000</pubDate>
</item>
<item>
	<title>Jan Arne Petersen: Maliit running under wayland</title>
	<guid>http://blog.jpetersen.org/?p=139</guid>
	<link>http://blog.jpetersen.org/2013/01/10/maliit-running-under-wayland/</link>
	<description>&lt;p&gt;We at &lt;a href=&quot;http://www.openismus.com&quot;&gt;Openismus&lt;/a&gt; combined our experiences in the &lt;a href=&quot;https://wiki.maliit.org/Main_Page&quot;&gt;Maliit input method framework&lt;/a&gt; and &lt;a href=&quot;http://wayland.freedesktop.org/&quot;&gt;Wayland&lt;/a&gt; &lt;a href=&quot;http://blog.jpetersen.org/2012/09/18/text-input-method-support-in-wayland-update/&quot;&gt;input methods&lt;/a&gt; and added support for Wayland input methods to Maliit. This allows using Maliit as a virtual keyboard under Weston/Wayland beside the demo weston-keyboard. To try it out use maliit-framework from &lt;a href=&quot;https://gitorious.org/maliit/maliit-framework&quot;&gt;master&lt;/a&gt; and Weston from our &lt;a href=&quot;https://github.com/openismus/weston&quot;&gt;github repository&lt;/a&gt; and compile it with Qt 5 and &lt;code&gt;qmake CONFIG+=wayland&lt;/code&gt;, maliit-plugins (from &lt;a href=&quot;https://gitorious.org/maliit/maliit-plugins&quot;&gt;master&lt;/a&gt;) needs to be build with &lt;code&gt;qmake CONFIG+=disable-nemo-keyboard&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://jpetersen.org/videos/maliit-wayland.mp4&quot;&gt;screen cast&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There is no &lt;a href=&quot;http://trac.enlightenment.org/e/wiki/EFLOverview&quot;&gt;EFL&lt;/a&gt; support in Maliit (and no Maliit support in EFL) but since there is &lt;a href=&quot;http://blog.jpetersen.org/2012/10/25/efl-integration-for-wayland-input-methods/&quot;&gt;wayland input method support for EFL&lt;/a&gt; available one can just use Maliit with EFL applications under Wayland. This shows one of the advantages of the Wayland input methods, that input method frameworks do not need explicit support for all kind of UI toolkits anymore.&lt;/p&gt;
&lt;p&gt;The current plan is to get input method support into &lt;a href=&quot;http://lists.freedesktop.org/archives/wayland-devel/2012-December/006767.html&quot;&gt;Wayland 1.2&lt;/a&gt;. Adding support for Wayland input method to Maliit allowed us to discover some &lt;a href=&quot;https://gitorious.org/maliit/maliit-framework/blobs/master/connection/README.weston&quot;&gt;missing features&lt;/a&gt; which we will work on next together with some more &lt;a href=&quot;http://lists.freedesktop.org/archives/wayland-devel/2012-October/005645.html&quot;&gt;improvement suggestions&lt;/a&gt; to get the input methods really ready for Wayland 1.2.&lt;/p&gt;</description>
	<pubDate>Thu, 10 Jan 2013 11:29:25 +0000</pubDate>
</item>
<item>
	<title>Murray Cumming: Updated Maliit packages for Ubuntu</title>
	<guid>http://www.murrayc.com/blog/?p=1815</guid>
	<link>http://www.murrayc.com/permalink/2013/01/04/updated-maliit-packages-for-ubuntu/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=updated-maliit-packages-for-ubuntu</link>
	<description>&lt;p&gt;Our Ubuntu packages for the Maliit framework and keyboard had not been updated for a while, so just before the holidays I uploaded 0.93.1 versions for Ubuntu Quantal to the &lt;a href=&quot;https://launchpad.net/~maliit-team/+archive/ppa&quot;&gt;Maliit PPA&lt;/a&gt;. I fixed various lintian warnings along the way.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;d really like some help getting this into official Debian and Ubuntu.&lt;/p&gt;</description>
	<pubDate>Fri, 04 Jan 2013 09:01:14 +0000</pubDate>
</item>
<item>
	<title>Mathias Hasselmann: The Movie Database, Grilo and mock testing</title>
	<guid>http://taschenorakel.de/mathias/2012/12/21/tmdb-grilo-mock-testing/</guid>
	<link>http://taschenorakel.de/mathias/2012/12/21/tmdb-grilo-mock-testing/</link>
	<description>&lt;p&gt;This year at &lt;a href=&quot;http://openismus.com/&quot;&gt;Openismus&lt;/a&gt; had a strong focus on media files and
related metadata. So it isn't surprising that we also got in touch with
&lt;a href=&quot;http://live.gnome.org/Grilo&quot;&gt;Grilo&lt;/a&gt;. Grilo is a framework for discovering media files and decorating
it with relevant metadata. One missing piece was background information about
movies, like story summaries, artwork, information about artists. With the
support of our customers we decided to change that.&lt;/p&gt;
&lt;p&gt;Now an obvious choice for getting information on movies is Amazon's incredibly
comprehensive &lt;a href=&quot;http://imdb.com/&quot;&gt;Internet Movie Database&lt;/a&gt;. Sadly there doesn't seem to be
any official web API that could be used by open source software. If I missed
something, please tell me in the comments.&lt;/p&gt;
&lt;h3&gt;The Movie Database plugin for Grilo&lt;/h3&gt;
&lt;p&gt;Anyway, with IMDb out of reach we had to look for an alternative - and we've
found a great one: &lt;a href=&quot;http://themoviedb.org/&quot;&gt;The Movie Database&lt;/a&gt;. This database is a community
driven project, built with the needs of media players in mind. It comes with a
great and easy to use &lt;a href=&quot;http://docs.themoviedb.apiary.io/&quot;&gt;API&lt;/a&gt;. Like IMDb it seems to know just each and
every relevant and irrelevant movie ever made. Some entertaining stuff like
movie trivia, goofs and quotes are missing, but for most movies the database
knows the IMDb id - so all the entertainment is just one click away.&lt;/p&gt;
&lt;p&gt;Now that we've found a good movie database &lt;a href=&quot;http://jensge.org/&quot;&gt;Jens&lt;/a&gt; started implementing a
&lt;a href=&quot;http://developer.gnome.org/grilo-plugins/unstable/sec-plugin-tmdb.html&quot;&gt;TMDb plugin for Grilo&lt;/a&gt;, and a first version of the plugin was
released with &lt;a href=&quot;http://git.gnome.org/browse/grilo-plugins/tree/NEWS?h=grilo-plugins-0.2.2&quot;&gt;grilo-plugins 0.2.2&lt;/a&gt;. I've later finished
it while integrating it with our customer's project. &lt;a href=&quot;http://murrayc.com/blog/&quot;&gt;Murray&lt;/a&gt; took
care of examples and documentation.&lt;/p&gt;
&lt;p&gt;The plugin implements a metadata resolver: It takes a media object, checks for
a title or the unique movie id and then fills the media object with information
it found on TMDb. Biggest obstacle when using the plugin is the need for an
&lt;a href=&quot;http://help.themoviedb.org/kb/general/how-do-i-register-for-an-api-key&quot;&gt;API key&lt;/a&gt;. It should be easy to get. The database operator hope these
keys will help them to deal with misbehaving clients.&lt;/p&gt;
&lt;p&gt;Another issue is related to Grilo's architecture. Grilo doesn't permit its
sources to improve any metadata. So if you interpolated a movie title from the
filename and pass a media object with that title to the TMDb plugin, the plugin
is not permitted to replace your usually ugly title with the pretty and
official title it found in the database. To work around that issue you would
not resolve the TMDb data in a single step. Instead you'd do a first resolve
operation to just retrieve the TMDb's movie id. In a second step you'd delete
your own title, but keep the resolved movie id and let the plugin work with
that data:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/* Create dummy media from filename */
media = grl_media_new ();
grl_media_set_title (media, &quot;the_last_unicorn_720p&quot;);

/* Ask grilo to resolve the TMDb id */
metadata_key_tmdb_id = grl_registry_lookup_metadata_key (registry, &quot;tmdb-id&quot;);
keys = grl_metadata_key_list_new (metadata_key_tmdb_id, GRL_METADATA_KEY_INVALID);
grl_source_resolve_sync (source, media, keys, options, &amp;amp;error);
/* Exercise: Release memory and handle possible errors */

/* Use the resolved id to get full metadata */
movie_id = grl_data_get_string (GRL_DATA (media), metadata_key_tmdb_id);

if (movie_id) {
    grl_data_remove (GRL_DATA (media), GRL_METADATA_KEY_TITLE);
    grl_source_resolve_sync (source, media, keys, options, &amp;amp;error);
    /* ... */
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Behind your back the same number of network requests is needed for both
approaches.&lt;/p&gt;
&lt;h3&gt;Testing the Plugin&lt;/h3&gt;
&lt;p&gt;At Openismus we have a mantra we strongly believe in:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;No code is done before it has proper tests.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Or more radically:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It doesn't work if it isn't tested.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the case of the TMDb plugin this commitment caused us a bit of work. Grilo
didn't have any infrastructure for testing network based plugins yet. Also if
we'd do those tests we'd like to run them offline:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it works without API keys&lt;/li&gt;
&lt;li&gt;it saves resources and is much quicker&lt;/li&gt;
&lt;li&gt;it permits testing of obscure errors&lt;/li&gt;
&lt;li&gt;it is more reliable by removing countless points of failure&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So we took the challenge and also implemented a mock testing framework for
Grilo. It became handy that Grilo already routes all its network access
through a dedicated abstraction, so that it can implement request throttling.
So we just hooked into that layer and introduced a few environment variables
that influence behavior of that layer: First you'd set &lt;code&gt;GRL_NET_CAPTURE_DIR&lt;/code&gt;
to some folder name and then let your plugin perform a few interesting
operations. In a next step you'd edit the recorded files and rename them nicely
to suite your needs. Essential in that work is a generated key-value file of
the name &lt;code&gt;grl-net-mock-data-$PID.ini&lt;/code&gt; which maps URLs to captured responses.
Once done you can set &lt;code&gt;GRL_NET_MOCKED&lt;/code&gt; to point to that file. Grilo will then
stop doing real network requests and answer all requests with the information
this file provides.&lt;/p&gt;
&lt;p&gt;Details about &lt;a href=&quot;http://developer.gnome.org/grilo/unstable/ch04.html#testing-plugins&quot;&gt;testing with the Grilo mock framework&lt;/a&gt; are in the
reference manual. A few examples for using the framework can be found in
&lt;a href=&quot;http://git.gnome.org/browse/grilo-plugins/tree/test/test_tmdb_full_resolution.c&quot;&gt;Grilo's test folder&lt;/a&gt;.&lt;/p&gt;</description>
	<pubDate>Fri, 21 Dec 2012 07:24:00 +0000</pubDate>
</item>
<item>
	<title>Mathias Hasselmann: Media Discovery with QtGStreamer</title>
	<guid>http://taschenorakel.de/mathias/2012/12/20/media-discovery-qtgstreamer/</guid>
	<link>http://taschenorakel.de/mathias/2012/12/20/media-discovery-qtgstreamer/</link>
	<description>&lt;p&gt;Earlier this year we at &lt;a href=&quot;http://openismus.com/&quot;&gt;Openismus&lt;/a&gt; proposed a &lt;a href=&quot;http://qt-project.org/&quot;&gt;Qt&lt;/a&gt; based
project that would utilize &lt;a href=&quot;http://gstreamer.freedesktop.org/&quot;&gt;GStreamer&lt;/a&gt; for handling media files.
Especially we were interested in using the &lt;a href=&quot;http://gstreamer.freedesktop.org/data/doc/gstreamer/1.0/gst-plugins-base-libs/html/gst-plugins-base-libs-gstdiscoverer.html&quot;&gt;GstDiscoverer&lt;/a&gt; class
which provides a really nice and easy to use API for discovering properties of
media files, such as the container format and the audio and video formats, but
also more interesting things like EXIF information, when used with photos.&lt;/p&gt;
&lt;p&gt;Now combining code from different worlds with their different paradigms isn't
exactly fun. The resulting code often is a disgusting Frankenstein monster not
fitting at any place, unless you wrap one of the libraries to match the
project's preferred code style. Luckily in the case of Qt and GStreamer
&lt;a href=&quot;http://collabora.com/&quot;&gt;Collabora&lt;/a&gt;'s &lt;a href=&quot;http://gkiagia.wordpress.com/&quot;&gt;George Kiagiadakis&lt;/a&gt; created
&lt;a href=&quot;http://gstreamer.freedesktop.org/wiki/QtGStreamer&quot;&gt;QtGStreamer&lt;/a&gt; and therefore did most of the hard work already.
Still that library didn't support our beloved GstDiscoverer class yet. So we
had the choice: Use something different, or wrap that thing. Now we love doing
free software, also we use GstDiscoverer with great success in the &lt;a href=&quot;http://rygel-project.org/&quot;&gt;Rygel UPnP
AV/DLNA Media Server&lt;/a&gt; already, and in the end the media files shall get
played via GStreamer in the end. So we decided to just wrap that class for
QtGStreamer.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://bugzilla.gnome.org/show_bug.cgi?id=680236&quot; title=&quot;QtGStreamer doesn't wrap GstDiscoverer&quot;&gt;Doing that work&lt;/a&gt; actually was surprisingly easy: A few loose ends
here (&lt;a href=&quot;https://bugzilla.gnome.org/show_bug.cgi?id=680235&quot; title=&quot;QGlib::Value doesn't support QGlib::Error&quot;&gt;#680235&lt;/a&gt;), a bit of nitpicking there (&lt;a href=&quot;https://bugzilla.gnome.org/show_bug.cgi?id=680233&quot; title=&quot;Connecting signals causes a compiler warning on 64 bit&quot;&gt;#680233&lt;/a&gt;,
&lt;a href=&quot;https://bugzilla.gnome.org/show_bug.cgi?id=680237&quot; title=&quot;QGst::ClockTime is inconvenient to use&quot;&gt;#GB680237&lt;/a&gt;). Biggest effort was doing the &lt;a href=&quot;http://cgit.freedesktop.org/gstreamer/qt-gstreamer/tree/tests/auto/discoverertest.cpp&quot;&gt;regression
tests&lt;/a&gt;. This tests also demonstrate how easy the wrapped
GstDiscoverer is to use. Synchronous media discovery is done like that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;QGst::DiscovererPtr discoverer = QGst::Discoverer::create(QGst::ClockTime::fromSeconds(1));
QGst::DiscovererInfoPtr info;

try {
    info = discoverer-&amp;gt;discoverUri(&quot;file:///home/mathias/blockbuster.ogv&quot;);
} catch(const QGlib::Error &amp;amp;error) {
    qWarning(&quot;Discovery failed: %s&quot;, qPrintable(error.message()));
    // ...maybe also check error.domain() and .code()
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You also can try asynchronous discovery if you have a Qt build that integrates
GMainLoop:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;QGst::DiscovererPtr discoverer = QGst::Discoverer::create(QGst::ClockTime::fromSeconds(1));

// Connect C++ member methods to the signals
QGlib::connect(discoverer, &quot;starting&quot;, this, &amp;amp;DiscovererTest::onStartingDiscovery);
QGlib::connect(discoverer, &quot;discovered&quot;, this, &amp;amp;DiscovererTest::onUriDiscovered);
QGlib::connect(discoverer, &quot;finished&quot;, this, &amp;amp;DiscovererTest::onDiscoveryFinished, QGlib::PassSender);

discoverer-&amp;gt;start();

QEventLoop loop;
loop.exec();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Usually only X11 builds match that requirement, but it should be possible to
just hook &lt;a href=&quot;http://qt.gitorious.org/qt/qt/blobs/4.8/src/corelib/kernel/qeventdispatcher_glib_p.h&quot;&gt;QEventDispatcherGlib&lt;/a&gt; into your own
application if needed.&lt;/p&gt;
&lt;p&gt;The discovered data is accessible by the various attributes and methods of
QGst::DiscovererInfo:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;QGst::DiscovererInfoPtr info = ...;

qDebug() &amp;lt;&amp;lt; info-&amp;gt;uri();
qDebug() &amp;lt;&amp;lt; info-&amp;gt;tags();
qDebug() &amp;lt;&amp;lt; info-&amp;gt;duration();
// ...

Q_FOREACH(const QGst::DiscovererVideoInfoPtr &amp;amp;info, info-&amp;gt;videoStreams()) {
    ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sadly our customer wasn't that much a fan of Qt as we thought, so we didn't
have much use of our own for this work yet. This situation also delayed
finishing the last few bits of that patches. Luckily &lt;a href=&quot;http://murrayc.com/blog/&quot;&gt;Murray&lt;/a&gt; just took
the time recently to do that last bits of work, and to get the patches merged.
The code is in the git repository now and should get released with QtGStreamer
0.10.3. So whenever your Qt application needs to discover media file properties
you also can use QtGStreamer now.&lt;/p&gt;</description>
	<pubDate>Thu, 20 Dec 2012 09:10:10 +0000</pubDate>
</item>
<item>
	<title>Tristan Van Berkom: Isolated unit testing of D-Bus services</title>
	<guid>http://blogs.gnome.org/tvb/?p=308</guid>
	<link>http://blogs.gnome.org/tvb/2012/12/20/isolated-unit-testing-of-d-bus-services/</link>
	<description>&lt;p&gt;Hi all, long time no blog&amp;#8230;&lt;/p&gt;
&lt;p&gt;At Openismus these past months we&amp;#8217;ve been making a series of improvements for the Evolution Data Server, again.&lt;/p&gt;
&lt;p&gt;As it goes with patch reviews, better to take on one at a time, so this blog post will focus on isolated unit testing of your D-Bus services.&lt;/p&gt;
&lt;p&gt;If you work on the implementation of D-Bus services you&amp;#8217;ll be happy to know about the new &lt;a href=&quot;http://developer.gnome.org/gio/2.34/GTestDBus.html&quot;&gt;GTestDBus&lt;/a&gt; object introduced in GIO since 2.34. Thanks to this nifty new object we can now perform unit tests on D-Bus services in a completely isolated fashion.&lt;/p&gt;
&lt;p&gt;Using GTestDBus to implement a &lt;a href=&quot;http://git.gnome.org/browse/evolution-data-server/tree/tests/test-server-utils&quot;&gt;new test fixture&lt;/a&gt; for Evolution Data Server (EDS) now makes it possible to run &amp;#8216;make check&amp;#8217; for EDS without running the actual EDS servers manually, and without even installing the EDS software into the target prefix before hand. With a little more work, we can even get regular distchecks passing for EDS again.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s how:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First of all, you need to have an in-tree directory holding your D-Bus .service description files. Typically you already have the .service.in files stored somewhere in tree to be installed somewhere into the install prefix, but you need a separate one (I think it&amp;#8217;s good practice to add a subdirectory to your &amp;#8216;tests/&amp;#8217; directory, so it becomes &amp;#8216;$(top_builddir)/tests/services&amp;#8217;)&lt;/li&gt;
&lt;li&gt;The contents of your separate .service.in files for testing should point to the in-tree location of your D-Bus service, typically it would look like this:
&lt;pre&gt;[D-BUS Service]
Name=org.gnome.MyProject.MyServiceName
Exec=@abs_top_builddir@/src/my-server-name&lt;/pre&gt;
&lt;p&gt;This will define a service which explicitly activates a server which you&amp;#8217;ve built in your source tree.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;Then, you just need to provide that in-tree service directory to g_test_dbus_add_service_dir(), typically you would put the following into your tests/Makefile.am:
&lt;pre&gt;-DTEST_SERVICE_DIRECTORY=\&quot;&quot;$(abs_top_builddir)/tests/services&quot;\&quot;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Finally you just need a basic test fixture, with this test fixture you can ensure that your temporary D-Bus session along with your test service is recreated for every test in the suite:
&lt;pre&gt;typedef struct {
  GTestDBus *dbus;
  MyProxyType *proxy;
} TestFixture;

static void
fixture_setup (TestFixture *fixture, gconstpointer unused)
{
  /* Create a private dbus-daemon for this test */
  fixture-&amp;gt;dbus = g_test_dbus_new (G_TEST_DBUS_NONE);

  /* Add the private directory with our in-tree service files */
  g_test_dbus_add_service_dir (fixture-&amp;gt;dbus, TEST_SERVICE_DIRECTORY);

  /* Start the private D-Bus daemon */
  g_test_dbus_up (fixture-&amp;gt;dbus);

  /* Get a proxy which we will be using in test cases, typically
   * this is some API generated by gdbus-codegen
   */
  fixture-&amp;gt;proxy = my_generated_code_new_for_bus_sync (...);
}

static void
fixture_teardown (TestFixture *fixture, gconstpointer unused)
{
  /* Destroy the proxy */
  g_object_unref (fixture-&amp;gt;proxy);

  /* Stop the private D-Bus daemon */
  g_test_dbus_down (fixture-&amp;gt;dbus);
  g_object_unref (fixture-&amp;gt;dbus);
}&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With this basic type of fixture, you can produce a series of tests using g_test_add() in the normal way, all testing various behaviours of fixture-&amp;gt;proxy.&lt;/p&gt;
&lt;p&gt;Of course, perfect isolation of your service&amp;#8217;s test cases may need more efforts than just the above, for instance in the EDS test cases we create and delete a data directory between each test and setup the XDG_CONFIG_HOME, XDG_DATA_HOME and XDG_CACHE_HOME enviornment variables to point to that directory (avoiding any interaction with the user&amp;#8217;s addressbook &amp;amp; calendar). We also compile a gsettings schema in the local data directory and setup GSETTINGS_SCHEMA_DIR to point to the in-tree directory (avoiding any need to have the EDS settings schemas already installed).&lt;/p&gt;
&lt;p&gt;This morning before writing this post I also provided a &lt;a href=&quot;https://bugzilla.gnome.org/show_bug.cgi?id=690543&quot; target=&quot;_blank&quot;&gt;simple patch&lt;/a&gt; to GIO adding an example of this testing paradigm.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
	<pubDate>Thu, 20 Dec 2012 08:35:47 +0000</pubDate>
</item>
<item>
	<title>Murray Cumming: Openismus running jenkins for continuous integration</title>
	<guid>http://www.murrayc.com/blog/?p=1796</guid>
	<link>http://www.murrayc.com/permalink/2012/12/10/openismus-running-jenkins-for-continuous-integration/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=openismus-running-jenkins-for-continuous-integration</link>
	<description>&lt;p&gt;Over the last couple of weeks, I&amp;#8217;ve been playing with a Jenkins installation at &lt;a href=&quot;http://jenkins.openismus.com/&quot;&gt;jenkins.openismus.com&lt;/a&gt;, building some of the Openismus projects. Here are some notes about my experience.&lt;/p&gt;
&lt;h3&gt;Installation&lt;/h3&gt;
&lt;p&gt;This runs on an Amazon EC2 instance. Initial installation was surprisingly simple and well &lt;a href=&quot;https://wiki.jenkins-ci.org/display/JENKINS/Installing+Jenkins+on+Ubuntu&quot;&gt;documented&lt;/a&gt;, though it took me a while to figure out how to use Jenkins properly. I initially used the official Ubuntu 12.10 packages for Jenkins, but they are a little old so I had to switch to using the Debian/Ubuntu packages from jenkins.org to fix a &lt;a href=&quot;https://issues.jenkins-ci.org/browse/JENKINS-15977&quot;&gt;bug with the copyArtifacts plugin&lt;/a&gt;. The two packages seem to be structured very differently, so I had to remove all the Ubuntu Jenkins packages before installing the jenkins.org packages, to avoid a conflict.&lt;/p&gt;
&lt;p&gt;See also the &lt;a title=&quot;https://wiki.jenkins-ci.org/display/JENKINS/Standard+Security+Setup&quot; href=&quot;https://wiki.jenkins-ci.org/display/JENKINS/Standard+Security+Setup&quot; rel=&quot;nofollow&quot;&gt;Jenkins standard security setup instructions&lt;/a&gt;, though I had to use the &amp;#8220;Jenkins own user database -&amp;gt; Allow users to sign up&amp;#8221; feature first, to create a user which I could then enter in to the matrix grid. I then disabled the &amp;#8220;Allow users to sign up&amp;#8221; checkbox.&lt;/p&gt;
&lt;p&gt;Although Jenkins can use slave servers, and probably should, I&amp;#8217;m doing everything on one server for now, because I&amp;#8217;m afraid of the Amazon EC2 costs getting out of control. Luckily we don&amp;#8217;t need to run each build more than once or twice per day to get some benefit. Later I will probably try running EC2 spot instances for the builds. Maybe that won&amp;#8217;t be too expensive.&lt;/p&gt;
&lt;h3&gt;Git-based projects with Jenkins&lt;/h3&gt;
&lt;p&gt;You&amp;#8217;ll need to use the &lt;a href=&quot;https://wiki.jenkins-ci.org/display/JENKINS/Plugins#Plugins-Howtoinstallplugins&quot;&gt;pluginManager&lt;/a&gt; page to install the Git plugin, so that there is something other than &amp;#8220;None&amp;#8221; listed under &amp;#8220;Source Code Control&amp;#8221; when creating a job. Of course, we have to &amp;#8220;apt-get install git&amp;#8221; too. We must also specify a git username and email address for the &amp;#8220;git plugin&amp;#8221; on the configure page, to avoid &amp;#8220;Please tell me who you are&amp;#8221; errors in the job when Jenkins tries to locally tag the checked out git repository. Neither the configure page or the pluginManager admin pages seem to be linked from anywhere, so I had to discover them via google searches.&lt;/p&gt;
&lt;p&gt;Be careful to specify the master branch rather than leaving that blank, or I think Jenkins will try building arbitrary branches, and maybe all of them.&lt;/p&gt;
&lt;p&gt;You can specify a &amp;#8220;git clean -dfx&amp;#8221; via the &amp;#8220;Clean after checkout&amp;#8221; option under the &amp;#8220;advanced&amp;#8221; section, and you probably should so you get a truly clean build each time.&lt;/p&gt;
&lt;p&gt;You can use the &amp;#8220;Poll SCM&amp;#8221; Build trigger, with the cronjob syntax, to regularly check the git repository for changes. This is not ideal, but to do it properly you&amp;#8217;d need to add a git hook to the git repository to request a build from your jenkins server whenever there is a git commit.&lt;/p&gt;
&lt;h3&gt;Multiple branches&lt;/h3&gt;
&lt;p&gt;You can specify more than one git branch, to make Jenkins try building more than just one, but it&amp;#8217;s hard see what branch was built when looking at the results.&lt;/p&gt;
&lt;h3&gt;Simple maven builds&lt;/h3&gt;
&lt;p&gt;For maven-based Java projects such as &lt;a href=&quot;https://gitorious.org/online-glom&quot;&gt;OnlineGlom&lt;/a&gt;, Jenkins is very straightforward, because maven typically downloads all the dependencies without expecting anything to be installed already, and &amp;#8220;maven package&amp;#8221; typically does the whole build.&lt;/p&gt;
&lt;h3&gt;Autotools builds, or similar&lt;/h3&gt;
&lt;p&gt;For autotools-based projects, you&amp;#8217;ll need to make sure that you&amp;#8217;ve &amp;#8220;apt-get install&amp;#8221;ed the project&amp;#8217;s dependencies.&lt;/p&gt;
&lt;p&gt;Then you must specify the configure and make (or qmake) steps in a build step.&lt;/p&gt;
&lt;p&gt;Of course, many real-world projects will need newer versions of their dependencies. For instance, we build maliit-plugins, which depends on maliit-framework, which we develop in sync. For this, I:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tell the maliit-framework job&amp;#8217;s build to &amp;#8220;make install&amp;#8221; into a local directory, via the &amp;#8220;&amp;#8211;prefix=&amp;#8221; configure option.&lt;/li&gt;
&lt;li&gt;Use an &amp;#8220;archive the artifacts&amp;#8221; post-build action to store everything in that directory.&lt;/li&gt;
&lt;li&gt;Use a &amp;#8220;copy artifacts from another project&amp;#8221; build step in the maliit-plugins job.&lt;/li&gt;
&lt;li&gt;Export several variables so the build system has access to the dependency in the local prefix. For instance, (maliit uses hateful awful qtmake instead of autotools, but you&amp;#8217;d need something similar for autotools):
&lt;pre&gt;
export MALIIT_FW_PREFIX=$WORKSPACE/build_install
export C_INCLUDE_PATH=$MALIIT_FW_PREFIX/include:$C_INCLUDE_PATH
export CPLUS_INCLUDE_PATH=$MALIIT_FW_PREFIX/include:$CPLUS_INCLUDE_PATH
export PKG_CONFIG_PATH=$MALIIT_FW_PREFIX/lib/pkgconfig:$PKG_CONFIG_PATH
export LD_LIBRARY_PATH=$MALIIT_FW_PREFIX/lib:$LD_LIBRARY_PATH
export XDG_DATA_DIRS=$MALIIT_FW_PREFIX/share:$XDG_DATA_DIRS
export XDG_CONFIG_DIRS=$MALIIT_FW_PREFIX/etc/xdg:$XDG_CONFIG_DIRS
export QMAKEFEATURES=$MALIIT_FW_PREFIX/share/qt4/mkspecs/features/:$QMAKEFEATURES&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can use the &amp;#8220;&lt;label&gt;Build after other projects are built&lt;/label&gt;&amp;#8221; build trigger to make Jenkins try a build whenever a dependency is built.&lt;/p&gt;
&lt;p&gt;I have not tried this with multiple built dependencies. I imagine it could get awkard. It feels like Jenkins needs a plugin for autotools to make this simpler.&lt;/p&gt;
&lt;h3&gt;Multiple configurations&lt;/h3&gt;
&lt;p&gt;You can create &amp;#8220;multiple configuration&amp;#8221; jobs to try multiple ways of building your project. For instance, you might provide different sets of options to your configure script. But I couldn&amp;#8217;t use this feature due to the &lt;a href=&quot;https://issues.jenkins-ci.org/browse/JENKINS-15896&quot;&gt;spaces that it puts in the build path&lt;/a&gt;s. So I created separate top-level jobs for each configuration. Other people seem to do the same, maybe for the same reason.&lt;/p&gt;
&lt;h3&gt;Email notifcation&lt;/h3&gt;
&lt;p&gt;I&amp;#8217;ve tried using Amazon&amp;#8217;s &lt;a href=&quot;https://console.aws.amazon.com/ses/home&quot;&gt;Simple Email Service &lt;/a&gt;to send notification emails about build failures, but I don&amp;#8217;t have that working yet. I&amp;#8217;ll update this if I do.&lt;/p&gt;</description>
	<pubDate>Mon, 10 Dec 2012 11:38:53 +0000</pubDate>
</item>
<item>
	<title>Murray Cumming: Programming For Kids</title>
	<guid>http://www.murrayc.com/blog/?p=1776</guid>
	<link>http://www.murrayc.com/permalink/2012/11/29/programming-for-kids/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=programming-for-kids</link>
	<description>&lt;p&gt;I tried a couple of applications with my four-year-old son: &lt;a href=&quot;http://www.piktomir.ru/&quot;&gt;Pictomir&lt;/a&gt; and MIT&amp;#8217;s &lt;a href=&quot;http://scratch.mit.edu/&quot;&gt;Scratch&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Neither seem particularly well maintained and neither are suitable for young children without lots of supervision. Pictomir is easier to get started with, but not easy enough. Scratch is probably more interesting to older children, though they&amp;#8217;ll partly be learning about how software is still so often arbitrarily annoying, and I&amp;#8217;d prefer that they were introduced via a better example. I&amp;#8217;m very tempted to write something better.&lt;/p&gt;
&lt;h3&gt;Pictomir&lt;/h3&gt;
&lt;div id=&quot;attachment_1802&quot; class=&quot;wp-caption alignright&quot;&gt;&lt;a href=&quot;http://www.murrayc.com/blog/wp-content/uploads/2012/11/screenshot-pictomir.png&quot;&gt;&lt;img class=&quot;size-medium wp-image-1802&quot; title=&quot;screenshot-pictomir&quot; alt=&quot;pictomir&quot; src=&quot;http://www.murrayc.com/blog/wp-content/uploads/2012/11/screenshot-pictomir-300x219.png&quot; width=&quot;300&quot; height=&quot;219&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Pictomir at first start up.&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;http://www.piktomir.ru/&quot;&gt;Pictomir&lt;/a&gt; leads the child through a series of levels, telling an R2D2 robot (Don&amp;#8217;t tell George Lucas) to move around some isomorphic squares to paint some tiles. At the beginning the program exists and the child just needs to click the play button. In subsequent stages the child has to build part of the program himself, and then all of the program.&lt;/p&gt;
&lt;p&gt;The available commands, at least at the start, are icons for left-turn, forwards, right-turn and paint at the top of the screen. These may be be dragged into the available boxes in the program at the right of the screen, though you can instead put them there by clicking to select and then clicking on the empty box in the program. However, the available commands are far away from the program where you must place them, so the child has to spend lots of time moving the mouse pointer back and forth across a wasteland of empty space.&lt;/p&gt;
&lt;p&gt;I found an official Ubuntu package in the &lt;a href=&quot;https://launchpad.net/~v-yacovlev/+archive/lpm&quot;&gt;developer&amp;#8217;s PPA&lt;/a&gt;. It was last updated to Ubuntu 10.10 (Maverick), but you can install it manually on later versions. All of its UI is in Russian, though you can ignore most of it because the UI is icon-based. When I built the newer code from source a few months ago, I think the UI was translated.&lt;/p&gt;
&lt;p&gt;I guess that Pictomir was developed for a specific screen size and generally older PCs. It does not scale the playing area up, so the child has to deal with a tiny R2D2 on a tiny grid in the middle of wide empty space.&lt;/p&gt;
&lt;p&gt;pictomir has a bare &lt;a href=&quot;http://lpm.org.ru/svn/pictomir/&quot;&gt;svn repository&lt;/a&gt;, though I can&amp;#8217;t see how clean its commits are, and I don&amp;#8217;t know if it&amp;#8217;s still used. There are no commits since last year. My svn says that the svn format is too old to check it out, though I&amp;#8217;ve checked it on on previous Ubuntu installations.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s website it quite awful (and only in Russian). I only &lt;a href=&quot;https://plus.google.com/100123542880051296706/posts/bN7bptbUaaY&quot;&gt;discovered&lt;/a&gt; Pictomir thanks to commenters on Google+.&lt;/p&gt;
&lt;h3&gt;Scratch&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&quot;http://scratch.mit.edu/&quot;&gt;Scratch&lt;/a&gt; UI has several problems that make life hard for the child:&lt;/p&gt;
&lt;div id=&quot;attachment_1799&quot; class=&quot;wp-caption alignright&quot;&gt;&lt;a href=&quot;http://www.murrayc.com/blog/wp-content/uploads/2012/11/screenshot-scratch.png&quot;&gt;&lt;img class=&quot;size-medium wp-image-1799&quot; title=&quot;screenshot-scratch&quot; alt=&quot;scratch&quot; src=&quot;http://www.murrayc.com/blog/wp-content/uploads/2012/11/screenshot-scratch-300x221.png&quot; width=&quot;300&quot; height=&quot;221&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Scratch, after creating and running a small program.&lt;/p&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Scratch requires the child to cope with tiny targets (See Fitt&amp;#8217;s Law)&lt;/li&gt;
&lt;li&gt;Scratch demands the use of drag and drop. This is frustrating for normal users, let alone children, and really hard with some laptop touchpads or trackpoints.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Update&lt;/strong&gt;: Scratch requires the child to understand the difference between left-click and right-click. Right-click brings up a help context menu, which just causes confusion.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Update&lt;/strong&gt;: The tiny commands have tiny text edit boxes. Children have a high chance of clicking it instead of clicking the command block itself. This problem could be partly solved by accepting drags on the edit box.&lt;/li&gt;
&lt;li&gt;Scratch requires the child to double-click (see below).&lt;/li&gt;
&lt;li&gt;The commands require the children to read, but a subset of the commands could instead be respresented by icons. The words are particularly hard for beginner readers because they are written in such a tiny font.&lt;/li&gt;
&lt;li&gt;To get started with scratch, you need to figure out that you need to double-click on the first program command to actually start your program. There is no simple run button. You can cause your program to be run by clicking the green Flag button, but that&amp;#8217;s something you need to put in your program.&lt;/li&gt;
&lt;li&gt;When you try to move a command around in the program, it moves the command and all subsequent commands, as a group. So moving just one command means moving stuff around and then moving some of the stuff back to where you started.&lt;/li&gt;
&lt;li&gt;Your program moves the Scratch cat sprite around the canvas, but that canvas is tiny, and the sprite can move off screen. The only way I found to get it back was to double-click the set-x-to and set-y-to program commands. I can figure that out, but beginners will not.&lt;/li&gt;
&lt;li&gt;When you&amp;#8217;ve drawn all over your canvas, the only way to wipe it is to go to the Pen set of commands and double-click the Clear command.&lt;/li&gt;
&lt;li&gt;The sprite moves far too fast for the child to understand the relationship between the commands and the motion, without someone explaining it. If the command says move-10-steps then I&amp;#8217;d expect the sprite to visibly move 10 steps. Advanced users might prefer it to be faster and smoother, but the default should make things obvious.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are some other strange things in the UI which are probably a side-effect of its eccentric (Smalltalk) implementation.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scratch has a menu (well, an icon-menu) for changing its language, instead of just using the user&amp;#8217;s regular language.&lt;/li&gt;
&lt;li&gt;None of the UI elements (menus, tabs, buttons, file chooser dialog, etc) match other standard applications on the system.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think Scratch could be really popular with younger kids if it ran on Android with a touch interface and with less text, maybe as a simpler version. But the developers don&amp;#8217;t seem to have any interest in that &amp;#8211; they seem to be working on a &lt;a href=&quot;http://wiki.scratch.mit.edu/wiki/Scratch_2.0&quot;&gt;Flash-based version of Scratch&lt;/a&gt; for the web, which is unlikely to work well with touchscreens, even if they can get Flash to work on Android and iPhone (they won&amp;#8217;t). And I have no interest in hacking on Smalltalk. There seem to be various programming-language-based forks of at least the underlying engine, but none seem to be successful.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
	<pubDate>Thu, 29 Nov 2012 11:53:26 +0000</pubDate>
</item>
<item>
	<title>Murray Cumming: Online Glom: Image fields</title>
	<guid>http://www.murrayc.com/blog/?p=1767</guid>
	<link>http://www.murrayc.com/permalink/2012/11/22/online-glom-image-fields/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=online-glom-image-fields</link>
	<description>&lt;p&gt;I found some work in one of my old branches and cleaned it up, so now &lt;a href=&quot;http://www.glom.org/wiki/index.php?title=Development/OnlineGlom&quot;&gt;OnlineGlom&lt;/a&gt; supports image fields too.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.murrayc.com/blog/wp-content/uploads/2012/11/screenshot-online-glom-with-image.png&quot;&gt;&lt;img class=&quot;size-medium wp-image-1780 alignright&quot; title=&quot;screenshot-online-glom-with-image&quot; src=&quot;http://www.murrayc.com/blog/wp-content/uploads/2012/11/screenshot-online-glom-with-image-173x300.png&quot; alt=&quot;Online Glom with an image field&quot; width=&quot;173&quot; height=&quot;300&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As usual, it was far more work than seemed necessary. GWT&amp;#8217;s Image widget is not much more than a wrapper around the HTML &amp;lt;img&amp;gt; tag, so I had to create a separate service, with the same authentication system, to serve image data and invent a URL syntax to refer to the images from the database. It is certainly easier with GTK+ code on the desktop, even when delivering the image data asynchronously. This feels like something that a web progamming system should take care of, even if this is what happens behind the scenes. I wonder if any do.&lt;/p&gt;
&lt;p&gt;Next, I want to make sure that OnlineGlom can handle tables whose primary keys are not numeric, because we&amp;#8217;ve been hard-coding that in a few places. Then I hope I can start the big job of supporting data editing.&lt;/p&gt;</description>
	<pubDate>Thu, 22 Nov 2012 12:15:01 +0000</pubDate>
</item>
<item>
	<title>Murray Cumming: gtkmm maintainership</title>
	<guid>http://www.murrayc.com/blog/?p=1763</guid>
	<link>http://www.murrayc.com/permalink/2012/11/08/gtkmm-maintainership/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=gtkmm-maintainership</link>
	<description>&lt;p&gt;I have not had enough time recently for my maintainership of gtkmm, glibmm, libxml++ and libsigc++. And I&amp;#8217;m unlikely to find time soon. Family and (income earning) work have taken priority. That&amp;#8217;s why glibmm and gtkmm didn&amp;#8217;t have .0 releases until a couple of weeks after the GNOME .0 release, and why there was no real attempt to follow the GNOME release schedule this time. I&amp;#8217;ve hardly touched cairomm for years.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s not a lot of work but I&amp;#8217;ve had to find a few days every few months to keep glibmm and gtkmm up to date with API additions in glib and GTK+, to keep roughly in sync with them. There has been rather a lot of new API recently. See the list of new API in &lt;a href=&quot;https://mail.gnome.org/archives/gtkmm-list/2012-November/msg00024.html&quot;&gt;gtkmm 3.6&lt;/a&gt;, &lt;a href=&quot;https://mail.gnome.org/archives/gtkmm-list/2012-November/msg00023.html&quot;&gt;glibmm 2.34&lt;/a&gt; , &lt;a href=&quot;https://mail.gnome.org/archives/gtkmm-list/2012-April/msg00023.html&quot;&gt;gtkmm 3.4&lt;/a&gt;, and &lt;a href=&quot;https://mail.gnome.org/archives/gtkmm-list/2012-April/msg00024.html&quot;&gt;glibmm 2.32&lt;/a&gt;. Krzesimir&amp;#8217;s ongoing attempt to use the introspection information (rather than .defs files) would help with this but not hugely because we&amp;#8217;d still need to take care that the API is right for C++. Some initial .hg/ccg creator script would probably be most helpful.&lt;/p&gt;
&lt;p&gt;I have no time for the more difficult bugs that turn up occasionally. Luckily Kjell Ahlstedt, José Alburquerque and others arrive regularly in bugzilla with great fixes for hard problems. I trust Kjell and José to commit directly, but they deserve some decent patch review. Unfortunately I often keep them waiting far too long.&lt;/p&gt;
&lt;p&gt;I need to make some change. As a start, I might stop receiving bug email for glibmm and gtkmm, and stop worrying about adding new API. I guess it will take at least one missed GNOME release cycle for some other people to take over my responsibilities.&lt;/p&gt;</description>
	<pubDate>Thu, 08 Nov 2012 11:14:47 +0000</pubDate>
</item>
<item>
	<title>Jan Arne Petersen: EFL integration for Wayland input methods</title>
	<guid>http://blog.jpetersen.org/?p=133</guid>
	<link>http://blog.jpetersen.org/2012/10/25/efl-integration-for-wayland-input-methods/</link>
	<description>&lt;p&gt;3 days ago &lt;a href=&quot;http://wayland.freedesktop.org/&quot;&gt;Wayland&lt;/a&gt; and Weston 1.0 were &lt;a href=&quot;http://lists.freedesktop.org/archives/wayland-devel/2012-October/005967.html&quot;&gt;released&lt;/a&gt;. We at &lt;a href=&quot;http://www.openismus.com&quot;&gt;Openismus&lt;/a&gt; are working on input method support for Wayland (see &lt;a href=&quot;http://blog.jpetersen.org/2012/06/20/text-input-method-support-in-wayland/&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;http://blog.jpetersen.org/2012/09/18/text-input-method-support-in-wayland-update/&quot;&gt;here&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;To show the input methods working we have an &lt;a href=&quot;http://cgit.freedesktop.org/wayland/weston/tree/clients/editor.c&quot;&gt;editor&lt;/a&gt; and &lt;a href=&quot;http://cgit.freedesktop.org/wayland/weston/tree/clients/keyboard.c&quot;&gt;keyboard&lt;/a&gt; example client in Weston. But we also want to demo input methods in real world applications. As a start we implemented an input method module for the &lt;a href=&quot;http://trac.enlightenment.org/e/wiki/EFLOverview&quot;&gt;EFL (Enlightenment Foundation Libraries)&lt;/a&gt; toolkit.&lt;/p&gt;
&lt;p&gt;The EFL input method module is available at &lt;a href=&quot;https://github.com/openismus/ecore-imf-wayland&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://jpetersen.org/videos/wayland-input-methods-efl.mp4&quot;&gt;screen cast&lt;/a&gt;&lt;/p&gt;</description>
	<pubDate>Thu, 25 Oct 2012 18:15:56 +0000</pubDate>
</item>
<item>
	<title>Jens Georg: PushUp 0.3.0</title>
	<guid>http://jensge.org/?p=713</guid>
	<link>http://jensge.org/2012/06/pushup-0-3-0/</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://jensge.org/pushup_0.3.0-1_armel.deb&quot;&gt;&lt;img class=&quot;size-full wp-image-714 alignright&quot; title=&quot;pushup_0.3.0-1_armel.deb&quot; src=&quot;http://jensge.org/wp-content/uploads/2012/06/pushup_0.3.0-1_armel.deb_.png&quot; alt=&quot;&quot; width=&quot;111&quot; height=&quot;111&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Installing this version will REBOOT your device!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;Also, if you have installed the previous version from OVI store, you need to uninstall it first before installing this version.&lt;/p&gt;
&lt;p&gt;I have release a new version of PushUp. Most notable changes, aside those from syncing with upstream korva, are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Compatibility with devices that need file extensions on the HTTP URLs&lt;/li&gt;
&lt;li&gt;The possibility to share files which are unknown to Tracker&lt;/li&gt;
&lt;li&gt;Drop the libffi dependency which caused install issues for some people&lt;/li&gt;
&lt;li&gt;Next try on using a nice icon in the share dialog&lt;/li&gt;
&lt;li&gt;Default icons for remote devices&lt;/li&gt;
&lt;li&gt;An option to cancel transfers using Transfer UI&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;Please note that due to the slight issues with the N9&amp;#8242;s sharing ui, &lt;em&gt;the device has to reboot after installing PushUp. This will happen automatically.&lt;/em&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;As usual, it&amp;#8217;s available &lt;a href=&quot;http://jensge.org/pushup_0.3.0-1_armel.deb&quot;&gt;here&lt;/a&gt;, at &lt;a href=&quot;http://apps.formeego.com/staging/applications/n9/pr1.0/harmattan/Multimedia/pushup/&quot;&gt;apps.formeego.com&lt;/a&gt; or in &lt;a href=&quot;http://store.ovi.com/content/272618&quot;&gt;OVI store&lt;/a&gt;.&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;http://jensge.org/wp-content/uploads/2012/06/2012-06-29_10-03-33.png&quot;&gt;&lt;img class=&quot;alignnone size-medium wp-image-745&quot; title=&quot;2012-06-29_10-03-33&quot; src=&quot;http://jensge.org/wp-content/uploads/2012/06/2012-06-29_10-03-33-168x300.png&quot; alt=&quot;&quot; width=&quot;168&quot; height=&quot;300&quot; /&gt;&lt;/a&gt;      &lt;a href=&quot;http://jensge.org/wp-content/uploads/2012/06/2012-06-24_16-51-46.png&quot;&gt;&lt;img class=&quot;alignnone size-medium wp-image-716&quot; title=&quot;2012-06-24_16-51-46&quot; src=&quot;http://jensge.org/wp-content/uploads/2012/06/2012-06-24_16-51-46-168x300.png&quot; alt=&quot;&quot; width=&quot;168&quot; height=&quot;300&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description>
	<pubDate>Sat, 20 Oct 2012 12:11:42 +0000</pubDate>
</item>
<item>
	<title>Jens Georg: Rygel + Transcoding on Ubuntu 12.10</title>
	<guid>http://jensge.org/?p=812</guid>
	<link>http://jensge.org/2012/10/rygel-transcoding-on-ubuntu-12-04/</link>
	<description>&lt;p&gt;Update: As Jeremy points out, the update has been synched. All should be well now.&lt;/p&gt;
&lt;p&gt;Update: This post only applies to the package on 12.10 and will be fixed when Ubuntu resyncs Rygel from Debian.&lt;/p&gt;
&lt;p&gt;It seems that the Rygel package is missing some important files which renders the transcoding non-functional.&lt;/p&gt;
&lt;p&gt;A work-around is to download the files from &lt;a href=&quot;http://git.gnome.org/browse/rygel/tree/data/presets&quot;&gt;http://git.gnome.org/browse/rygel/tree/data/presets&lt;/a&gt;&lt;br /&gt;
and drop them into &lt;code&gt;/usr/share/rygel/presets&lt;/code&gt;.&lt;/p&gt;</description>
	<pubDate>Mon, 08 Oct 2012 15:04:24 +0000</pubDate>
</item>
<item>
	<title>Murray Cumming: Openismus at UDS</title>
	<guid>http://www.murrayc.com/blog/?p=1752</guid>
	<link>http://www.murrayc.com/permalink/2012/09/28/openismus-at-uds/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=openismus-at-uds</link>
	<description>&lt;p&gt;I just booked my travel and hotel to visit the &lt;a href=&quot;http://uds.ubuntu.com/&quot;&gt;Ubuntu Developer Conference&lt;/a&gt; in Copenhagen at the end of October, along with Michael Hasselmann and Mathias Hasselmann, all of us representing &lt;a href=&quot;http://www.openismus.com/&quot;&gt;Openismus&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I think this will be my first UDS since &lt;a href=&quot;http://www.murrayc.com/blog/permalink/2006/11/16/ubuntu-developer-summit-mountain-view/&quot;&gt;UDS, Mountain View in 2006&lt;/a&gt; and half a day at &lt;a href=&quot;http://www.murrayc.com/blog/permalink/2008/05/21/brussels-and-prague/&quot;&gt;UDS, Prague in 2008&lt;/a&gt;. Lots has changed since then.&lt;/p&gt;</description>
	<pubDate>Fri, 28 Sep 2012 09:38:07 +0000</pubDate>
</item>
<item>
	<title>Jens Georg: UPnP Hall of shame</title>
	<guid>http://jensge.org/?p=792</guid>
	<link>http://jensge.org/2012/08/upnp-hall-of-shame/</link>
	<description>&lt;p&gt;This XML snippet is from a LG TV:&lt;/p&gt;
&lt;p&gt;Duration is supposed to be a string representation of an integer. Well done, guys m(&lt;/p&gt;</description>
	<pubDate>Sun, 23 Sep 2012 20:18:07 +0000</pubDate>
</item>
<item>
	<title>Murray Cumming: Openismus Revived</title>
	<guid>http://www.murrayc.com/blog/?p=1747</guid>
	<link>http://www.murrayc.com/permalink/2012/09/20/openismus-revived/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=openismus-revived</link>
	<description>&lt;p&gt;Here&amp;#8217;s an update since my &lt;a href=&quot;http://www.murrayc.com/blog/permalink/2012/06/22/openismus-status/&quot;&gt;last status post in June&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Things have improved for &lt;a href=&quot;http://www.openismus.com/&quot;&gt;Openismus&lt;/a&gt; even more though we are not complacent. Several proposals, including the ones I mentioned in that last blog post, have resulted in customer contracts. So we are now busy working on the Maliit input method system (virtual keyboard), Wayland, Rygel UPnP/DLNA and Evolution Data Server (EDS). We are even thinking of hiring another developer if we can find someone who is just right.&lt;/p&gt;
&lt;p&gt;We are now established in the habit of creating proposals for customers, revising them, and shifting into implementation. We take our customer proposals seriously, making sure that the developers are the main authors and making sure that they don&amp;#8217;t leave questions unanswered. If there&amp;#8217;s something we might help your company with then we&amp;#8217;d like the chance to convince you too.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://mikhas.posterous.com/&quot;&gt;Michael Hasselmann&lt;/a&gt; is now the main person negotiating new work for us and keeping some of that work on schedule. He has been very successful &amp;#8211; a surprise to himself but not to us. We are calling him a Sales Engineer but that doesn&amp;#8217;t really do his dedication justice.&lt;/p&gt;
&lt;p&gt;Michael can travel much more than I could for the last few years. Right now he&amp;#8217;s at the &lt;a href=&quot;http://events.linuxfoundation.org/events/automotive-linux-summit&quot;&gt;Automotive Linux Summit&lt;/a&gt; in the UK and tomorrow he will be at the &lt;a href=&quot;http://www.x.org/wiki/Events/XDC2012&quot;&gt;X Developers Conference&lt;/a&gt; in Nürnberg with &lt;a href=&quot;http://blog.jpetersen.org/&quot;&gt;Jan Arne Petersen&lt;/a&gt; (where our interest is mostly in Wayland and input methods). On Monday and Tuesday he&amp;#8217;ll visit me in the Munich office.&lt;/p&gt;
&lt;p&gt;We have achieved this thanks, of course, to the hard work of our whole team at Openismus. They have fought hard so we can all keep doing worthwhile work that we enjoy. I am proud of them and glad to be part of this.&lt;/p&gt;</description>
	<pubDate>Thu, 20 Sep 2012 16:01:03 +0000</pubDate>
</item>
<item>
	<title>Jens Georg: Helium 0.6.0</title>
	<guid>http://jensge.org/?p=802</guid>
	<link>http://jensge.org/2012/09/helium-0-6-0/</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://jensge.org/helium_0.6.0_armel.deb&quot;&gt;&lt;img class=&quot;alignleft size-full wp-image-803&quot; title=&quot;Helium 0.6.0&quot; src=&quot;http://jensge.org/wp-content/uploads/2012/09/qrcode_helium_0.6.0_armel.deb_.png&quot; alt=&quot;&quot; width=&quot;111&quot; height=&quot;111&quot; /&gt;&lt;/a&gt;Helium 0.6.0 is available. It mostly contains back-end changes, but  several user-visible changes as well:&lt;/p&gt;
&lt;h2&gt;Improved seeking&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://jensge.org/wp-content/uploads/2012/09/player-seeking-scaled-screenshot.png&quot;&gt;&lt;img class=&quot;alignright size-medium wp-image-804&quot; title=&quot;player-seeking-scaled-screenshot&quot; src=&quot;http://jensge.org/wp-content/uploads/2012/09/player-seeking-scaled-screenshot-300x138.png&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;138&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;The handling of seeking in the player view has been improved. The area that reacts to the&lt;br /&gt;
seeking has been enlarged and the the flicking doesn&amp;#8217;t steal the events anymore. A tool-tip will show the current seek position.&lt;/div&gt;
&lt;h2&gt;&lt;a href=&quot;http://jensge.org/wp-content/uploads/2012/09/filtering-scaled-screenshot.png&quot;&gt;&lt;img class=&quot;alignleft size-medium wp-image-806&quot; title=&quot;filtering-scaled-screenshot&quot; src=&quot;http://jensge.org/wp-content/uploads/2012/09/filtering-scaled-screenshot-300x206.png&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;206&quot; /&gt;&lt;/a&gt;Filtering&lt;/h2&gt;
&lt;p&gt;It is now possible to filter the list of media files. To activate the filter input, just drag down and pull the list at the top as in every other program on the device. By default the filtering will only work on the titles. This can be changed in settings to match against most of the other meta-data as well.&lt;/p&gt;
&lt;h2&gt;Debugging&lt;a href=&quot;http://jensge.org/wp-content/uploads/2012/09/settings-scaled-screenshot.png&quot;&gt;&lt;img class=&quot;alignright size-medium wp-image-807&quot; title=&quot;settings-scaled-screenshot&quot; src=&quot;http://jensge.org/wp-content/uploads/2012/09/settings-scaled-screenshot-300x192.png&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;192&quot; /&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It&amp;#8217;s now possible to log the UPnP traffic to help debugging of interoperability issues. By default, the log file is written to MyDocs to enable easy transfer of the log files via mass storage mode.&lt;/p&gt;</description>
	<pubDate>Tue, 18 Sep 2012 16:17:56 +0000</pubDate>
</item>
<item>
	<title>Jan Arne Petersen: Text Input Method Support in Wayland ‒ Update</title>
	<guid>http://blog.jpetersen.org/?p=124</guid>
	<link>http://blog.jpetersen.org/2012/09/18/text-input-method-support-in-wayland-update/</link>
	<description>&lt;p&gt;In my last &lt;a href=&quot;http://blog.jpetersen.org/2012/06/20/text-input-method-support-in-wayland&quot; title=&quot;Text Input Method Support in Wayland&quot;&gt;post about Text Input Method Support in Wayland&lt;/a&gt; I wrote about a input methods technical demo which I created for &lt;a href=&quot;http://wayland.freedesktop.org/&quot;&gt;Weston&lt;/a&gt; (the Wayland reference compositor). That work got merged into Weston and got improved allot since: The &lt;a href=&quot;http://cgit.freedesktop.org/wayland/weston/tree/protocol/text.xml&quot;&gt;text_model&lt;/a&gt; and &lt;a href=&quot;http://cgit.freedesktop.org/wayland/weston/tree/protocol/input-method.xml&quot;&gt;input_method&lt;/a&gt; interfaces got all the basic requests and events, which are required to get a simple virtual keyboard working. Focus handling to track focus via wl_seat was implemented. The example keyboard and editor clients got also improved to better showcase the available features. There is a screencast for demo:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://jpetersen.org/videos/wayland-ims-prototype.mp4&quot;&gt;screen cast&lt;/a&gt;&lt;/p&gt;</description>
	<pubDate>Tue, 18 Sep 2012 13:47:38 +0000</pubDate>
</item>
<item>
	<title>Michael Hasselmann: Travel plans for September</title>
	<guid>http://mikhas.posterous.com/travel-plans-for-september</guid>
	<link>http://mikhas.posterous.com/travel-plans-for-september</link>
	<description>&lt;p&gt;
	&lt;p&gt;Planning my travels for September made me yearn for a travel assistant &amp;mdash; it&amp;rsquo;s impressive how much time one can waste with crappy booking websites and clueless hotel staff. On the other hand, doing it myself allowed me to shuffle things around until I was happy with the plan. Not sure my imagined travel assistant would have had that much patience ;&amp;ndash;)&lt;/p&gt;

&lt;p&gt;Anyway, tomorrow I&amp;rsquo;ll be attending the &lt;a href=&quot;http://events.linuxfoundation.org/events/automotive-linux-summit&quot;&gt;2nd Automotive Linux Summit&lt;/a&gt; (Sep 19-20) and &lt;a href=&quot;http://events.linuxfoundation.org/events/automotive-linux-summit/schedule&quot;&gt;the schedule&lt;/a&gt; is &lt;em&gt;packed&lt;/em&gt; with interesting talks. Sadly, there won&amp;rsquo;t be any time for me to visit Warwick Castle again, which is just 15 minutes away from the venue. They say it&amp;rsquo;s for kids, but the &lt;a href=&quot;http://www.warwick-castle.com/whats-on/daily-shows.aspx&quot;&gt;Warwick Castle daily shows&lt;/a&gt; are well worth a visit, even for grown-up kids.&lt;/p&gt;

&lt;p&gt;The Automotive Linux Summit clashes with the &lt;a href=&quot;http://www.x.org/wiki/Events/XDC2012&quot;&gt;X Developer Conference&lt;/a&gt; (Sep 19-21) in Nuremberg, which means I can only attend XDC on Friday (and perhaps the beer hike on Saturday). Now, I haven&amp;rsquo;t suddenly become a X hacker over night, but I want to know how the progress in Wayland is perceived and whether there&amp;rsquo;s some good advice for our &lt;a href=&quot;http://blog.jpetersen.org/2012/09/18/text-input-method-support-in-wayland-update/&quot;&gt;Wayland input method work&lt;/a&gt;. It would have been a great opportunity for me to learn more about EGL and new trends in OpenGL, but I&amp;rsquo;ll have to leave that to my colleague &lt;a href=&quot;http://blog.jpetersen.org/&quot;&gt;Jan Arne Petersen&lt;/a&gt;, who will attend the whole conference.&lt;/p&gt;

&lt;p&gt;After staying in Nuremberg for the weekend, I will spend a few days in Munich (&lt;em&gt;not&lt;/em&gt; for the Wiesn) before I head home to Berlin.&lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href=&quot;http://www.openismus.com&quot;&gt;Openismus&lt;/a&gt; for sending me to ALS and XDC!&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://mikhas.posterous.com/travel-plans-for-september&quot;&gt;Permalink&lt;/a&gt; 

	| &lt;a href=&quot;http://mikhas.posterous.com/travel-plans-for-september#comment&quot;&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;</description>
	<pubDate>Tue, 18 Sep 2012 08:56:00 +0000</pubDate>
</item>
<item>
	<title>Jens Georg: A common mistake in UPnP</title>
	<guid>http://jensge.org/?p=785</guid>
	<link>http://jensge.org/2012/08/a-common-mistake-in-upnp/</link>
	<description>&lt;p&gt;We get a lot of reports of UPnP AV clients not working properly with Rygel. It either isn&amp;#8217;t seen by the client at all or does not show any content.&lt;/p&gt;
&lt;p&gt;The reason is usually the same. People are not following the specs. Rygel seems to be one of the few UPnP-AV/DLNA server out there that implements a higher version of the UPnP-AV specification than :1. A lot of clients are explicitly testing for this version, ignoring higher versions although the UPnP standard states that higher version services need to be backward-compatible. (cf. UDA 1.1, section 1.2.2, last paragraph on page 10). Of course we can work around that &amp;#8211; and we do, but the list of exceptions is getting longer and longer and to be honest I&amp;#8217;m starting to get really annoyed of those fixes.&lt;/p&gt;
&lt;p&gt;I expect that there will be more and more devices with higher versions now that DLNA has added features that require higher versions of the specification than :1. So pretty please get your clients fixed. And if you don&amp;#8217;t want to, &lt;a href=&quot;https://bugzilla.gnome.org/show_bug.cgi?id=680743&quot; target=&quot;_blank&quot;&gt;then don&amp;#8217;t make it extra complicated to work around your bug&lt;/a&gt;. But really, fix it.&lt;/p&gt;
&lt;p&gt;And please have a working support email address so I can complain directly. About every client author I tried to contact has bounced &amp;#8211; and the rest ignored me.&lt;/p&gt;</description>
	<pubDate>Tue, 28 Aug 2012 06:55:47 +0000</pubDate>
</item>
<item>
	<title>Tristan Van Berkom: Glade @ GUADEC</title>
	<guid>http://blogs.gnome.org/tvb/?p=305</guid>
	<link>http://blogs.gnome.org/tvb/2012/07/23/glade-guadec/</link>
	<description>&lt;p&gt;Hi everyone,&lt;/p&gt;
&lt;p&gt;Long time no blog. I&amp;#8217;ve been meaning to blog and build hype around this but as I&amp;#8217;ve been busy with so many things it just hasnt come out.&lt;/p&gt;
&lt;p&gt;Well the first thing so say is, please be interested to click this link and visit &lt;a href=&quot;http://blogs.gnome.org/xjuan/&quot; target=&quot;_blank&quot;&gt;Juan Pablo&amp;#8217;s blog&lt;/a&gt;. He is speaking first thing on the first day of GUADEC on the topic of embedding GtkBuilder script natively into GtkContainer derived widgets. Some may remember some of &lt;a href=&quot;http://blogs.gnome.org/tvb/2010/03/08/it-was-a-saturday-afternoon-patch/&quot; target=&quot;_blank&quot;&gt;my ancient&lt;/a&gt; &lt;a href=&quot;http://blogs.gnome.org/tvb/2010/03/14/composite-saga-continues/&quot; target=&quot;_blank&quot;&gt;blog posts&lt;/a&gt; on the same topic, I never found time to complete the patches in the composite-containers branch but Juan Pablo has picked up the work with a fury and is going to explain in more details in his talk.&lt;/p&gt;
&lt;p&gt;In a last minute decision, as the dates are right, I also decided to drop in too. With all the work Juan has already done, a little consensus and participation hopefully we can finally pull off this great feature.&lt;/p&gt;
&lt;p&gt;See you there &lt;img src=&quot;http://blogs.gnome.org/tvb/wp-content/mu-plugins/tango-smilies/tango/face-wink.png&quot; alt=&quot;;-)&quot; class=&quot;wp-smiley&quot; /&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
	<pubDate>Mon, 23 Jul 2012 21:01:14 +0000</pubDate>
</item>
<item>
	<title>Krzesimir Nowak: Gmmproc progress</title>
	<guid>tag:blogger.com,1999:blog-1677281587803116780.post-3705910071574566078</guid>
	<link>http://krnowak.blogspot.com/2012/07/gmmproc-progress.html</link>
	<description>I have recently pushed over 30 commits to &lt;a href=&quot;http://git.gnome.org/browse/glibmm/log/?h=gmmproc-refactor&quot;&gt;glibmm gmmproc-refactor branch&lt;/a&gt;. This concludes gmmproc's first &quot;milestone&quot; - to generate glibmm sources, build a library, build the tests and examples and finally succesfully run the tests. But by saying &quot;glibmm&quot; I mean only GLib wrappers - Gio wrappers are next on the list.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;First milestone?&lt;/h3&gt;&lt;br /&gt;Yeah, right, as if there are any. That &quot;first milestone&quot; may look modest, but I actually think that it is like 75% of work done. GIR parsing, type conversions system, parsing templates, replacing m4 code with perl and then tying them and squeezing them with foot into some semblance of a program - all of those had to be written to  have something working.&lt;br /&gt;&lt;br /&gt;I haven't yet made any benchmarks of gmmproc rewrite, but right now it seems to be faster than the old one. Still old one can be faster if we run parallel build (make -jX) - there is one of main differences between currently used gmmproc and its rewrite. The former processes and writes one set of files (like from widget.hg and widget.ccg to widget.h, widget.cc and widget_p.h) on every run, while the former processes all files in single run. That forces me to actually do parallel processing inside my program instead of reusing make's powers. Fortunately, I tried to write most of my code in a way that parallelizing it would be easy if done in OpenMP style.&lt;br /&gt;&lt;br /&gt;Talking about speed - there is one area I would like to speed up in general - GIR parsing. It looks like the slowest part of whole gmmproc, but I didn't yet tried to profile it. I was thinking about using typelib instead, but from what I heard, there is no detailed C type information there (the &quot;c:type&quot; attributes from gir). This is still to be confirmed as it is not on top of my nowhere written list. Otherwise, using typelib would be, I imagine, faster. Provided that C-to-perl interface to GIRepository is written first - whooo, yak shaving! &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Some plans&lt;/h3&gt;&lt;br /&gt;Still, I feel no hurry in rewriting as I rather see it to be used in next version of glibmm/gtkmm (I assume that those will be glibmm-4 and gtkmm-4). Thus I am not writing a strict drop-in replacement - I already have made (or I plan to make) some changes in generated API (like exception-to-GError conversion in vfuncs wrappers) and in template API (I would like to get rid of _CUSTOM_CTOR_CAST and similar in favour of _CLASS_FOO options).&lt;br /&gt;&lt;br /&gt;There is still much to be done beside threading the application:&lt;br /&gt;1. generating Doxygen documentation based on docs in GIR,&lt;br /&gt;2. code documentation,&lt;br /&gt;3. gmmproc macros documentation,&lt;br /&gt;4. tests (there are some, but still not enough),&lt;br /&gt;5. reports about unwrapped classes and functions,&lt;br /&gt;6. and probably more. &lt;br /&gt;&lt;br /&gt;I am happy to get this far and to actually finally see something more or less working.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Small disclaimer&lt;/h3&gt;&lt;br /&gt;The code is ugly mess. It needs to be reorganized, reshuffled in  several places. WrapParser class is huge, even with moving some  functions into shared modules. 'use' clauses have to be reviewed.  'constant' module for section traits was probably a crappy idea. Sometimes class/function naming is bogus (identity conversions, imbued types, tokens  store?). Code style is very inconsistent (I started reading &lt;a href=&quot;http://www.onyxneon.com/books/modern_perl/index.html&quot;&gt;Modern Perl&lt;/a&gt;  somewhere in the middle).&lt;br /&gt;Oh, and commit messages are useless - they are probably going to be squashed at some point into single enormous commit for merging into master (and I am going to get only +1 commit of contribution on glibmm on Ohloh, damn!).&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/1677281587803116780-3705910071574566078?l=krnowak.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Mon, 23 Jul 2012 06:30:57 +0000</pubDate>
</item>
<item>
	<title>Jens Georg: Rygel split-up</title>
	<guid>http://jensge.org/?p=750</guid>
	<link>http://jensge.org/2012/07/rygel-split-up/</link>
	<description>&lt;p&gt;Following up on &lt;a href=&quot;http://www.murrayc.com/blog/permalink/2012/06/22/rygel-for-a-dlna-player/&quot;&gt;Murray&amp;#8217;s &amp;#8220;Rygel for a DLNA Player&amp;#8221; proposal&lt;/a&gt;, I&amp;#8217;ve made some of the suggested changes listed there which are now in master. These two new libraries have been added&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;librygel-core: This has been a long-standing TODO item. It was necessary to allow in-process use of the DLNA and UPnP knowledge coded in Rygel, allowing the creation of librygel-renderer (see below). On top of this there are other benefits
&lt;ul&gt;
&lt;li&gt;It will allow a Rygel version running on Windows without ugly libtool hacks for the plug-ins.&lt;/li&gt;
&lt;li&gt;It simplifies the reuse of other parts of Rygel&amp;#8217;s code, such as the transcoding HTTP server, in programs like Korva.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;the new librygel-renderer: In essence this is the &lt;a href=&quot;https://live.gnome.org/Rygel/Plugins#Playbin&quot;&gt;playbin plugin&lt;/a&gt; with a bit of API on top that simplifies the code necessary to create a renderer. It offers either a playbin element you can use in your code or wraps around an existing playbin.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In future we can extend this family of libraries by &amp;#8220;librygel-browse&amp;#8221; for remote content access and &amp;#8220;librygel-control&amp;#8221; for remote control.&lt;/p&gt;
&lt;p&gt;To demonstrate librygel-renderer&amp;#8217;s capabilities of converting an arbitrary media player based on &lt;a href=&quot;http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-playbin2.html&quot;&gt;GStreamer&amp;#8217;s GstPlaybin2&lt;/a&gt; into a proper UPnP/DLNA renderer, I have added librygel-renderer support to Totem. You can see the result in the following demo:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The first part of the video (using Sintel) shows how changes in local file playback are being reflected on the UPnP side. In the second part, I set a remote video (Big Buck Bunny) and control totem solely via UPnP, where play, pause, stop, controlling volume, seeking and getting the current playback position is working quite well.&lt;/p&gt;
&lt;p&gt;This simple conversion is not a complete DLNA Player. It would need UPnP/DLNA server browsing capabilities for this, as stated in the proposal (In general. Totem can access these servers via its Grilo plug-in).&lt;/p&gt;
&lt;p&gt;Of course, with Totem being a complex, mature piece of software, some things don&amp;#8217;t work yet:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Volume changes in Totem aren&amp;#8217;t reflected via UPnP&lt;/li&gt;
&lt;li&gt;It is not possible to initiate a remote play-back until Totem has an item in its playlist&lt;/li&gt;
&lt;li&gt;The announced media format support is nowhere near what Totem actually supports&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Still, getting &lt;a href=&quot;https://github.com/phako/Totem/commit/28c91907f5b63a2b7c84592d86e4102af9bba853&quot;&gt;an UPnP/DLNA-compatible (and actually close to certifiable) renderer in three lines of code&lt;/a&gt; is impressive, don&amp;#8217;t you think?&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s one draw-back that I realized while implementing this. My initial idea to sit on top of a GStreamer playbin2 might be flawed for already existing and mature software such as Totem. There might be much more code-paths dealing with control that happen outside of a playbin. We have an alternative for that as well and that would be implementing one of Rygel&amp;#8217;s interfaces by the consuming party. The UPnP and DLNA compatibility that is already in the current code would need to be transferred to this, which is, of course, more work than just attaching to a playbin.&lt;/p&gt;
&lt;p&gt;Why should I prefer this above the already available &lt;a href=&quot;https://live.gnome.org/Rygel/Plugins#MPRIS&quot;&gt;MPRIS Rygel plug-in&lt;/a&gt;? There might be several reasons.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You don&amp;#8217;t want a whole separate Rygel process running just for adding UPnP renderer capabilities to your media player.&lt;/li&gt;
&lt;li&gt;You aim for some kind of UPnP or DLNA certification &amp;#8211; The additional layer of indirection can make that really hard while the presented approach is nearly ready.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So are we going to abandon Rygel&amp;#8217;s MPRIS renderer plugin now? No. Because we can&amp;#8217;t expect every media player in the world a) use GStreamer and b) want to link against Rygel. MPRIS gives us a quick, ready-made access to a vast amount of players out there and the compatibility it offers is (most of the time) just enough for casual home use.&lt;/p&gt;</description>
	<pubDate>Wed, 04 Jul 2012 10:33:32 +0000</pubDate>
</item>
<item>
	<title>Jens Georg: N9 PR1.3</title>
	<guid>http://jensge.org/?p=771</guid>
	<link>http://jensge.org/2012/07/n9-pr1-3/</link>
	<description>&lt;p&gt;You might have noticed, there&amp;#8217;s a new device update out; the changes relates to Rygel are rather small:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It fixes 100% CPU usage when encountered by DLNA clients that issue a massive amount of seek requests (&lt;a href=&quot;https://bugzilla.gnome.org/show_bug.cgi?id=662125&quot;&gt;GNOME Bug#662125&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Fixes the issue with XBox 360 that showed songs up to 5 times (&lt;a href=&quot;http://jensge.org/2012/07/n9-pr1-3/ https://bugzilla.gnome.org/show_bug.cgi?id=664184&quot;&gt;GNOME Bug#664184&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;A small memory leak when streaming transcoded audio&lt;/li&gt;
&lt;/ul&gt;</description>
	<pubDate>Wed, 04 Jul 2012 10:32:11 +0000</pubDate>
</item>
<item>
	<title>Jens Georg: Plants</title>
	<guid>http://jensge.org/?p=709</guid>
	<link>http://jensge.org/2012/06/plants/</link>
	<description>&lt;p&gt;Following up from&lt;a href=&quot;http://jensge.org/2012/06/plants/ http://jensge.org/2009/08/es-grunt-so-grun/&quot;&gt; ~ three years ago&lt;/a&gt;, here&amp;#8217;s how it looks like today&lt;a href=&quot;http://jensge.org/wp-content/uploads/2012/06/12060062.jpg&quot;&gt;&lt;img class=&quot;aligncenter size-medium wp-image-710&quot; title=&quot;12060062&quot; src=&quot;http://jensge.org/wp-content/uploads/2012/06/12060062-e1340530956653-168x300.jpg&quot; alt=&quot;&quot; width=&quot;168&quot; height=&quot;300&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description>
	<pubDate>Sun, 24 Jun 2012 09:43:16 +0000</pubDate>
</item>
<item>
	<title>Jan Arne Petersen: Text Input Method Support in Wayland</title>
	<guid>http://blog.jpetersen.org/?p=108</guid>
	<link>http://blog.jpetersen.org/2012/06/20/text-input-method-support-in-wayland/</link>
	<description>&lt;p&gt;Over the last years, we at &lt;a href=&quot;http://www.openismus.com/&quot;&gt;Openismus&lt;/a&gt; have worked on input methods for mobile devices (see for example &lt;a href=&quot;http://www.maliit.org/&quot;&gt;the Maliit input method framework&lt;/a&gt;). During that work we noticed that there are several problems caused by the toolkit-level interface between the input method system and the applications (beside having to implement interfaces for every toolkit, like &lt;a href=&quot;http://developer.gnome.org/gtk3/stable/GtkIMContext.html&quot;&gt;GtkIMContext&lt;/a&gt; and &lt;a href=&quot;http://qt-project.org/doc/qt-4.8/qinputcontext.html&quot;&gt;QInputContext&lt;/a&gt;). One of this problems is synchronizing events happening to the focus window and the virtual keyboard window. Therefore good platform integration of input methods such as virtual keyboards requires additional window management policies, as the window manager has to gain knowledge about input methods. The compositing window manager on Nokia&amp;#8217;s N9 serves as an example for the amount of required integration. It also taught us about what can go wrong and that Xorg induced latency is a hard problem to solve (see &lt;a href=&quot;http://blog.jpetersen.org/2012/01/25/compositing-in-maliit/&quot;&gt;Compositing in Maliit&lt;/a&gt;). There is also the &lt;a href=&quot;http://www.x.org/releases/X11R7.6/doc/libX11/specs/XIM/xim.html&quot;&gt;XIM&lt;/a&gt; X extension which integrated input methods on the X level, but its limitations and complexity puts it as a second choice compared to the toolkit interfaces mentioned above (especially since it does not manage to solve there problems).&lt;/p&gt;
&lt;p&gt;The move from Xorg to &lt;a href=&quot;http://wayland.freedesktop.org&quot;&gt;Wayland&lt;/a&gt; offers the possibility to move the input method system from the toolkit level down to the display server, as discussed in our &lt;a href=&quot;https://wiki.maliit.org/Wayland_Input_Method_System_Proposal&quot;&gt;Wayland Input Method System Proposal&lt;/a&gt;. Last week, Openismus let me work on a small &lt;a href=&quot;https://gitorious.org/openismus-playground/weston-text-protocol&quot;&gt;prototype technical demo&lt;/a&gt; for Weston (the Wayland reference compositor) which implements some of the ideas in that proposal. This should be useful for testing the idea of having the input method system integrated in Wayland.&lt;/p&gt;
&lt;h3&gt;New Wayland interfaces&lt;/h3&gt;
&lt;div id=&quot;attachment_112&quot; class=&quot;wp-caption alignleft&quot;&gt;&lt;a href=&quot;http://www.jpetersen.org/blog/wp-content/uploads/2012/06/3-process-solution-with-text-and-input-method-protocol.png&quot;&gt;&lt;img class=&quot;size-medium wp-image-112&quot; title=&quot;Standalone input method system with text and input method protocols&quot; src=&quot;http://www.jpetersen.org/blog/wp-content/uploads/2012/06/3-process-solution-with-text-and-input-method-protocol-300x197.png&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;197&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Standalone input method system with text and input method protocols&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;The prototype defines three interfaces. The first is the &lt;a href=&quot;https://gitorious.org/openismus-playground/weston-text-protocol/blobs/master/protocol/text.xml&quot;&gt;text_model&lt;/a&gt;, which is used to communicate from the application/toolkit side with the input method system. It provides the input method system with all required information about the active text, such as selection, surrounding text and cursor index. The application receives events over this interface, such as preedit and commit, from the input method system. For the prototype, I implemented an &lt;a href=&quot;https://gitorious.org/openismus-playground/weston-text-protocol/blobs/master/clients/editor.c&quot;&gt;example editor client&lt;/a&gt;, which uses the text model to send the surrounding text to the input method system and receives commit events.&lt;/p&gt;
&lt;p&gt;The second interface is the &lt;a href=&quot;https://gitorious.org/openismus-playground/weston-text-protocol/blobs/master/protocol/text.xml&quot;&gt;input_method interface&lt;/a&gt; which is used to communicate between the input method and Wayland. For the prototype we use a really simple &lt;a href=&quot;https://gitorious.org/openismus-playground/weston-text-protocol/blobs/master/clients/keyboard.c&quot;&gt;keyboard client &lt;/a&gt;which just sends commit events when pressing one of the keys.&lt;/p&gt;
&lt;p&gt;The third interface is used to register the keyboard surface as an input panel on the shell. I added the input_panel interface to the &lt;a href=&quot;https://gitorious.org/openismus-playground/weston-text-protocol/blobs/master/protocol/desktop-shell.xml&quot;&gt;desktop shell protocol&lt;/a&gt;. This allows the shell to stack the keyboard surface into the right layer (for the prototype I used the panel layer). Additionally, the prototype adds support to the shell to show the keyboard only when a text model is active.&lt;/p&gt;
&lt;h3&gt;Demos&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://jpetersen.org/videos/wayland-ims-prototype.mp4&quot;&gt;screen cast&lt;/a&gt;&lt;br /&gt;
The &lt;a href=&quot;http://jpetersen.org/videos/wayland-ims-prototype.mp4&quot;&gt;screen cast&lt;/a&gt; shows the prototype in action, but for those with a working &lt;a href=&quot;http://wayland.freedesktop.org/building.html&quot;&gt;Wayland installation&lt;/a&gt;, it should also be possible to just compile and run the &lt;a href=&quot;https://gitorious.org/openismus-playground/weston-text-protocol&quot;&gt;prototype&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Outlook&lt;/h3&gt;
&lt;p&gt;The prototype is the outcome of less than a week of coding, but it already uses some of the concepts we learned while working on Maliit. It should serve as a baseline for further Wayland input method system integration, even if many basic items are missing. For instance, there is no integration with hardware keyboard events, nor keyboard focus (which is handled by wl_seat in Wayland). Nevertheless I will polish my patches a bit and send them to the Wayland mailing list for integration into Weston, so that they can be used for more work on input methods in Wayland/Weston. My colleague Michael &lt;a href=&quot;http://akademy2012.kde.org/program/sessions/wayland-choosing-better-input-method-architecture&quot;&gt;will present this work&lt;/a&gt; at aKademy in two weeks, which will be a good opportunity to discuss the possibilities of such an input method system in Wayland.&lt;/p&gt;</description>
	<pubDate>Wed, 20 Jun 2012 15:31:26 +0000</pubDate>
</item>
<item>
	<title>Mathias Hasselmann: Performance and Memory Usage of Evolution Data Server</title>
	<guid>http://taschenorakel.de/mathias/2012/06/20/performance-and-memory-usage-of-evolution-data-server/</guid>
	<link>http://taschenorakel.de/mathias/2012/06/20/performance-and-memory-usage-of-evolution-data-server/</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://www.openismus.com/&quot;&gt;Openismus&lt;/a&gt; asked me to perform some benchmarks on &lt;a href=&quot;https://live.gnome.org/Evolution/EDS_Architecture&quot;&gt;Evolution Data Server&lt;/a&gt;. We wanted to track the progress of recent performance improvements and identify possible improvements. Therefore, I tested these versions of EDS:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://git.gnome.org/browse/evolution-data-server/tree/NEWS?id=EVOLUTION_DATA_SERVER_3_5_2&quot;&gt;EDS 3.5.2&lt;/a&gt; from June 4th 2012 - the latest development release.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://git.gnome.org/browse/evolution-data-server/tree/NEWS?id=EVOLUTION_DATA_SERVER_3_4_2&quot;&gt;EDS 3.4.2&lt;/a&gt; from May 14th 2012 - the latest stable release.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://git.gnome.org/browse/evolution-data-server/tree/NEWS?id=EVOLUTION_DATA_SERVER_3_2_3&quot;&gt;EDS 3.2.3&lt;/a&gt; from January 9th 2012 - shipped with &lt;a href=&quot;http://www.ubuntu.com/&quot;&gt;Ubuntu 12.04 LTS&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://git.gnome.org/browse/evolution-data-server/tree/NEWS?id=EVOLUTION_DATA_SERVER_2_32_3&quot;&gt;EDS 2.32.3&lt;/a&gt; from April 21th 2011, - the last stable release of the &lt;a href=&quot;http://www.gnome.org/&quot;&gt;GNOME 2&lt;/a&gt; series.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://maemo.gitorious.org/eds-fremantle/eds-fremantle&quot;&gt;Maemo Fremantle's EDS fork&lt;/a&gt; from June 23th 2010, which was carefully optimized for the &lt;a href=&quot;http://en.wikipedia.org/wiki/Nokia_N900&quot;&gt;Nokia N900&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The code is in a &lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks&quot;&gt;phonebooks-benchmarks repository on Gitorious&lt;/a&gt; with a full auotools build, and with a script to build and test all these versions of EDS. So you can try this too, and you can help to correct or improve the benchmarks. See below for details. &lt;/p&gt;
&lt;p&gt;EDS offers various APIs to access the address book. The traditional interface was &lt;a href=&quot;http://developer.gnome.org/libebook/stable/EBook.html&quot;&gt;EBook&lt;/a&gt;, which has served us well in &lt;a href=&quot;http://www.gnome.org/&quot;&gt;GNOME 2&lt;/a&gt; and &lt;a href=&quot;http://de.wikipedia.org/wiki/Maemo&quot;&gt;Maemo 5&lt;/a&gt;. However, some APIs such as batch saving are missing in the upstream version. Also its asynchronous API doesn't follow the conventions established later by &lt;a href=&quot;http://developer.gnome.org/gio/stable/&quot;&gt;GIO&lt;/a&gt;. To overcome these EBook shortcomings, and to make efficient use of &lt;a href=&quot;http://developer.gnome.org/gio/stable/gdbus-convenience.html&quot;&gt;GDBus&lt;/a&gt;, the &lt;a href=&quot;http://developer.gnome.org/libebook/stable/EBookClient.html&quot;&gt;EBookClient&lt;/a&gt; API was added in EDS 3.2. We can even use the backend &lt;a href=&quot;http://developer.gnome.org/libedata-book/stable/EDataBook.html&quot;&gt;EDataBook&lt;/a&gt; API, and that lets us measure the overhead imposed by using D-Bus.&lt;/p&gt;
&lt;p&gt;I tested the back-ends with different numbers of contacts. For each benchmark, and for each contact count, we create an entirely new private database. D-Bus communication was moved to a private D-Bus session. To avoid swapping, the maximum virtual memory size was limited to 2 GiB per ulimit command. This limit probably caused the crash of Maemo 5's EDS in the test with 12,800 contacts, but I have not checked that yet.&lt;/p&gt;
&lt;h2&gt;Contact Saving&lt;/h2&gt;
&lt;p&gt;These benchmarks simply store a list of parsed contacts in the address book. This simulates use cases such as the initial import of contacts upon migration or synchronization.&lt;/p&gt;
&lt;p&gt;To avoid possible side effects from lazy parsing, we retrieve the attribute list for each contact before starting the benchmark.  With &lt;a href=&quot;http://developer.gnome.org/libebook/stable/EBook.html&quot;&gt;EBook&lt;/a&gt; from &lt;a href=&quot;https://maemo.gitorious.org/eds-fremantle/eds-fremantle&quot;&gt;Maemo 5&lt;/a&gt; and &lt;a href=&quot;http://developer.gnome.org/libebook/stable/EBookClient.html&quot;&gt;EBookClient&lt;/a&gt; since EDS 3.4, contacts are saved in batches of 3,200 contacts. This partitioning was needed to deal with resource limitations in the file backend. All other EDS variants must save their contacts one by one.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Contact saving, without batching&quot; src=&quot;http://taschenorakel.de/files/eds-benchmarks/contact-saving-normal.png&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks/blobs/master/src/ebookbenchmark.cpp#line62&quot;&gt;EBook&lt;/a&gt;, &lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks/blobs/master/src/ebookclientbenchmark.cpp#line54&quot;&gt;EBookClient&lt;/a&gt;, &lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks/blobs/master/src/edatabookbenchmark.cpp#line88&quot;&gt;EDataBook&lt;/a&gt; implementation&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As expected, the effort for contact saving grows quickly when not using a batch API. This is because a new database transaction must be created and committed for each contact. Things look much better when using the batch saving API which was available in Maemo 5 already, and was recently added to EBookClient:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Contact saving in batches&quot; src=&quot;http://taschenorakel.de/files/eds-benchmarks/batch-saving-normal.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Batch saving performance of EDS 3.4+ is &lt;em&gt;just excellent&lt;/em&gt;: Although slowly growing with the number of contacts, it remains below a threshold of 3 ms per contact even for 12,800 contacts. That growing effort can be accounted to growing attribute indices. The initial peak (until 50 contacts for Maemo 5, and until 400 contacts for EDS 3.4+) can be accounted to database setup cost.&lt;/p&gt;
&lt;p&gt;In terms of performance there is no difference between using EBookClient or EDataBook (which avoids D-Bus).&lt;/p&gt;
&lt;h2&gt;Contact Fetching&lt;/h2&gt;
&lt;p&gt;A very basic, but essential, benchmark is fetching all contacts. To get a first impression I just fetched all contacts without any constraints.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Fetch all contacts&quot; src=&quot;http://taschenorakel.de/files/eds-benchmarks/fetch-all-contacts.png&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks/blobs/master/src/ebookbenchmark.cpp#line144&quot;&gt;EBook&lt;/a&gt;, &lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks/blobs/master/src/ebookclientbenchmark.cpp#line150&quot;&gt;EBookClient&lt;/a&gt;, &lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks/blobs/master/src/edatabookbenchmark.cpp#line181&quot;&gt;EDataBook&lt;/a&gt; implementation&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Contact fetching performance decreased significantly during the EDS 3 series and then got better again: Fetching all contacts with 3.4 takes about 133% of the time that EDS 2.32 needs and even 225% of Maemo 5's time. With EDS 3.5 contact loading time is improving again, making the EBook version of EDS 3.5 comparable in performance to EDS 2.32. Git archeology and quick testing identifies &lt;a href=&quot;https://bugzilla.gnome.org/show_bug.cgi?id=673527&quot;&gt;Christophe Dumez's bugfix&lt;/a&gt; as the relevant change. Apparently the file backend didn't make optimal use of 
Berkeley DB transactions.&lt;/p&gt;
&lt;p&gt;Still there is significant room for improvement, because:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;simple contact fetching with EBook 3.5 still takes 175% of the time Maemo 5 needs.&lt;/li&gt;
&lt;li&gt;EBookClient 3.5 is still 20% slower than EBook 3.5, and 64% slower than EDataBook.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This basic test shows already that the chosen client-server architecture of EDS causes a non-ignorable overhead.&lt;/p&gt;
&lt;p&gt;It would be absolutely worth investigating how Maemo 5 reaches its far superior performance: After all it even beats EDataBook. I remember having spent significant time on avoiding vCard parsing and string copying. I also remember having replaced the rather inefficient GList with GPtrArray at several places. Some of the ideas have been ported upstream during &lt;a href=&quot;http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements&quot;&gt;Openismus' work for Intel&lt;/a&gt;. Apparently there are more gems to recover.&lt;/p&gt;
&lt;h2&gt;Fetching by UID&lt;/h2&gt;
&lt;p&gt;Fetching contacts by UID simulates lazy loading of contact lists: Initially, we only fetch contact IDs. We only fetch the full contacts when the device becomes idle, or when contacts become visible on screen. This approach is needed because even the fastest implementation (Maemo 5) needs several seconds to fetch any contact list of realistical size on mobile hardware.
Another useful optimization we implemented on the Nokia N9 is fetching of partial contacts, that only contain relevant information, like for instance the person's name. EDS doesn't support this optimization.&lt;/p&gt;
&lt;p&gt;As a first test we fetch contacts one-by-one, without using any kind of batch API:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Fetch by UID without batches&quot; src=&quot;http://taschenorakel.de/files/eds-benchmarks/fetch-by-id-without-batches.png&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks/blobs/master/src/ebookbenchmark.cpp#line111&quot;&gt;EBook&lt;/a&gt;, &lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks/blobs/master/src/ebookclientbenchmark.cpp#line116&quot;&gt;EBookClient&lt;/a&gt;, &lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks/blobs/master/src/edatabookbenchmark.cpp#line138&quot;&gt;EDataBook&lt;/a&gt; implementation&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The good news is that this chart shows quite constant performance for each client.&lt;/p&gt;
&lt;p&gt;The bad news is that contact fetching is pretty slow: 3.9 ms per contact, as seen with EDS 3.5, translates roughly to 390 ms to fetch only 100 contacts on this hardware. Considering that typical mobile devices are roughly 10 times slower than my notebook, these numbers are disappointing. Especially if you consider that EDS 2.32 was about 4 times, and Maemo 5 even about 13 times faster. This are entirely different worlds. It should be investigated what causes this significant performance regression from EDS 2.32 to EDS 3.2+. One also should try to port the performance fixes of Maemo 5.&lt;/p&gt;
&lt;p&gt;The performance reachable under ideal circumstances is shown by the EDataBook client. This only needs about 50 µs (0.05 ms) to fetch one contact by its id. &lt;em&gt;Directly accessing the address book via EDataBook is about two orders of magnitude faster than the current EBookClient&lt;/em&gt;. That's the goal that EDS can, and should, aim for. Apparently a significant amount of time is spent on performing D-Bus communication, whereas the requested task can be performed by the backend within almost no time.&lt;/p&gt;
&lt;p&gt;However, this data was acquired by fetching the contacts one by one. We can surely do better by using a batch API. That should drastically reduce the overhead caused, for instance, by D-Bus. But neither EBook or EBookClient provide an API to fetch contacts by lists of contact IDs. The thing that comes closest is filtering the contacts by a disjunction of UID field tests:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(or (is &quot;id&quot; &quot;uid1&quot;) (is &quot;id&quot; &quot;id2&quot;) ...)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So I tried that. The results for such queries, using batches of UIDs, look like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Fetch by UID in huge batches&quot; src=&quot;http://taschenorakel.de/files/eds-benchmarks/fetch-by-id-in-huge-batches.png&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks/blobs/master/src/ebookbenchmark.cpp#line136&quot;&gt;EBook&lt;/a&gt;, &lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks/blobs/master/src/ebookclientbenchmark.cpp#line142&quot;&gt;EBookClient&lt;/a&gt;, &lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks/blobs/master/src/edatabookbenchmark.cpp#line173&quot;&gt;EDataBook&lt;/a&gt; implementation&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This chart speaks for itself. To remain responsive and appear fluid while scrolling, applications should render at 60 frames per second. To reach that framerate newly visible contacts must be fetched and rendered within less than 16 ms. EDS apparently cannot meet that performance goal even on desktop computers. Considering the huge performance differences between client-server access and direct access, as seen when fetching contacts one by one, it seems very worthwhile to add dedicated support for fetching multiple contacts by UID. The most obvious approach would be adding a batch API in the spirit of &lt;code&gt;e_book_client_add_contacts()&lt;/code&gt;. Another solution would be adding more fast paths to the query processing code.&lt;/p&gt;
&lt;h2&gt;Filtering&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;small&gt;&lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks/blobs/master/src/ebookbenchmark.cpp#line105&quot;&gt;EBook&lt;/a&gt;, &lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks/blobs/master/src/ebookclientbenchmark.cpp#line110&quot;&gt;EBookClient&lt;/a&gt;, &lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks/blobs/master/src/edatabookbenchmark.cpp#line132&quot;&gt;EDataBook&lt;/a&gt; implementation, the &lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks/blobs/master/src/edsbenchmark.cpp#line239&quot;&gt;queries used&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Contact filtering is relatively efficient when using fields such as last-name, for which indices are hit. Still, the D-Bus overhead is noticeable: EDataBook needs less than 60% of EBook's or EBookClient's time.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://taschenorakel.de/files/eds-benchmarks/filter-by-family-name.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The times to match long prefixes and suffixes look quite similar when hitting indices.&lt;/p&gt;
&lt;p&gt;The behavior of EBook for short name prefixes is a bit strange. The EBook API is now deprecated, but it could still be worthwhile to identify the issue causing this strange behavior, so that it can be avoided in the future:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://taschenorakel.de/files/eds-benchmarks/filter-by-short-family-name-prefix.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Interestingly, there seem to be no &lt;em&gt;functional&lt;/em&gt; database indices for email addresses or phone numbers in more recent versions of EDS:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;http://taschenorakel.de/files/eds-benchmarks/filter-by-email-address.png&quot; /&gt;
&lt;img alt=&quot;&quot; src=&quot;http://taschenorakel.de/files/eds-benchmarks/filter-by-long-phone-number-suffix.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The behavior of Maemo 5's EDS is a bit surprising, as I know that &lt;a href=&quot;http://www.robster.org.uk/blog/&quot;&gt;Rob&lt;/a&gt; spent significant amounts of time on adding Berkeley DB based indices to that EDS version.&lt;/p&gt;
&lt;p&gt;It might be worth optimizing index usage in EDS, because prefix and suffix searches are commonly used in mobile applications. Prefix searches need to be fast, for quick feedback during auto completion. Suffix searches need to be fast, for instance to provide instant caller identification.&lt;/p&gt;
&lt;h2&gt;Memory Usage&lt;/h2&gt;
&lt;p&gt;Memory is cheap those days. Still, especially on embedded devices, you should keep a close eye on the memory consumption of your software. Obviously, memory consumption grows with the number of contacts used:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Resident Set Size (RSS)&quot; src=&quot;http://taschenorakel.de/files/eds-benchmarks/memory-usage-rss.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It's nice to see how memory consumption has reduced from release to release. It's also good to see that EBookClient seems to use slightly less memory than EBook.&lt;/p&gt;
&lt;p&gt;You might miss the graphs for Maemo 5 and EDS 2.32. I had to drop them for this chart as they show &lt;a href=&quot;http://taschenorakel.de/files/eds-benchmarks/memory-usage-rss-leaking.png&quot;&gt;serious memory leaks&lt;/a&gt;, preventing any useful examination. Apparently the leak really is in those versions of EDS: The EBook benchmarks for EDS 3.2+ are using exactly the same code but don't show this bad behavior.&lt;/p&gt;
&lt;p&gt;Notice that I've accumulated the client's and the backend's memory consumption. This allows us to estimate the cost of EDS's client-server architecture. Apparently this architecture increases memory consumption by about 40% in these benchmarks.&lt;/p&gt;
&lt;p&gt;While the RSS usage gives us information about the efficiency and correctness of the code, it's also interesting to check the virtual memory size needed by the benchmarks. Please take the following numbers with a &lt;strong&gt;reasonable grain of salt&lt;/strong&gt;: I got these numbers by simply adding together the virtual memory size of the client and of the backend process, as reported by the processes' &lt;em&gt;status&lt;/em&gt; file. A proper measurement would process the &lt;em&gt;maps&lt;/em&gt; file to properly account for shared memory regions.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Virtual Memory Size (VMS)&quot; src=&quot;http://taschenorakel.de/files/eds-benchmarks/memory-usage-vms.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The first issue we notice is the massively increased memory usage of EBookClient 3.2. It's almost 40% more than the others. Fortunately, the issue seems to have been fixed already in EDS 3.4.&lt;/p&gt;
&lt;p&gt;At first glance, the very low virtual memory usage of the EDataBook benchmark is impressive. It seems to consume only 40% of the client-server based benchmarks. Still, there is a fairly high chance that this huge delta must be attributed to my poor measurement here: Assuming perfect code segment sharing there only remains a delta of about 20 MiB, which would be nothing but the RSS delta of EDataBook and EBookClient. It would be nice to investigate this in more detail.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;RSS usage per contact&quot; src=&quot;http://taschenorakel.de/files/eds-benchmarks/rss-per-contact.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This chart shows the memory per contact after the contact saving benchmark. The overall memory usage per contact has grown dramatically by almost 40% in EDS 3+. The most efficient approach is apparently to directly access EDataBook, which consumes only 55% of the RSS per contact, compared to the client-server approaches.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;RSS usage per contact, model only&quot; src=&quot;http://taschenorakel.de/files/eds-benchmarks/rss-per-contact-model.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This high memory usage per contact is a bit surprising since, after subtracting effects from library and database initialization, the memory usage per contact remained constant between EDS 2.32 and EDS 3.5. The parallel usage of both Berkeley DB and SQLite in the file backend might be to blame, but this is currently pure speculation from me.&lt;/p&gt;
&lt;p&gt;The temporary regression in EDS 3.2 was apparently fixed. The increased memory usage of EBookClient and EDataBook over EBook is because the EBookClient and EDataBook benchmarks, in a slightly unrealistic bias for performance, store both the EContact and the VCard string for each contact.&lt;/p&gt;
&lt;h2&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;The developers of Evolution Data Server have paid good attention to performance and have successfully implemented significant improvements. However, EDS releases regularly suffer performance regressions, and the performance of EDS still isn't good enough for usage in mobile devices. Fortunately the performance problems are solvable. Some fixes will be straightforward, such as adding more batch API (or fast paths) for query processing. Others will need careful performance monitoring: For instance when activating more database indices, to speed up queries, we must be careful not to slow down contact saving.&lt;/p&gt;
&lt;p&gt;A not so trivial improvement would be adding a direct access API for reading the local database. The speed and memory usage 
measurements show the value of such API: Direct access is significantly faster than via D-Bus in most usage cases, and it seems to significantly reduce memory usage.&lt;/p&gt;
&lt;p&gt;Another significant improvement should be finishing the file backend's transition to SQLite: Using two database backends in parallel significantly increases code complexity and has measurably bad impact on memory consumption.&lt;/p&gt;
&lt;h2&gt;Usage Instructions&lt;/h2&gt;
&lt;p&gt;The full source code of this project is in our &lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks&quot;&gt;phonebooks-benchmarks repository on Gitorious&lt;/a&gt;. You'll need a fairly recent C++ compiler because I also used this project to get more familiar with the new features of C++11. I've successfully tested g++ 4.6.3 and g++ 4.7.0. Clang 3.0 definitely won't work because of incomplete lambda support.&lt;/p&gt;
&lt;p&gt;Other than that, you'll need &lt;a href=&quot;http://www.boost.org/&quot;&gt;Boost 1.48&lt;/a&gt; to compile the benchmarks. The optional chart-drawing module uses &lt;a href=&quot;http://www.imagemagick.org/www/Magick++/&quot;&gt;ImageMagick++&lt;/a&gt; and
&lt;a href=&quot;http://mathgl.sourceforge.net/&quot;&gt;MathGL 2.0.2&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There is a simple script for building and installing the tested EDS versions. The configure script will give instructions.&lt;/p&gt;
&lt;p&gt;To finally run the benchmarks just call &lt;code&gt;src/phonebook-benchmarks&lt;/code&gt;, and to draw the charts run &lt;code&gt;src/phonebook-benchmarks-mkcharts&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;When doing your own tests that needs a non-trivial vCard generator take look at &lt;a href=&quot;https://gitorious.org/openismus-playground/phonebook-benchmarks/blobs/master/src/mkvcards.cpp&quot;&gt;&lt;code&gt;src/phonebook-benchmarks-mkvcards&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Outlook&lt;/h2&gt;
&lt;p&gt;It would be interesting to take a more detailed look at the virtual memory usage.&lt;/p&gt;
&lt;p&gt;Also it would be educational to compare these results with other address book implementations. The first candidates I have in mind are &lt;a href=&quot;https://gitorious.org/qtcontacts-tracker&quot;&gt;QtContacts on Tracker&lt;/a&gt; and &lt;a href=&quot;https://review.tizen.org/git/?p=api/contacts.git;a=tree&quot;&gt;Tizen's native contacts API&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We didn't cover &lt;a href=&quot;http://developer.gnome.org/libebook/stable/EBookView.html&quot;&gt;EBookView&lt;/a&gt; and &lt;a href=&quot;http://developer.gnome.org/libebook/stable/EBookClientView.html&quot;&gt;EBookClientView&lt;/a&gt; yet. These views take a query and notify the application when the contact set matching the query has changed. Typically, every user interface needs to use them.&lt;/p&gt;
&lt;p&gt;We also didn't talk about the calendar API yet.&lt;/p&gt;
&lt;p&gt;Well, and most importantly we at &lt;a href=&quot;http://www.openismus.com/&quot;&gt;Openismus&lt;/a&gt; would enjoy fixing the identified performance problems.&lt;/p&gt;</description>
	<pubDate>Wed, 20 Jun 2012 00:26:40 +0000</pubDate>
</item>
<item>
	<title>Michael Hasselmann: Concrete problems and generic solutions</title>
	<guid>http://mikhas.posterous.com/concrete-problems-and-generic-solutions</guid>
	<link>http://mikhas.posterous.com/concrete-problems-and-generic-solutions</link>
	<description>&lt;p&gt;
	&lt;p&gt;&lt;div class=&quot;p_embed p_image_embed&quot;&gt;
&lt;a href=&quot;http://getfile5.posterous.com/getfile/files.posterous.com/temp-2012-06-18/BotdzhaFDbJxBsnvJrzsexCrAJJpaobmiFDGlsdBEleajjfcdnhxIbHnmijq/maliit-gnome-vkb-comparison.png.scaled1000.png&quot;&gt;&lt;img alt=&quot;Maliit-gnome-vkb-comparison&quot; height=&quot;343&quot; src=&quot;http://getfile2.posterous.com/getfile/files.posterous.com/temp-2012-06-18/BotdzhaFDbJxBsnvJrzsexCrAJJpaobmiFDGlsdBEleajjfcdnhxIbHnmijq/maliit-gnome-vkb-comparison.png.scaled500.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;
For the Maliit Keyboard, we need the ability to style it for different form factors. As our focus is mostly on mobile devices (where the form factor is known), we got away with pixel-based styling that &amp;mdash; while being resolution dependent &amp;mdash; makes it easy to place and size the buttons in exactly the way needed. It&amp;rsquo;s what designers call pixel perfect, and the difference can be very noticable. Let&amp;rsquo;s take a look at the comparing screenshot, with the Gnome3 virtual keyboard on top (&lt;a href=&quot;http://library.gnome.org/misc/release-notes/3.2/&quot;&gt;taken from the 3.2 release notes&lt;/a&gt;) and the Gnome3-styled Maliit Keyboard at the bottom (&lt;a href=&quot;http://www.youtube.com/watch?v=akvQZwJYSbw&quot;&gt;video&lt;/a&gt;). The former uses a generic layout engine and generic styling, whereas the latter allows to style pixel-perfect layouts.&lt;/p&gt;
&lt;p&gt;For the official Gnome3 virtual keyboard, one can notice how the space bar is strangely sized, how the regular keys are unpleasantly square and how the enter and backspace keys are way too small. They all use the same graphical asset. For the Gnome3 styled Maliit Keyboad, the letters d-j, x-n, together with the space bar and its neighboring keys, form a neatly aligned center area, with a staircase pattern to each side of the keyboard. If you look in the last row, you will notice that the space bar is &lt;em&gt;just&lt;/em&gt; a few pixels too large. This happens because the only non-pixel-perfect elements in the Maliit Keyboard are stretched keys and spacer elements, and I somehow still compute their width incorrectly. From a designer perspective, that &amp;ldquo;pixel bug&amp;rdquo; in the layout destroys the immersion of an otherwise good design. Pixel perfectness &amp;mdash; whilst having a poor reputation among us developers perhaps &amp;mdash; is actually quite a challenge to get right!&lt;/p&gt;
&lt;p&gt;Maliit Keyboard is a reimplementation of the MeeGo Keyboard that was shipped on the Nokia N9. It doesn&amp;rsquo;t share any code with it, but it does reuse the ideas and the XML layout files. The format for the layout files evolved from programmer-friendly to designer-friendly over time, which I think was a good change. Instead of using the complex and pretty generic styling system of libmeegotouch (which was intended to fit the needs of any mobile application), I use a concrete style class that reads a styling profile folder, looks into into the two INI files (one for the main keyboard area, one for the extended keys) and fills a model with style attributes. In the given context of virtual keyboard styling, the concrete solution offers the same flexibility as the generic solution but comes with a fraction of the implementation complexity and remains simple to extend. This is because the concrete solution fits the intended use-case perfectly, whereas a generic solution will always acrue overhead.&lt;/p&gt;
&lt;p&gt;The trade-off, of course, is that for a new use-case, I&amp;rsquo;d probably have to write a new style class and create new style attributes. It is very unlikely, however, that the styling requirements of a fairly specific &amp;ldquo;application&amp;rdquo; would fit the the styling requirements of a regular application, so why burden myself with a generic enough abstraction that I will never use? Inversely, why try to make a generic solution fit a specialised problem? Jokingly, that&amp;rsquo;s precisely what I call Java programming: Instead of solving the problem at hand, write a framework that can solve all similar problems. I have started to grow a strong aversion against that, not because I like reinventing the wheel (I don&amp;rsquo;t), but because I think that understanding the concepts behind an idea is far more valuable than clinching to an implementation of it.&lt;/p&gt;
&lt;p&gt;For the Maliit Keyboard, I took the concepts of the libmeegotouch styling system and mixed my understanding of CSS with the XML layout files. The result feels pretty clean and easy to use, but that&amp;rsquo;s because I based the implementation on well-understood concepts, not because of the implementation itself. Who knows, if I keep myself busy with implementing virtual keyboards for just a bit longer, I should eventually be able to write a pretty decent book about VKB design patterns ;&amp;ndash;)&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://mikhas.posterous.com/concrete-problems-and-generic-solutions&quot;&gt;Permalink&lt;/a&gt; 

	| &lt;a href=&quot;http://mikhas.posterous.com/concrete-problems-and-generic-solutions#comment&quot;&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;</description>
	<pubDate>Tue, 19 Jun 2012 06:21:00 +0000</pubDate>
</item>
<item>
	<title>Krzesimir Nowak: SyncEvolution</title>
	<guid>tag:blogger.com,1999:blog-1677281587803116780.post-514294698009788433</guid>
	<link>http://krnowak.blogspot.com/2012/06/syncevolution.html</link>
	<description>These are bit dated news (well, only two weeks or so), but &lt;a href=&quot;http://lists.syncevolution.org/pipermail/syncevolution/2012-May/003722.html&quot;&gt;the fork/exec rewrite of DBus server was merged into master branch&lt;/a&gt;. The main aim of rewrite was to allow several concurrent synchronisations to be done (provided that the sync sessions don't conflict with each other). It wasn't possible before, because libsynthesis (the main library used for sync) does not have asynchronous API. There were two solutions: either use threads or spawn children processes doing syncs. The latter solution was chosen, because Patrick Ohly did not want threads to avoid complications with some possibly thread-unaware libraries. (Of course waiting for libsynthesis to get asynchronous API wasn't an option.)&lt;br /&gt;&lt;br /&gt;The rewrite involved splitting the code in one file of syncevo-dbus-server into several files and then detangling all tightly coupled  classes - I guess that &lt;a href=&quot;https://meego.gitorious.org/meego-middleware/syncevolution/trees/master/src/dbus/server&quot;&gt;the result&lt;/a&gt; is quite nice compared to &lt;a href=&quot;https://meego.gitorious.org/meego-middleware/syncevolution/blobs/d436e331d697bf6568b58a946e1e01daf4518a7d/src/syncevo-dbus-server.cpp&quot;&gt;what it used to be&lt;/a&gt;. In the meantime &lt;a href=&quot;https://meego.gitorious.org/meego-middleware/syncevolution/trees/master/src/gdbusxx&quot;&gt;new C++ DBus layer based on GLib GDBus&lt;/a&gt; was added. Most of this work was done by&amp;nbsp;&lt;a href=&quot;http://blixtra.org/&quot;&gt;Chris Kühl&lt;/a&gt; - I was mostly helping in fixing issues in new DBus layer and then working full-time on it and the code using it. As a final step I ported command line test from C++ to Python, so our work could be proved to work.&lt;br /&gt;&lt;br /&gt;This was a really long task,  very often I felt that I was losing grasp on the code I was working on and probably sometimes I had actually lost it. Now I feel happy to see it finally merged into master.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/1677281587803116780-514294698009788433?l=krnowak.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Wed, 06 Jun 2012 13:36:43 +0000</pubDate>
</item>
<item>
	<title>Jens Georg: Helium 0.5.0 available</title>
	<guid>http://jensge.org/?p=677</guid>
	<link>http://jensge.org/2012/06/helium-0-5-0-available/</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://helium_0.5.0_armel.deb&quot;&gt;&lt;img class=&quot;size-full wp-image-672 alignright&quot; title=&quot;helium_0.5.0_armel.deb&quot; src=&quot;http://jensge.org/wp-content/uploads/2012/04/helium_0.5.0_armel.deb_.png&quot; alt=&quot;&quot; width=&quot;111&quot; height=&quot;111&quot; /&gt;&lt;/a&gt;Helium 0.5.0 is available. It contains a lot of improvements and some new features such as&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Volume control on the player&lt;/li&gt;
&lt;li&gt;Possibility to play a media file on a different renderer than the currently selected&lt;/li&gt;
&lt;li&gt;Option to start the on-device media sharing&lt;/li&gt;
&lt;li&gt;Some more settings&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Get it &lt;a href=&quot;http://jensge.org/helium_0.5.0_armel.deb&quot;&gt;on this site&lt;/a&gt; or via &lt;a href=&quot;http://apps.formeego.com/staging/applications/n9/pr1.0/harmattan/Multimedia/helium/&quot; target=&quot;_blank&quot;&gt;apps.formeego.com&lt;/a&gt;. I&amp;#8217;ve also updated &lt;a href=&quot;http://jensge.org/helium-a-m-dmc-for-your-n9/&quot;&gt;the documentation &lt;/a&gt;to reflect the changes.&lt;/p&gt;</description>
	<pubDate>Mon, 04 Jun 2012 23:31:57 +0000</pubDate>
</item>
<item>
	<title>Michael Hasselmann: Get ready for Qt Contributor Summit!</title>
	<guid>http://mikhas.posterous.com/get-ready-for-qt-contributor-summit</guid>
	<link>http://mikhas.posterous.com/get-ready-for-qt-contributor-summit</link>
	<description>&lt;p&gt;
	&lt;p&gt;With only roughly over five weeks to go, &lt;a href=&quot;http://qt-project.org/groups/qt-contributors-summit-2012/wiki&quot;&gt;QtCS 2012&lt;/a&gt; is approaching fast on the event horizon (pun absolutely intended).
During the &lt;a href=&quot;http://mikhas.posterous.com/tizen-developer-conference-2012&quot;&gt;TiZen Developer Conference&lt;/a&gt;, Quim Gil and I, with help from Robin Burchell, found time to work on a draft, the &lt;a href=&quot;http://qt-project.org/groups/qt-contributors-summit-2012/wiki/Program&quot;&gt;result being visible&lt;/a&gt; in the QtDev wiki. Don&amp;rsquo;t be scared by the amount of pre-scheduled sessions, we will try to keep it as unconference-y as possible. However this allows us to properly prepare selected sessions.&lt;/p&gt;

&lt;p&gt;Please keep in mind that QtCS 2012 is &lt;a href=&quot;http://qt-project.org/groups/qt-contributors-summit-2012/wiki#0603623aed00ca2a39deacd463852a44&quot;&gt;invite-only&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Session presenters, prepare!&lt;/h2&gt;

&lt;p&gt;If you are a maintainer of a &lt;a href=&quot;http://qt-project.org/wiki/Qt-Essentials-Modules&quot;&gt;Qt Essentials module&lt;/a&gt;, then you will have to drive one of the pre-scheduled sessions.&lt;/p&gt;

&lt;p&gt;It might be a good idea to start writing a report about what happened in your area over the last couple of months, and where you plan to take your module for the Qt 5.1 release. Attendees of your session will probably expect you to talk about Qt 5 migration and how it will affect code using your module. On top of that, the most urgent bugs might get discussed, along with new feature requests, so please be prepared.&lt;/p&gt;

&lt;p&gt;If you find a topic that isn&amp;rsquo;t showing up in the program yet, consider to get in touch with other interested folks (the &lt;a href=&quot;http://lists.qt-project.org/mailman/listinfo/development&quot;&gt;Qt development mailing list&lt;/a&gt; or #qt IRC channel are good places to ask). With sufficient feedback, you should have everything it needs to drive the session yourself!&lt;/p&gt;

&lt;h2&gt;Plenary sessions&lt;/h2&gt;

&lt;p&gt;The first day will start with the State of the Union session about Qt 5 and Qt 5.1, summarizing where we are and where do we want to go with the Qt project.&lt;/p&gt;

&lt;p&gt;The second day is about betting on Qt Quick, covering topics such as theming, platform integration and cross-platform. We want to invite the maintainers and a few vendors/users/contributors to expose their thoughts and needs with the hope of bringing a common understanding.&lt;/p&gt;

&lt;p&gt;For the last day, we have a special surprise, as the topic will be HTML5 &amp;amp; the web. I am aware that this &lt;em&gt;will&lt;/em&gt; raise a lot of controversy among the community, but it is an area where we need to find answers. With all the latest interest in web technologies, the answer can no longer be &amp;ldquo;We don&amp;rsquo;t do web&amp;rdquo;. That&amp;rsquo;s what killed the dinosaurs, remember?  Then again, Qt already has better answers then that, so it&amp;rsquo;s about time for a fierce but honest panel discussion, including the Qt WebKit maintainers and other users/contributors driving this area.&lt;/p&gt;

&lt;h2&gt;Hack'n'Tell&lt;/h2&gt;

&lt;p&gt;Of course we also want to you to feel entertained during the summit, which is why we want to try out &lt;a href=&quot;http://www.meetup.com/berlin-hack-and-tell&quot;&gt;Hack'n'Tell&lt;/a&gt; sessions.&lt;/p&gt;

&lt;p&gt;The rules are simple: Show us a cool hack involving Qt. You got 5 minutes. No slides.&lt;/p&gt;

&lt;p&gt;I realize that preparing cool hacks takes some time, which is the original intent for this blog post: to announce the Call for Cute Hacks. For the first day at least, it would be great to have a couple of presenters before the summit starts. For the other days, I kind of hope that the summit itself will spark great ideas and demos that need to be shown immediately.&lt;/p&gt;

&lt;p&gt;I hope I got you excited a bit, so let&amp;rsquo;s make QtCS 2012 an event to remember!&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://mikhas.posterous.com/get-ready-for-qt-contributor-summit&quot;&gt;Permalink&lt;/a&gt; 

	| &lt;a href=&quot;http://mikhas.posterous.com/get-ready-for-qt-contributor-summit#comment&quot;&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;</description>
	<pubDate>Thu, 17 May 2012 09:02:00 +0000</pubDate>
</item>
<item>
	<title>Michael Hasselmann: Trip to California, May 2012</title>
	<guid>http://mikhas.posterous.com/trip-to-california-may-2012</guid>
	<link>http://mikhas.posterous.com/trip-to-california-may-2012</link>
	<description>&lt;p&gt;
	&lt;p&gt;In anticipation of two busy conferences in the San Francisco Bay Area, &lt;a href=&quot;http://mikhas.posterous.com/tizen-developer-conference-2012&quot;&gt;the TiZen Developer Conference 2012&lt;/a&gt; and the &lt;a href=&quot;http://uds.ubuntu.com/event/&quot;&gt;Ubuntu Developer Summit&lt;/a&gt;&lt;a href=&quot;http://uds.ubuntu.com/event/)&quot;&gt;&lt;/a&gt; for the &lt;a href=&quot;http://cdimage.ubuntu.com/daily-live/current/&quot;&gt;Quetzal release&lt;/a&gt;, I prepared myself by arriving one week earlier. This avoids the stress of a long distance flight immediately before conferences start, but also helps to adjust yourself to the environment (e.g., get used to public transport, find your ways around the area, get used to the food, etc.).&lt;div class=&quot;p_embed p_image_embed&quot;&gt;
&lt;a href=&quot;http://getfile6.posterous.com/getfile/files.posterous.com/temp-2012-05-16/jllFmquHliFcJpDejprFfwwBepHBAAajomqrreCnntbdbnoFiHacaGwzeItk/12050217.jpg.scaled1000.jpg&quot;&gt;&lt;img alt=&quot;12050217&quot; height=&quot;282&quot; src=&quot;http://getfile3.posterous.com/getfile/files.posterous.com/temp-2012-05-16/jllFmquHliFcJpDejprFfwwBepHBAAajomqrreCnntbdbnoFiHacaGwzeItk/12050217.jpg.scaled500.jpg&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://getfile0.posterous.com/getfile/files.posterous.com/temp-2012-05-16/EoHBaIvoHIchECueCHiHxuvrAIpADDenkyJmwdiantFkzdAclJdGlIvFbwph/12050215.jpg.scaled1000.jpg&quot;&gt;&lt;img alt=&quot;12050215&quot; height=&quot;282&quot; src=&quot;http://getfile8.posterous.com/getfile/files.posterous.com/temp-2012-05-16/EoHBaIvoHIchECueCHiHxuvrAIpADDenkyJmwdiantFkzdAclJdGlIvFbwph/12050215.jpg.scaled500.jpg&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://getfile9.posterous.com/getfile/files.posterous.com/temp-2012-05-16/sjyboEoIBAhjaHjxsEpmtHlcjacschrBoDwfJparafBAafxBxCnjItrfdcEG/12050048.jpg.scaled1000.jpg&quot;&gt;&lt;img alt=&quot;12050048&quot; height=&quot;282&quot; src=&quot;http://getfile7.posterous.com/getfile/files.posterous.com/temp-2012-05-16/sjyboEoIBAhjaHjxsEpmtHlcjacschrBoDwfJparafBAafxBxCnjItrfdcEG/12050048.jpg.scaled500.jpg&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://getfile3.posterous.com/getfile/files.posterous.com/temp-2012-05-16/DEAczirnHDxzpnlfhzyFliAbewoqegEBtGcwzEvlujDxqnizzyvzAzcDJmsp/12050045.jpg.scaled1000.jpg&quot;&gt;&lt;img alt=&quot;12050045&quot; height=&quot;282&quot; src=&quot;http://getfile5.posterous.com/getfile/files.posterous.com/temp-2012-05-16/DEAczirnHDxzpnlfhzyFliAbewoqegEBtGcwzEvlujDxqnizzyvzAzcDJmsp/12050045.jpg.scaled500.jpg&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://getfile6.posterous.com/getfile/files.posterous.com/temp-2012-05-16/AHzhJihiuhmfsDealvomCpGzGmcjBqrpIFhvvqbpupogcjIFtpxEGCFxbptq/12050027.jpg.scaled1000.jpg&quot;&gt;&lt;img alt=&quot;12050027&quot; height=&quot;282&quot; src=&quot;http://getfile1.posterous.com/getfile/files.posterous.com/temp-2012-05-16/AHzhJihiuhmfsDealvomCpGzGmcjBqrpIFhvvqbpupogcjIFtpxEGCFxbptq/12050027.jpg.scaled500.jpg&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://getfile9.posterous.com/getfile/files.posterous.com/temp-2012-05-16/thJonIfavqJgisyEraIIgJynnAavvamjAiHhAmgmkizocFaqyndxfCEruhHn/12050028.jpg.scaled1000.jpg&quot;&gt;&lt;img alt=&quot;12050028&quot; height=&quot;282&quot; src=&quot;http://getfile0.posterous.com/getfile/files.posterous.com/temp-2012-05-16/thJonIfavqJgisyEraIIgJynnAavvamjAiHhAmgmkizocFaqyndxfCEruhHn/12050028.jpg.scaled500.jpg&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://getfile7.posterous.com/getfile/files.posterous.com/temp-2012-05-16/tIefolrGFiIjzDJJIrhcpBbCxpfDfkrorjtuqGvoosDuewCGniiggvzHHJnz/12050025.jpg.scaled1000.jpg&quot;&gt;&lt;img alt=&quot;12050025&quot; height=&quot;282&quot; src=&quot;http://getfile1.posterous.com/getfile/files.posterous.com/temp-2012-05-16/tIefolrGFiIjzDJJIrhcpBbCxpfDfkrorjtuqGvoosDuewCGniiggvzHHJnz/12050025.jpg.scaled500.jpg&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://getfile4.posterous.com/getfile/files.posterous.com/temp-2012-05-16/FcoEehCsBssrvyHHopstgczCpjCBGJcorxkyDApupbyhqqBvwFAEfAhkBgaH/12050022.jpg.scaled1000.jpg&quot;&gt;&lt;img alt=&quot;12050022&quot; height=&quot;282&quot; src=&quot;http://getfile9.posterous.com/getfile/files.posterous.com/temp-2012-05-16/FcoEehCsBssrvyHHopstgczCpjCBGJcorxkyDApupbyhqqBvwFAEfAhkBgaH/12050022.jpg.scaled500.jpg&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://getfile9.posterous.com/getfile/files.posterous.com/temp-2012-05-16/msFIFvCscAjDFvDwrJGcafImlebwHfunttbkeIsriqplxxCIzIdHzHqibgGA/12050017.jpg.scaled1000.jpg&quot;&gt;&lt;img alt=&quot;12050017&quot; height=&quot;282&quot; src=&quot;http://getfile5.posterous.com/getfile/files.posterous.com/temp-2012-05-16/msFIFvCscAjDFvDwrJGcafImlebwHfunttbkeIsriqplxxCIzIdHzHqibgGA/12050017.jpg.scaled500.jpg&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://getfile0.posterous.com/getfile/files.posterous.com/temp-2012-05-16/BkGGszBIvkyxiByDuqarnJnwIJbmgrqkBefHqmrFIkogeEbGaFFpAmHqpkkf/12050015.jpg.scaled1000.jpg&quot;&gt;&lt;img alt=&quot;12050015&quot; height=&quot;282&quot; src=&quot;http://getfile3.posterous.com/getfile/files.posterous.com/temp-2012-05-16/BkGGszBIvkyxiByDuqarnJnwIJbmgrqkBefHqmrFIkogeEbGaFFpAmHqpkkf/12050015.jpg.scaled500.jpg&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://getfile6.posterous.com/getfile/files.posterous.com/temp-2012-05-16/JiokAuhhvlrBhxbCjyqafHqwdsDgmlAEnvmoFjBlahsxkisJHqciksxiwylt/12050011.jpg.scaled1000.jpg&quot;&gt;&lt;img alt=&quot;12050011&quot; height=&quot;282&quot; src=&quot;http://getfile0.posterous.com/getfile/files.posterous.com/temp-2012-05-16/JiokAuhhvlrBhxbCjyqafHqwdsDgmlAEnvmoFjBlahsxkisJHqciksxiwylt/12050011.jpg.scaled500.jpg&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://getfile1.posterous.com/getfile/files.posterous.com/temp-2012-05-16/uBxjwvqtuhephfwBfAnwaaniFnJlxoBkqxIgmpJgcrrDCFppkjFxdxHvqkst/12050009.jpg.scaled1000.jpg&quot;&gt;&lt;img alt=&quot;12050009&quot; height=&quot;282&quot; src=&quot;http://getfile6.posterous.com/getfile/files.posterous.com/temp-2012-05-16/uBxjwvqtuhephfwBfAnwaaniFnJlxoBkqxIgmpJgcrrDCFppkjFxdxHvqkst/12050009.jpg.scaled500.jpg&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://getfile4.posterous.com/getfile/files.posterous.com/temp-2012-05-16/EurlpeIalerskEIumsziiyIzhHonAxjfpAjFBylzbGHgujopJJyDIwepAFAz/12050007.jpg.scaled1000.jpg&quot;&gt;&lt;img alt=&quot;12050007&quot; height=&quot;282&quot; src=&quot;http://getfile1.posterous.com/getfile/files.posterous.com/temp-2012-05-16/EurlpeIalerskEIumsziiyIzhHonAxjfpAjFBylzbGHgujopJJyDIwepAFAz/12050007.jpg.scaled500.jpg&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://getfile1.posterous.com/getfile/files.posterous.com/temp-2012-05-16/flJqpbbikEgJCxwfjrJhqzqauztjBtJCItlhwFBriAHDuxAAeHnBmdFsiElA/12050006.jpg.scaled1000.jpg&quot;&gt;&lt;img alt=&quot;12050006&quot; height=&quot;282&quot; src=&quot;http://getfile7.posterous.com/getfile/files.posterous.com/temp-2012-05-16/flJqpbbikEgJCxwfjrJhqzqauztjBtJCItlhwFBriAHDuxAAeHnBmdFsiElA/12050006.jpg.scaled500.jpg&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://getfile5.posterous.com/getfile/files.posterous.com/temp-2012-05-16/JldkrdDugpzInAtgmIjGkCJEkgvBHfitzyGihyJdreFviuiaieltaeGHdsyD/12050004.jpg.scaled1000.jpg&quot;&gt;&lt;img alt=&quot;12050004&quot; height=&quot;282&quot; src=&quot;http://getfile3.posterous.com/getfile/files.posterous.com/temp-2012-05-16/JldkrdDugpzInAtgmIjGkCJEkgvBHfitzyGihyJdreFviuiaieltaeGHdsyD/12050004.jpg.scaled500.jpg&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://getfile2.posterous.com/getfile/files.posterous.com/temp-2012-05-16/cinciqisFwwDgngelzwrscrcsvCdpDhhfuxjooxyoGpGysbpvbteosxusDEr/12050003.jpg.scaled1000.jpg&quot;&gt;&lt;img alt=&quot;12050003&quot; height=&quot;282&quot; src=&quot;http://getfile9.posterous.com/getfile/files.posterous.com/temp-2012-05-16/cinciqisFwwDgngelzwrscrcsvCdpDhhfuxjooxyoGpGysbpvbteosxusDEr/12050003.jpg.scaled500.jpg&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://getfile8.posterous.com/getfile/files.posterous.com/temp-2012-05-16/iqhlIJJvczhgFoHijvuoDnuaAzHGElDgzEliEvyrEHpDkEIhiiAymiaJmbka/12040176.jpg.scaled1000.jpg&quot;&gt;&lt;img alt=&quot;12040176&quot; height=&quot;282&quot; src=&quot;http://getfile4.posterous.com/getfile/files.posterous.com/temp-2012-05-16/iqhlIJJvczhgFoHijvuoDnuaAzHGElDgzEliEvyrEHpDkEIhiiAymiaJmbka/12040176.jpg.scaled500.jpg&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://getfile1.posterous.com/getfile/files.posterous.com/temp-2012-05-16/DErrqAfqnwFefcaApdrJjbxhisBtzjeDHclgHIAzmqlmDjBbammtrluzfwwk/12040174.jpg.scaled1000.jpg&quot;&gt;&lt;img alt=&quot;12040174&quot; height=&quot;282&quot; src=&quot;http://getfile8.posterous.com/getfile/files.posterous.com/temp-2012-05-16/DErrqAfqnwFefcaApdrJjbxhisBtzjeDHclgHIAzmqlmDjBbammtrluzfwwk/12040174.jpg.scaled500.jpg&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;
&lt;div class=&quot;p_see_full_gallery&quot;&gt;&lt;a href=&quot;http://mikhas.posterous.com/trip-to-california-may-2012&quot;&gt;See the full gallery on Posterous&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;My flight to California was somewhat jinxed. Instead of getting a direct flight to SFO from an European airport, I had to change over in Miami. So instead of 12 flight hours, I was already up to 17 hours. Then the flight got delayed, and I of course missed the connection flight. Being rescheduled to the next flight meant another 5 hours of extra waiting time and arriving at SFO briefly before midnight. Which means no public transport for you. Luckily, I had informed &lt;a href=&quot;https://twitter.com/#!/quimgil&quot;&gt;Quim Gil&lt;/a&gt; about my additional delays (thanks to free WiFi at Miami airport), and being the good friend that he is, he decided to pick me up from SFO.&lt;/p&gt;
&lt;p&gt;On the next day (a warm Sunday), I had time to visit the &lt;a href=&quot;http://www.computerhistory.org/&quot;&gt;Computer History Museam&lt;/a&gt; in Mountain View. Later that evening, Quim, &lt;a href=&quot;https://twitter.com/#!/bergie&quot;&gt;Henri&lt;/a&gt; and I met for a few drinks, the outcome being this &lt;a href=&quot;http://talk.maemo.org/showthread.php?t=83984&quot;&gt;Maemo thread&lt;/a&gt;. Sadly, the thread itself has seemingly no positive outcome yet.&lt;/p&gt;
&lt;p&gt;On Monday, it was time to go to San Francisco, where I spent the next days (mostly) working and preparing my TiZen session for next week. It was great to experience San Francisco from a non-tourist point of view (though I still had to visit &lt;a href=&quot;http://www.johnnyrockets.com/&quot;&gt;Johnny Rockets&lt;/a&gt; together with &lt;a href=&quot;https://twitter.com/#!/mardy&quot;&gt;Alberto&lt;/a&gt;, &lt;a href=&quot;http://sil2100.vexillium.org/&quot;&gt;Łukasz&lt;/a&gt;, &lt;a href=&quot;http://www.flickr.com/photos/kitty-kat/&quot;&gt;Kat&lt;/a&gt; and &lt;a href=&quot;http://amigadave.com/&quot;&gt;Dave&lt;/a&gt;, the milkshakes really are that good). My highlight of the week was perhaps the lunch with the ever friendly &lt;a href=&quot;http://yorba.org&quot;&gt;Yorba guys&lt;/a&gt; on Friday. I saw their awesome new T-shirts, but sadly they&amp;rsquo;re for employees-only.&lt;/p&gt;
&lt;p&gt;On the weekend, I met with &lt;a href=&quot;https://plus.google.com/109286216957171423064/posts&quot;&gt;Lokesh&lt;/a&gt; and we drove down to Santa Cruz (great beach, lots of surfers, too) and from there to Monterey, on the famous &lt;a href=&quot;http://en.wikipedia.org/wiki/17-Mile_Drive&quot;&gt;17-Mile Drive&lt;/a&gt;. I even dared to (very briefly!) swim in the Pacific Ocean, another first for me. The Pacific made me pay my courage in blood though (nothing too bad, just an annoying cut at my heel).&lt;/p&gt;
&lt;p&gt;Then, well rested and all that, it was time for the conferences. Since there was only one keynote for Monday evening at the TiZen Developer Conference, I spent most of the day at UDS. The one thing to notice was probably that UDS had way more developers than TiZen, and to my surprise, even some high profile GNOME developers attended UDS. So much for all the silly fights about Ubuntu not being GNOME etc. I also met &lt;a href=&quot;http://danieldandrada.blogspot.de/&quot;&gt;Daniel d'Andrader&lt;/a&gt; again, which was nice.&lt;/p&gt;
&lt;p&gt;For the other two days, it was always a bit of back-and-forth between UDS and TiZen. UDS had the better food (breakfast, hm!), but TiZen probably had the better parties (California Academy of Science comes to mind). On Thursday I started to feel exhausted and on Friday, I was glad UDS was to be over soon. The beach party (without a beach) &lt;a href=&quot;http://www.quickmeme.com/meme/3pauml/&quot;&gt;totally killed it&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The flight back was uneventful. After two weeks in California, with the second one being extremely stressful, I was glad to finally land in Berlin again.&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://mikhas.posterous.com/trip-to-california-may-2012&quot;&gt;Permalink&lt;/a&gt; 

	| &lt;a href=&quot;http://mikhas.posterous.com/trip-to-california-may-2012#comment&quot;&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;</description>
	<pubDate>Wed, 16 May 2012 11:51:00 +0000</pubDate>
</item>
<item>
	<title>Michael Hasselmann: TiZen Developer Conference 2012</title>
	<guid>http://mikhas.posterous.com/tizen-developer-conference-2012</guid>
	<link>http://mikhas.posterous.com/tizen-developer-conference-2012</link>
	<description>&lt;p&gt;
	&lt;p&gt;&lt;a href=&quot;http://getfile9.posterous.com/getfile/files.posterous.com/temp-2012-05-16/kDqecnqwAbBGpwcHlEqCgqEICwHElunmhlhxyyHFAzqCipmlvwueucGthDlc/tdc2012.jpg&quot;&gt;&lt;img src=&quot;http://getfile9.posterous.com/getfile/files.posterous.com/temp-2012-05-16/kDqecnqwAbBGpwcHlEqCgqEICwHElunmhlhxyyHFAzqCipmlvwueucGthDlc/tdc2012.jpg.thumb100.jpg?content_part=ffCnHlgeAbajmadiHgwi&quot; align=&quot;left&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;The first day started slowly, with only one keynote in the evening. I wasn&amp;rsquo;t very happy with it, a proper keynote would have focused more on the visions and goals of TiZen, not so much on Linux or Android, or Microsoft.&lt;/p&gt;
&lt;p&gt;On the second day, my mind was mostly occupied with my own session, &amp;ldquo;Challenges of mobile text input&amp;rdquo;, &lt;a href=&quot;https://www.tizen.org/conference/tizen-developer-conference/schedule&quot;&gt;in the afternoon&lt;/a&gt;. It was good that speakers were informed early enough about the whole process, and the presentation templates were available long enough before the event. Even with the cold color scheme, I kind of like the clean TiZen design in the templates (though I still can&amp;rsquo;t get used to the name &amp;ldquo;Ti-Zen&amp;rdquo;).&lt;/p&gt;
&lt;p&gt;Two hours or so before my session, I had one technician help me upload my slides to the room&amp;rsquo;s PC. It&amp;rsquo;s great to not have to use your own laptop. Instead of worrying until the last minute whether everything will work, you know it just will, and if it doesn&amp;rsquo;t, it is not your task to fix it. Not having this typical presenter&amp;rsquo;s crisis helps to focus on the content of your session and also helps to stay calm.&lt;/p&gt;
&lt;p&gt;I was quite happy with my presentation, even though I was hoping for more input method developers in the audience. You can find the &lt;a href=&quot;https://wiki.maliit.org/images/6/6d/Challenges-of-mobile-text-input.pdf&quot;&gt;slides on the Maliit wiki&lt;/a&gt;, video (or at least audio) should be available at some later point, too.&lt;/p&gt;
&lt;p&gt;On the last day, every attendee could get a TiZen developer device. I was surprised it didn&amp;rsquo;t have &amp;ldquo;Intel Inside&amp;rdquo;, but the ARM Cortex9 with the Mali GPU is interesting hardware nevertheless. Perhaps not too surprising for a HTML5 platform, it also comes with a speedy and actually useful mobile browser from the start. Even if it is uncertain at this point whether TiZen will end being a success, I am looking forward to see actual TiZen consumer devices.&lt;/p&gt;
&lt;p&gt;Thanks to the &lt;a href=&quot;http://www.linuxfoundation.org/&quot;&gt;Linux Foundation&lt;/a&gt; for sponsoring me, and thanks to Brian Warner again for helping with the organising bits.&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://mikhas.posterous.com/tizen-developer-conference-2012&quot;&gt;Permalink&lt;/a&gt; 

	| &lt;a href=&quot;http://mikhas.posterous.com/tizen-developer-conference-2012#comment&quot;&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;</description>
	<pubDate>Wed, 16 May 2012 07:43:00 +0000</pubDate>
</item>
<item>
	<title>Michael Hasselmann: Multi word ribbon UI for Maliit (video)</title>
	<guid>http://mikhas.posterous.com/multi-word-ribbon-ui-for-maliit</guid>
	<link>http://mikhas.posterous.com/multi-word-ribbon-ui-for-maliit</link>
	<description>&lt;p&gt;
	&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Motivated by the new &lt;a href=&quot;http://www.youtube.com/watch?v=JEPYYo0-gfc&amp;t=0h0m21s&quot;&gt;Blackberry 10 &lt;em&gt;virtual&lt;/em&gt; keyboard&lt;/a&gt;, I decided to spent a couple of hours on a proof of concept, &lt;a href=&quot;http://www.youtube.com/watch?v=UZHbtN4UU0E&quot;&gt;this video being the result&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I had to hack the Presage engine a bit to provide word prediction in a similar fashion to what you see in the 2-3 seconds of the Blackberry video. Then I added some space between the rows of the keyboard, so that I could place additional word ribbons there. The word candidates appear next to their starting letters, though it&amp;rsquo;s only one candidate per letter. I need to find a better solution here, but then again Blackberry guys also haven&amp;rsquo;t solved it either ;&amp;ndash;) Tapping on the word candidates inserts then into the text editor (no gestures, for now).&lt;/p&gt;
&lt;p&gt;The code is very hackish, certainly nothing I would publish. I am going to put it onto a tablet so that I can show it around to you guys at the &lt;a href=&quot;http://mikhas.posterous.com/the-challenges-of-mobile-text-input&quot;&gt;TiZen Developer Conference&lt;/a&gt; or the &lt;a href=&quot;http://uds.ubuntu.com/&quot;&gt;Ubuntu Developer Summit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Jon is going to bring a camcorder on Sunday, so perhaps we can actually record a real, &lt;a href=&quot;http://www.youtube.com/user/maliitorg/videos&quot;&gt;youtube-worthy&lt;/a&gt; video then.&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://mikhas.posterous.com/multi-word-ribbon-ui-for-maliit&quot;&gt;Permalink&lt;/a&gt; 

	| &lt;a href=&quot;http://mikhas.posterous.com/multi-word-ribbon-ui-for-maliit#comment&quot;&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;</description>
	<pubDate>Thu, 03 May 2012 22:58:00 +0000</pubDate>
</item>
<item>
	<title>Michael Hasselmann: The challenges of mobile text input</title>
	<guid>http://mikhas.posterous.com/the-challenges-of-mobile-text-input</guid>
	<link>http://mikhas.posterous.com/the-challenges-of-mobile-text-input</link>
	<description>&lt;p&gt;
	&lt;p&gt;I am going to speak about mobile text input at the &lt;a href=&quot;https://www.tizen.org/community/events/2012/tizen-developer-conference&quot;&gt;TiZen Developer Conference&lt;/a&gt; (7-9 May, San Francisco, CA). My session is scheduled for &lt;a href=&quot;http://www.tizen.org/sites/default/files/pages/tdc2012_schedule_final.pdf&quot;&gt;Tuesday afternoon (PDF)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I had planned to only focus on the technical aspects, but I am also going to talk about other aspects, such as the &lt;a href=&quot;http://www.google.com/search?q=blackberry+10+virtual+keyboard&amp;ie=utf-8&amp;oe=utf-8&amp;channel=fs#q=blackberry+10+virtual+keyboard&amp;hl=en&quot;&gt;media coverage&lt;/a&gt; a cleverly designed text input method can achieve, and which features are apparently important to consumers.&lt;/p&gt;

&lt;p&gt;The most important feature is, unsurprisingly perhaps, the overall performance: How fast can consumers insert or manipulate text on their mobile devices &amp;mdash; &lt;a href=&quot;http://www.damnyouautocorrect.com/category/best-of-dyac/&quot;&gt;while still being accurate&lt;/a&gt;? I will explain techniques that can help to improve responsiveness, accuracy and speed of a virtual keyboard.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ll be in the bay area until end of next week and I am generally interested to discuss the finer details of (text) input methods, accessibility or &lt;a href=&quot;http://wayland.freedesktop.org/&quot;&gt;display servers&lt;/a&gt; and how one could improve the situation for accessibility on Linux. &lt;a href=&quot;https://twitter.com/#!/mikhas4711&quot;&gt;Contact me on Twitter&lt;/a&gt; in case you want to meet up and go somewhere for dinner (or drinks) in the beautiful city of San Francisco!&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://mikhas.posterous.com/the-challenges-of-mobile-text-input&quot;&gt;Permalink&lt;/a&gt; 

	| &lt;a href=&quot;http://mikhas.posterous.com/the-challenges-of-mobile-text-input#comment&quot;&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;</description>
	<pubDate>Thu, 03 May 2012 18:01:00 +0000</pubDate>
</item>
<item>
	<title>Jens Georg: Rygel on Ubuntu 12.04 service announcement</title>
	<guid>http://jensge.org/?p=662</guid>
	<link>http://jensge.org/2012/04/rygel-on-ubuntu-12-04-service-announcement/</link>
	<description>&lt;p&gt;If you just upgraded to Ubuntu 12.04 and your PS3 or Sony TV stopped showing videos, the work-around is to uninstall gstreamer0.10-plugins-bad-multiverse. See &lt;a title=&quot;NEEDINFO - Transcoding to MPEG broken on Ubuntu 12.04&quot; href=&quot;https://bugzilla.gnome.org/show_bug.cgi?id=672439&quot;&gt;bug 672439&lt;/a&gt; for the details.&lt;/p&gt;
&lt;p&gt;The bright side is that for the first time ever, we have a recent Ubuntu shipping the latest version of Rygel.&lt;/p&gt;</description>
	<pubDate>Thu, 26 Apr 2012 19:24:44 +0000</pubDate>
</item>
<item>
	<title>Mathias Hasselmann: Using Full Text Search Engines as Datastore</title>
	<guid>http://taschenorakel.de/mathias/2012/04/25/fulltext-search-datastore/</guid>
	<link>http://taschenorakel.de/mathias/2012/04/25/fulltext-search-datastore/</link>
	<description>&lt;p&gt;It's a common design to use full text search engines only for free text
searches, but to store the actual structured data in a separate database.
Such designs come at a cost. Therefore &lt;a href=&quot;http://openismus.com/&quot;&gt;Openismus&lt;/a&gt; asked me to build
upon my previous post, where &lt;a href=&quot;http://taschenorakel.de/mathias/2012/04/18/fulltext-search-benchmarks&quot;&gt;I analyzed several FTS engines&lt;/a&gt;.
This time I'll research if we could use the full text search index itself as
our primary data store.&lt;/p&gt;
&lt;h3&gt;Relations&lt;/h3&gt;
&lt;p&gt;A first obvious limitation is the lack of joins. So to use the FTS index as
data store, you must &lt;a href=&quot;http://en.wikipedia.org/wiki/Database_normalization&quot;&gt;denormalize your data&lt;/a&gt;. That is, instead
of storing your movie database in distinct entity tables like &lt;code&gt;Movie&lt;/code&gt; and
&lt;code&gt;Artist&lt;/code&gt;, linked by relationship tables like &lt;code&gt;isLeadActor&lt;/code&gt; or &lt;code&gt;isDirector&lt;/code&gt;,
you must find a way to put everything into one single flat table. This isn't
entirely nice in terms of redundancy and consistency. On the other hand joining
tables is what makes relational databases slow and hinders distributing them
across servers. Is there someone whispering &quot;NoSQL&quot;? Well. Yes, while I
absolutely dislike their striking marketing: They are on to something, and
with our journey today we enter their land.&lt;/p&gt;
&lt;p&gt;Seems I've lost myself in chatting, so back on topic. So to store data in a
FTS index we must denormalize our data. Luckily they make it easier than it
sounds.  In opposition to the relational model, there is no need to create
complex relationships, just to assign more than only one actor or director to a
movie: When adding artists to your movie you just tag each name with the proper
field prefix before adding it to the index, and you are done. &lt;em&gt;FTS engines
natively support multi-value fields!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;With some additional effort it also should be possible to store more structured
data in those multi-value fields, things like &lt;code&gt;(release-date, country)&lt;/code&gt;, or
&lt;code&gt;(actor, role)&lt;/code&gt;: You'd add more prefixes and use the positional information
stored for phrase searches to reliably identify those fields. Sadly my time is
too limited to research this more in detail, but the Internet surely has
documents about this. Well, or for additional fun you can try to figure it out
yourself.&lt;/p&gt;
&lt;h3&gt;Exact Matches&lt;/h3&gt;
&lt;del&gt;
Now a match reported by an FTS engine only tells us that the document or the
chosen field contains the phrase we were looking for. When searching for
`title:&quot;The Matrix&quot;` any FTS engine will not only return the first movie of
the Wachowskis' triology, it also will give matches for the other two movies,
and works like *&quot;Making 'The Matrix'&quot;*. So for doing exact lookups we'll have
to filter the initial result, and drop any document that doesn't exactly match
our requirements.

Sadly we really must check the field value instead of just checking the
computed score: For instance with Lucene both *&quot;The Matrix&quot;* and *&quot;Making
'The Matrix'&quot;* will get a score of 100%, since both documents fully satisfy all
terms of the query. Also we cannot use the score as indicator to only check
fields for documents that got at least 100%: When searching for
`director:&quot;Quentin Tarantino&quot;` the movie *&quot;Inglourious Basterds&quot;* will get
less than 100%, since Tarantino was working with Eli Roth for this movie.

So this additional filtering sounds expensive at the first moment, but remember
that our index lookup dramatically reduced the data set already. When looking
for `title:&quot;The Matrix&quot;` in the *imdb-50* data set, we talk about checking 9
documents instead of 121,587 documents for example. For useful data sets we
won't notice the overhead, like the test results below are showing.
&lt;/del&gt;

&lt;p&gt;You can just add unanalyzed fields and use term queries on them like kamstrup
pointed out.&lt;/p&gt;
&lt;h3&gt;Data Types&lt;/h3&gt;
&lt;p&gt;So we've learned that lack of relations isn't much of a problem for many
useful datasets, but structured data is not only about relationships, it also
is about data types. Full &lt;strong&gt;Text&lt;/strong&gt; Search engines only support lexicographical
order, so they surely fail for dates and numbers. You surely cannot use them
to find documents within a given range!&lt;/p&gt;
&lt;p&gt;I am sorry to disappoint you. The people researching FTS are smarter than that.
Actually properly sorting and ranging dates, while only using lexicographic
order is trivial. Most probably you have done it yourself already. Simply store
your dates in ISO format, that is &lt;code&gt;YYYY-MM-DDThh:mm:ss.SSSNNN&lt;/code&gt; or any prefix of
this, and you are done. Omit the separators if you prefer. ISO-8601 explicitly
is designed for lexicographic sorting.&lt;/p&gt;
&lt;p&gt;So how do you do this with numbers? You could prefix them, for instance with
zeros, to get a fixed width. This works reasonably if you know your number
ranges, and in most cases you do. Sometimes you know the range from your
application's context, e.g. the &lt;a href=&quot;http://www.youtube.com/watch?v=F1i40rnpOsA&quot;&gt;first known celluloid film&lt;/a&gt; was
recorded in 1888. More easily you just use your technical limits, like
&lt;em&gt;[-2&lt;sup&gt;63&lt;/sup&gt;..2&lt;sup&gt;63&lt;/sup&gt;-1]&lt;/em&gt; for long integers. While first
experiments really followed that approach, padding numbers with up to 18 zeros
isn't exactly efficient or pretty. Also we didn't talk about floating point
numbers yet. Therefore FTS engines like Lucene or Xapian provide more efficient
mechanisms for turning numbers into sortable strings. First they write a prefix
indicating number precision (64 bit, 32 bit, 10 bit, ...). Then they convert
the numbers to some unsigned format, and apply some kind of base-128 encoding
to the resulting bytes. The most significant bit gets stored first. For
floating point numbers they shuffle some bits of the number's IEEE-754
representation. The resulting, sortable 64 bit integer then is encoded like any
other number. You can consult &lt;a href=&quot;http://lucene.apache.org/core/3_6_0/api/core/org/apache/lucene/util/NumericUtils.html&quot;&gt;Lucene's documentation&lt;/a&gt;,
and the source code of &lt;a href=&quot;https://github.com/luceneplusplus/LucenePlusPlus/blob/master/src/core/util/NumericUtils.cpp&quot;&gt;Lucene::NumericUtils&lt;/a&gt;, or
&lt;a href=&quot;http://xapian.org/docs/sourcedoc/html/sortable-serialise_8cc_source.html&quot;&gt;Xapian::sortable_serialise&lt;/a&gt; for details.&lt;/p&gt;
&lt;h3&gt;Benchmarks&lt;/h3&gt;
&lt;p&gt;Hope I didn't lose you with all this theory, now it is &lt;em&gt;benchmark time&lt;/em&gt;!&lt;/p&gt;
&lt;p&gt;To test how useful FTS engines are for storing arbitrary data I've extended my
&lt;a href=&quot;http://taschenorakel.de/mathias/2012/04/18/fulltext-search-benchmarks&quot;&gt;previous benchmark&lt;/a&gt; to better support range searches, and to
support exact matching of fields. I've also added &lt;a href=&quot;http://mhr3.blogspot.de/2012/04/fts-engines-memory-usage.html&quot;&gt;Michal Hruby's
patch&lt;/a&gt; for supporting prefix searches. Since the prefix search
gives countless hits, the query results consistently are limited to 10.000 rows
now. I've dropped QtCLucene for now since it doesn't seem to support numeric
range searches and such. It was forked from Java Lucene a long time ago. For
SQLite I ran two sets of tests: &lt;em&gt;bm_sqlite&lt;/em&gt; doesn't create indices for fields
like movie title or artist names. Since such setup is unfair when comparing
with FTS engines, the second set &lt;em&gt;bm_sqlite_index&lt;/em&gt; creates indices for all
fields we perform lookups for. For tracker we again test the Nepomok media
ontology (&lt;em&gt;bm_tracker&lt;/em&gt;) and a optimized ontology (&lt;em&gt;bm_tracker_flat&lt;/em&gt;), that
attaches all properties to the same RDF class. I had to disable prefix searches
for &lt;em&gt;bm_tracker&lt;/em&gt;: The query ran for more than 2 hours on the dataset with 17k
movies. I seriously wish I'd get sponsored to improve Tracker's data model!&lt;/p&gt;
&lt;p&gt;Source code still is in the fts-benchmark repository, tagged as
&lt;a href=&quot;http://gitorious.org/openismus-playground/fts-benchmark/trees/releases/0.3&quot;&gt;&lt;code&gt;release/0.3&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Results and Discussion&lt;/h3&gt;
&lt;p&gt;Each query got run 7 times on 5 different data sets. This time I didn't take
the mean of the query execution times. The individual results of each dataset
are grouped together and labeled with &lt;code&gt;qxx_t1&lt;/code&gt; to &lt;code&gt;qxx_t7&lt;/code&gt;. Data and result
sets grow with each group.&lt;/p&gt;
&lt;p&gt;Also be careful when reading the charts as time is scaled logarithmically.
You might want to consult the raw data tables below for details. Please keep in
mind that the basic goal of this benchmarks is to test scalability, not raw
performance. Therefore I don't mind much if an engine is 10 times slower than
another for small data sets. Constant performance is the ideal result.&lt;/p&gt;
&lt;p&gt;You'll also notice that some charts have gaps for &lt;em&gt;bm_tracker&lt;/em&gt;. Like explained
above I had to skip &lt;em&gt;bm_tracker&lt;/em&gt; for few data sets, as tracker took way to long
to perform those benchmarks.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;rating:[90 TO 99]&quot; src=&quot;http://taschenorakel.de/files/fts-benchmark/ftsds1.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Lucene++ appears significantly slower than its competition for small data sets,
but then gives comparable results for data sets with more than 3,000 movies.
Still I would not overrate this finding: We are talking about lookup times in
the range of 10 ms. That's still pretty fast and close to measurement limits
like the spikes in the other engine's results show.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;release:[1999/01/01 TO 1999/09/30]&quot; src=&quot;http://taschenorakel.de/files/fts-benchmark/ftsds2.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This results are similar to the &lt;code&gt;rating:[90 TO 99]&lt;/code&gt; query.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;release=1999/03/31&quot; src=&quot;http://taschenorakel.de/files/fts-benchmark/ftsds3.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;For this query you see the importance of having an index for your lookup keys:
Performance of &lt;em&gt;bm_lucene++&lt;/em&gt; and &lt;em&gt;bm_sqlite_index&lt;/em&gt; remains almost constant,
while effort of the other engines grows dramatically as the data size grows.&lt;/p&gt;
&lt;p&gt;Xapian's bad performance comes as a surprise, but actually I am to blame here:
For stupid reasons I've implemented this very search as range search in
Lucene++ and Xapian (&lt;code&gt;release:[1999/03/31 TO 1999/03/31]&lt;/code&gt;). As the results
indicate Lucene++ seems to putting more effort into optimizing range searches,
and compensates my mistake.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;title=The Matrix&quot; src=&quot;http://taschenorakel.de/files/fts-benchmark/ftsds4.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Similar results as for &lt;code&gt;release=1999/03/31&lt;/code&gt;, only that Xapian behaves as
expected now. When given a proper query it also shows constant lookup time for
exact phrase searches.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;director=Quentin Tarantino&quot; src=&quot;http://taschenorakel.de/files/fts-benchmark/ftsds5.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;With this query you see the advantage you get from using denormalized tables:
Lucene++ and Xapian just are as efficient as in the previous tests, but as a
not so big surprise Tracker with the flat ontology now beats all remaining
engines, including &lt;em&gt;bm_sqlite_index&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;T*&quot; src=&quot;http://taschenorakel.de/files/fts-benchmark/ftsds6.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Performance of the different engines is similar to each other when performing
prefix searches.&lt;/p&gt;
&lt;h3&gt;Raw Result Data&lt;/h3&gt;
&lt;table class=&quot;results&quot;&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;rating:[90 TO 99] - 9 movies, 3 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;12.333 ms&lt;/td&gt;&lt;td&gt;10.409 ms&lt;/td&gt;&lt;td&gt;9.885 ms&lt;/td&gt;&lt;td&gt;9.821 ms&lt;/td&gt;&lt;td&gt;10.221 ms&lt;/td&gt;&lt;td&gt;9.840 ms&lt;/td&gt;&lt;td&gt;9.986 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;0.196 ms&lt;/td&gt;&lt;td&gt;0.169 ms&lt;/td&gt;&lt;td&gt;0.169 ms&lt;/td&gt;&lt;td&gt;0.173 ms&lt;/td&gt;&lt;td&gt;0.166 ms&lt;/td&gt;&lt;td&gt;0.167 ms&lt;/td&gt;&lt;td&gt;0.167 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;0.207 ms&lt;/td&gt;&lt;td&gt;0.183 ms&lt;/td&gt;&lt;td&gt;0.172 ms&lt;/td&gt;&lt;td&gt;0.192 ms&lt;/td&gt;&lt;td&gt;0.193 ms&lt;/td&gt;&lt;td&gt;0.173 ms&lt;/td&gt;&lt;td&gt;0.172 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;0.992 ms&lt;/td&gt;&lt;td&gt;0.655 ms&lt;/td&gt;&lt;td&gt;0.582 ms&lt;/td&gt;&lt;td&gt;0.589 ms&lt;/td&gt;&lt;td&gt;0.554 ms&lt;/td&gt;&lt;td&gt;0.549 ms&lt;/td&gt;&lt;td&gt;0.525 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;0.693 ms&lt;/td&gt;&lt;td&gt;0.463 ms&lt;/td&gt;&lt;td&gt;0.437 ms&lt;/td&gt;&lt;td&gt;0.461 ms&lt;/td&gt;&lt;td&gt;0.450 ms&lt;/td&gt;&lt;td&gt;0.443 ms&lt;/td&gt;&lt;td&gt;0.436 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;0.242 ms&lt;/td&gt;&lt;td&gt;0.201 ms&lt;/td&gt;&lt;td&gt;0.200 ms&lt;/td&gt;&lt;td&gt;0.198 ms&lt;/td&gt;&lt;td&gt;0.200 ms&lt;/td&gt;&lt;td&gt;0.199 ms&lt;/td&gt;&lt;td&gt;0.197 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;rating:[90 TO 99] - 1,099 movies, 17 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;12.949 ms&lt;/td&gt;&lt;td&gt;13.057 ms&lt;/td&gt;&lt;td&gt;12.981 ms&lt;/td&gt;&lt;td&gt;13.018 ms&lt;/td&gt;&lt;td&gt;13.150 ms&lt;/td&gt;&lt;td&gt;12.840 ms&lt;/td&gt;&lt;td&gt;12.644 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;0.696 ms&lt;/td&gt;&lt;td&gt;0.546 ms&lt;/td&gt;&lt;td&gt;0.516 ms&lt;/td&gt;&lt;td&gt;0.530 ms&lt;/td&gt;&lt;td&gt;0.515 ms&lt;/td&gt;&lt;td&gt;0.518 ms&lt;/td&gt;&lt;td&gt;0.522 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;0.448 ms&lt;/td&gt;&lt;td&gt;0.234 ms&lt;/td&gt;&lt;td&gt;0.231 ms&lt;/td&gt;&lt;td&gt;0.237 ms&lt;/td&gt;&lt;td&gt;0.236 ms&lt;/td&gt;&lt;td&gt;0.231 ms&lt;/td&gt;&lt;td&gt;0.231 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;5.051 ms&lt;/td&gt;&lt;td&gt;4.485 ms&lt;/td&gt;&lt;td&gt;4.441 ms&lt;/td&gt;&lt;td&gt;4.486 ms&lt;/td&gt;&lt;td&gt;4.425 ms&lt;/td&gt;&lt;td&gt;4.831 ms&lt;/td&gt;&lt;td&gt;4.828 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;1.465 ms&lt;/td&gt;&lt;td&gt;1.133 ms&lt;/td&gt;&lt;td&gt;1.110 ms&lt;/td&gt;&lt;td&gt;1.104 ms&lt;/td&gt;&lt;td&gt;1.108 ms&lt;/td&gt;&lt;td&gt;1.108 ms&lt;/td&gt;&lt;td&gt;1.108 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;1.445 ms&lt;/td&gt;&lt;td&gt;1.285 ms&lt;/td&gt;&lt;td&gt;1.159 ms&lt;/td&gt;&lt;td&gt;7.824 ms&lt;/td&gt;&lt;td&gt;1.878 ms&lt;/td&gt;&lt;td&gt;1.669 ms&lt;/td&gt;&lt;td&gt;1.393 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;rating:[90 TO 99] - 3,216 movies, 35 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;14.287 ms&lt;/td&gt;&lt;td&gt;13.596 ms&lt;/td&gt;&lt;td&gt;13.453 ms&lt;/td&gt;&lt;td&gt;13.912 ms&lt;/td&gt;&lt;td&gt;13.875 ms&lt;/td&gt;&lt;td&gt;14.559 ms&lt;/td&gt;&lt;td&gt;13.981 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;3.524 ms&lt;/td&gt;&lt;td&gt;4.110 ms&lt;/td&gt;&lt;td&gt;4.129 ms&lt;/td&gt;&lt;td&gt;1.916 ms&lt;/td&gt;&lt;td&gt;1.732 ms&lt;/td&gt;&lt;td&gt;2.300 ms&lt;/td&gt;&lt;td&gt;9.584 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;0.423 ms&lt;/td&gt;&lt;td&gt;2.036 ms&lt;/td&gt;&lt;td&gt;4.617 ms&lt;/td&gt;&lt;td&gt;4.577 ms&lt;/td&gt;&lt;td&gt;0.388 ms&lt;/td&gt;&lt;td&gt;1.957 ms&lt;/td&gt;&lt;td&gt;7.981 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;12.776 ms&lt;/td&gt;&lt;td&gt;11.816 ms&lt;/td&gt;&lt;td&gt;12.449 ms&lt;/td&gt;&lt;td&gt;11.755 ms&lt;/td&gt;&lt;td&gt;11.762 ms&lt;/td&gt;&lt;td&gt;11.983 ms&lt;/td&gt;&lt;td&gt;11.764 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;2.935 ms&lt;/td&gt;&lt;td&gt;2.517 ms&lt;/td&gt;&lt;td&gt;2.374 ms&lt;/td&gt;&lt;td&gt;2.264 ms&lt;/td&gt;&lt;td&gt;2.250 ms&lt;/td&gt;&lt;td&gt;2.261 ms&lt;/td&gt;&lt;td&gt;2.258 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;9.292 ms&lt;/td&gt;&lt;td&gt;2.702 ms&lt;/td&gt;&lt;td&gt;10.573 ms&lt;/td&gt;&lt;td&gt;6.773 ms&lt;/td&gt;&lt;td&gt;3.098 ms&lt;/td&gt;&lt;td&gt;11.438 ms&lt;/td&gt;&lt;td&gt;3.035 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;rating:[90 TO 99] - 17,251 movies, 260 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;58.996 ms&lt;/td&gt;&lt;td&gt;56.894 ms&lt;/td&gt;&lt;td&gt;62.172 ms&lt;/td&gt;&lt;td&gt;57.028 ms&lt;/td&gt;&lt;td&gt;57.255 ms&lt;/td&gt;&lt;td&gt;57.540 ms&lt;/td&gt;&lt;td&gt;57.259 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;36.682 ms&lt;/td&gt;&lt;td&gt;28.260 ms&lt;/td&gt;&lt;td&gt;34.116 ms&lt;/td&gt;&lt;td&gt;34.786 ms&lt;/td&gt;&lt;td&gt;35.195 ms&lt;/td&gt;&lt;td&gt;35.813 ms&lt;/td&gt;&lt;td&gt;35.221 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;45.802 ms&lt;/td&gt;&lt;td&gt;62.460 ms&lt;/td&gt;&lt;td&gt;31.603 ms&lt;/td&gt;&lt;td&gt;32.982 ms&lt;/td&gt;&lt;td&gt;33.302 ms&lt;/td&gt;&lt;td&gt;31.904 ms&lt;/td&gt;&lt;td&gt;31.656 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;67.022 ms&lt;/td&gt;&lt;td&gt;64.609 ms&lt;/td&gt;&lt;td&gt;64.649 ms&lt;/td&gt;&lt;td&gt;65.243 ms&lt;/td&gt;&lt;td&gt;64.183 ms&lt;/td&gt;&lt;td&gt;64.887 ms&lt;/td&gt;&lt;td&gt;64.283 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;14.730 ms&lt;/td&gt;&lt;td&gt;14.179 ms&lt;/td&gt;&lt;td&gt;14.132 ms&lt;/td&gt;&lt;td&gt;14.221 ms&lt;/td&gt;&lt;td&gt;14.248 ms&lt;/td&gt;&lt;td&gt;20.225 ms&lt;/td&gt;&lt;td&gt;35.888 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;94.872 ms&lt;/td&gt;&lt;td&gt;47.067 ms&lt;/td&gt;&lt;td&gt;85.202 ms&lt;/td&gt;&lt;td&gt;28.575 ms&lt;/td&gt;&lt;td&gt;142.854 ms&lt;/td&gt;&lt;td&gt;48.562 ms&lt;/td&gt;&lt;td&gt;52.567 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;rating:[90 TO 99] - 121,587 movies, 1,510 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;283.122 ms&lt;/td&gt;&lt;td&gt;392.801 ms&lt;/td&gt;&lt;td&gt;382.164 ms&lt;/td&gt;&lt;td&gt;403.929 ms&lt;/td&gt;&lt;td&gt;384.512 ms&lt;/td&gt;&lt;td&gt;408.292 ms&lt;/td&gt;&lt;td&gt;361.548 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;293.488 ms&lt;/td&gt;&lt;td&gt;236.636 ms&lt;/td&gt;&lt;td&gt;249.677 ms&lt;/td&gt;&lt;td&gt;232.674 ms&lt;/td&gt;&lt;td&gt;270.198 ms&lt;/td&gt;&lt;td&gt;282.806 ms&lt;/td&gt;&lt;td&gt;218.726 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;231.638 ms&lt;/td&gt;&lt;td&gt;311.523 ms&lt;/td&gt;&lt;td&gt;198.781 ms&lt;/td&gt;&lt;td&gt;279.063 ms&lt;/td&gt;&lt;td&gt;219.294 ms&lt;/td&gt;&lt;td&gt;192.589 ms&lt;/td&gt;&lt;td&gt;276.822 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;181.478 ms&lt;/td&gt;&lt;td&gt;272.453 ms&lt;/td&gt;&lt;td&gt;251.730 ms&lt;/td&gt;&lt;td&gt;256.744 ms&lt;/td&gt;&lt;td&gt;293.067 ms&lt;/td&gt;&lt;td&gt;230.615 ms&lt;/td&gt;&lt;td&gt;245.113 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;376.176 ms&lt;/td&gt;&lt;td&gt;417.637 ms&lt;/td&gt;&lt;td&gt;411.263 ms&lt;/td&gt;&lt;td&gt;366.596 ms&lt;/td&gt;&lt;td&gt;393.168 ms&lt;/td&gt;&lt;td&gt;372.888 ms&lt;/td&gt;&lt;td&gt;412.411 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;release:[1999/01/01 TO 1999/09/30] - 9 movies, 2 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;18.768 ms&lt;/td&gt;&lt;td&gt;10.167 ms&lt;/td&gt;&lt;td&gt;10.799 ms&lt;/td&gt;&lt;td&gt;10.215 ms&lt;/td&gt;&lt;td&gt;10.443 ms&lt;/td&gt;&lt;td&gt;10.917 ms&lt;/td&gt;&lt;td&gt;10.210 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;0.165 ms&lt;/td&gt;&lt;td&gt;0.166 ms&lt;/td&gt;&lt;td&gt;0.164 ms&lt;/td&gt;&lt;td&gt;0.164 ms&lt;/td&gt;&lt;td&gt;0.168 ms&lt;/td&gt;&lt;td&gt;0.164 ms&lt;/td&gt;&lt;td&gt;0.164 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;0.175 ms&lt;/td&gt;&lt;td&gt;0.175 ms&lt;/td&gt;&lt;td&gt;0.170 ms&lt;/td&gt;&lt;td&gt;0.169 ms&lt;/td&gt;&lt;td&gt;0.169 ms&lt;/td&gt;&lt;td&gt;0.169 ms&lt;/td&gt;&lt;td&gt;0.170 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;1.074 ms&lt;/td&gt;&lt;td&gt;0.569 ms&lt;/td&gt;&lt;td&gt;0.546 ms&lt;/td&gt;&lt;td&gt;0.561 ms&lt;/td&gt;&lt;td&gt;0.544 ms&lt;/td&gt;&lt;td&gt;0.549 ms&lt;/td&gt;&lt;td&gt;0.546 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;0.877 ms&lt;/td&gt;&lt;td&gt;0.480 ms&lt;/td&gt;&lt;td&gt;0.460 ms&lt;/td&gt;&lt;td&gt;0.458 ms&lt;/td&gt;&lt;td&gt;0.461 ms&lt;/td&gt;&lt;td&gt;0.458 ms&lt;/td&gt;&lt;td&gt;0.456 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;0.183 ms&lt;/td&gt;&lt;td&gt;0.175 ms&lt;/td&gt;&lt;td&gt;0.175 ms&lt;/td&gt;&lt;td&gt;0.178 ms&lt;/td&gt;&lt;td&gt;0.178 ms&lt;/td&gt;&lt;td&gt;0.180 ms&lt;/td&gt;&lt;td&gt;0.175 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;release:[1999/01/01 TO 1999/09/30] - 1,099 movies, 34 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;19.154 ms&lt;/td&gt;&lt;td&gt;19.449 ms&lt;/td&gt;&lt;td&gt;18.811 ms&lt;/td&gt;&lt;td&gt;19.419 ms&lt;/td&gt;&lt;td&gt;19.692 ms&lt;/td&gt;&lt;td&gt;19.315 ms&lt;/td&gt;&lt;td&gt;18.862 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;0.691 ms&lt;/td&gt;&lt;td&gt;0.686 ms&lt;/td&gt;&lt;td&gt;0.684 ms&lt;/td&gt;&lt;td&gt;0.687 ms&lt;/td&gt;&lt;td&gt;0.690 ms&lt;/td&gt;&lt;td&gt;0.702 ms&lt;/td&gt;&lt;td&gt;0.698 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;0.365 ms&lt;/td&gt;&lt;td&gt;0.311 ms&lt;/td&gt;&lt;td&gt;0.317 ms&lt;/td&gt;&lt;td&gt;0.312 ms&lt;/td&gt;&lt;td&gt;0.311 ms&lt;/td&gt;&lt;td&gt;0.312 ms&lt;/td&gt;&lt;td&gt;0.313 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;6.231 ms&lt;/td&gt;&lt;td&gt;5.543 ms&lt;/td&gt;&lt;td&gt;5.734 ms&lt;/td&gt;&lt;td&gt;5.522 ms&lt;/td&gt;&lt;td&gt;5.663 ms&lt;/td&gt;&lt;td&gt;5.538 ms&lt;/td&gt;&lt;td&gt;5.465 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;1.998 ms&lt;/td&gt;&lt;td&gt;1.494 ms&lt;/td&gt;&lt;td&gt;1.466 ms&lt;/td&gt;&lt;td&gt;1.469 ms&lt;/td&gt;&lt;td&gt;1.470 ms&lt;/td&gt;&lt;td&gt;1.454 ms&lt;/td&gt;&lt;td&gt;1.469 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;5.336 ms&lt;/td&gt;&lt;td&gt;1.590 ms&lt;/td&gt;&lt;td&gt;7.241 ms&lt;/td&gt;&lt;td&gt;1.977 ms&lt;/td&gt;&lt;td&gt;2.651 ms&lt;/td&gt;&lt;td&gt;4.013 ms&lt;/td&gt;&lt;td&gt;2.544 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;release:[1999/01/01 TO 1999/09/30] - 3,216 movies, 84 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;32.202 ms&lt;/td&gt;&lt;td&gt;31.513 ms&lt;/td&gt;&lt;td&gt;31.362 ms&lt;/td&gt;&lt;td&gt;30.894 ms&lt;/td&gt;&lt;td&gt;31.345 ms&lt;/td&gt;&lt;td&gt;31.741 ms&lt;/td&gt;&lt;td&gt;31.518 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;6.169 ms&lt;/td&gt;&lt;td&gt;2.645 ms&lt;/td&gt;&lt;td&gt;7.560 ms&lt;/td&gt;&lt;td&gt;20.764 ms&lt;/td&gt;&lt;td&gt;10.385 ms&lt;/td&gt;&lt;td&gt;13.278 ms&lt;/td&gt;&lt;td&gt;10.206 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;19.176 ms&lt;/td&gt;&lt;td&gt;4.358 ms&lt;/td&gt;&lt;td&gt;12.576 ms&lt;/td&gt;&lt;td&gt;15.448 ms&lt;/td&gt;&lt;td&gt;15.745 ms&lt;/td&gt;&lt;td&gt;5.572 ms&lt;/td&gt;&lt;td&gt;5.770 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;15.507 ms&lt;/td&gt;&lt;td&gt;14.803 ms&lt;/td&gt;&lt;td&gt;13.629 ms&lt;/td&gt;&lt;td&gt;15.465 ms&lt;/td&gt;&lt;td&gt;13.930 ms&lt;/td&gt;&lt;td&gt;14.515 ms&lt;/td&gt;&lt;td&gt;13.652 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;3.956 ms&lt;/td&gt;&lt;td&gt;3.488 ms&lt;/td&gt;&lt;td&gt;3.183 ms&lt;/td&gt;&lt;td&gt;3.176 ms&lt;/td&gt;&lt;td&gt;3.213 ms&lt;/td&gt;&lt;td&gt;3.193 ms&lt;/td&gt;&lt;td&gt;3.157 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;18.414 ms&lt;/td&gt;&lt;td&gt;5.874 ms&lt;/td&gt;&lt;td&gt;11.902 ms&lt;/td&gt;&lt;td&gt;12.932 ms&lt;/td&gt;&lt;td&gt;19.995 ms&lt;/td&gt;&lt;td&gt;21.098 ms&lt;/td&gt;&lt;td&gt;13.009 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;release:[1999/01/01 TO 1999/09/30] - 17,251 movies, 374 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;93.892 ms&lt;/td&gt;&lt;td&gt;93.900 ms&lt;/td&gt;&lt;td&gt;93.549 ms&lt;/td&gt;&lt;td&gt;93.555 ms&lt;/td&gt;&lt;td&gt;93.924 ms&lt;/td&gt;&lt;td&gt;94.396 ms&lt;/td&gt;&lt;td&gt;93.795 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;37.831 ms&lt;/td&gt;&lt;td&gt;44.905 ms&lt;/td&gt;&lt;td&gt;47.617 ms&lt;/td&gt;&lt;td&gt;45.894 ms&lt;/td&gt;&lt;td&gt;43.796 ms&lt;/td&gt;&lt;td&gt;45.752 ms&lt;/td&gt;&lt;td&gt;47.048 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;48.475 ms&lt;/td&gt;&lt;td&gt;47.805 ms&lt;/td&gt;&lt;td&gt;43.046 ms&lt;/td&gt;&lt;td&gt;47.393 ms&lt;/td&gt;&lt;td&gt;44.689 ms&lt;/td&gt;&lt;td&gt;47.842 ms&lt;/td&gt;&lt;td&gt;54.208 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;72.507 ms&lt;/td&gt;&lt;td&gt;72.667 ms&lt;/td&gt;&lt;td&gt;72.233 ms&lt;/td&gt;&lt;td&gt;73.570 ms&lt;/td&gt;&lt;td&gt;72.997 ms&lt;/td&gt;&lt;td&gt;72.991 ms&lt;/td&gt;&lt;td&gt;72.527 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;29.351 ms&lt;/td&gt;&lt;td&gt;48.892 ms&lt;/td&gt;&lt;td&gt;55.351 ms&lt;/td&gt;&lt;td&gt;49.793 ms&lt;/td&gt;&lt;td&gt;88.375 ms&lt;/td&gt;&lt;td&gt;55.393 ms&lt;/td&gt;&lt;td&gt;45.917 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;59.522 ms&lt;/td&gt;&lt;td&gt;168.591 ms&lt;/td&gt;&lt;td&gt;55.750 ms&lt;/td&gt;&lt;td&gt;83.424 ms&lt;/td&gt;&lt;td&gt;113.679 ms&lt;/td&gt;&lt;td&gt;62.803 ms&lt;/td&gt;&lt;td&gt;127.895 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;release:[1999/01/01 TO 1999/09/30] - 121,587 movies, 2,265 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;543.495 ms&lt;/td&gt;&lt;td&gt;564.582 ms&lt;/td&gt;&lt;td&gt;609.045 ms&lt;/td&gt;&lt;td&gt;519.248 ms&lt;/td&gt;&lt;td&gt;561.844 ms&lt;/td&gt;&lt;td&gt;663.549 ms&lt;/td&gt;&lt;td&gt;590.518 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;165.617 ms&lt;/td&gt;&lt;td&gt;387.256 ms&lt;/td&gt;&lt;td&gt;293.285 ms&lt;/td&gt;&lt;td&gt;335.219 ms&lt;/td&gt;&lt;td&gt;324.528 ms&lt;/td&gt;&lt;td&gt;324.022 ms&lt;/td&gt;&lt;td&gt;371.839 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;375.504 ms&lt;/td&gt;&lt;td&gt;315.671 ms&lt;/td&gt;&lt;td&gt;321.115 ms&lt;/td&gt;&lt;td&gt;371.228 ms&lt;/td&gt;&lt;td&gt;300.951 ms&lt;/td&gt;&lt;td&gt;344.073 ms&lt;/td&gt;&lt;td&gt;356.366 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;241.569 ms&lt;/td&gt;&lt;td&gt;316.626 ms&lt;/td&gt;&lt;td&gt;398.308 ms&lt;/td&gt;&lt;td&gt;349.426 ms&lt;/td&gt;&lt;td&gt;398.289 ms&lt;/td&gt;&lt;td&gt;318.078 ms&lt;/td&gt;&lt;td&gt;363.809 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;529.377 ms&lt;/td&gt;&lt;td&gt;556.989 ms&lt;/td&gt;&lt;td&gt;577.643 ms&lt;/td&gt;&lt;td&gt;576.194 ms&lt;/td&gt;&lt;td&gt;626.388 ms&lt;/td&gt;&lt;td&gt;545.251 ms&lt;/td&gt;&lt;td&gt;570.695 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;release=1999/03/31 - 9 movies, 1 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;10.065 ms&lt;/td&gt;&lt;td&gt;10.068 ms&lt;/td&gt;&lt;td&gt;9.702 ms&lt;/td&gt;&lt;td&gt;9.974 ms&lt;/td&gt;&lt;td&gt;9.837 ms&lt;/td&gt;&lt;td&gt;9.751 ms&lt;/td&gt;&lt;td&gt;10.356 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;0.164 ms&lt;/td&gt;&lt;td&gt;0.165 ms&lt;/td&gt;&lt;td&gt;0.171 ms&lt;/td&gt;&lt;td&gt;0.168 ms&lt;/td&gt;&lt;td&gt;0.167 ms&lt;/td&gt;&lt;td&gt;0.164 ms&lt;/td&gt;&lt;td&gt;0.162 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;0.171 ms&lt;/td&gt;&lt;td&gt;0.169 ms&lt;/td&gt;&lt;td&gt;0.171 ms&lt;/td&gt;&lt;td&gt;0.172 ms&lt;/td&gt;&lt;td&gt;0.175 ms&lt;/td&gt;&lt;td&gt;0.165 ms&lt;/td&gt;&lt;td&gt;0.164 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;0.659 ms&lt;/td&gt;&lt;td&gt;0.476 ms&lt;/td&gt;&lt;td&gt;0.473 ms&lt;/td&gt;&lt;td&gt;0.469 ms&lt;/td&gt;&lt;td&gt;0.464 ms&lt;/td&gt;&lt;td&gt;0.468 ms&lt;/td&gt;&lt;td&gt;0.468 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;0.510 ms&lt;/td&gt;&lt;td&gt;0.395 ms&lt;/td&gt;&lt;td&gt;0.385 ms&lt;/td&gt;&lt;td&gt;0.384 ms&lt;/td&gt;&lt;td&gt;0.389 ms&lt;/td&gt;&lt;td&gt;0.383 ms&lt;/td&gt;&lt;td&gt;0.389 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;0.154 ms&lt;/td&gt;&lt;td&gt;0.152 ms&lt;/td&gt;&lt;td&gt;0.151 ms&lt;/td&gt;&lt;td&gt;0.153 ms&lt;/td&gt;&lt;td&gt;0.152 ms&lt;/td&gt;&lt;td&gt;0.156 ms&lt;/td&gt;&lt;td&gt;0.152 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;release=1999/03/31 - 1,099 movies, 2 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;10.853 ms&lt;/td&gt;&lt;td&gt;10.545 ms&lt;/td&gt;&lt;td&gt;10.718 ms&lt;/td&gt;&lt;td&gt;10.390 ms&lt;/td&gt;&lt;td&gt;10.521 ms&lt;/td&gt;&lt;td&gt;10.754 ms&lt;/td&gt;&lt;td&gt;10.661 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;0.515 ms&lt;/td&gt;&lt;td&gt;0.528 ms&lt;/td&gt;&lt;td&gt;0.505 ms&lt;/td&gt;&lt;td&gt;0.512 ms&lt;/td&gt;&lt;td&gt;0.502 ms&lt;/td&gt;&lt;td&gt;0.507 ms&lt;/td&gt;&lt;td&gt;0.505 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;3.139 ms&lt;/td&gt;&lt;td&gt;0.184 ms&lt;/td&gt;&lt;td&gt;0.175 ms&lt;/td&gt;&lt;td&gt;3.440 ms&lt;/td&gt;&lt;td&gt;0.183 ms&lt;/td&gt;&lt;td&gt;0.212 ms&lt;/td&gt;&lt;td&gt;0.205 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;4.559 ms&lt;/td&gt;&lt;td&gt;4.229 ms&lt;/td&gt;&lt;td&gt;4.177 ms&lt;/td&gt;&lt;td&gt;4.220 ms&lt;/td&gt;&lt;td&gt;4.383 ms&lt;/td&gt;&lt;td&gt;4.532 ms&lt;/td&gt;&lt;td&gt;4.464 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;0.977 ms&lt;/td&gt;&lt;td&gt;0.830 ms&lt;/td&gt;&lt;td&gt;0.800 ms&lt;/td&gt;&lt;td&gt;0.808 ms&lt;/td&gt;&lt;td&gt;0.802 ms&lt;/td&gt;&lt;td&gt;0.811 ms&lt;/td&gt;&lt;td&gt;0.802 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;0.672 ms&lt;/td&gt;&lt;td&gt;0.685 ms&lt;/td&gt;&lt;td&gt;0.774 ms&lt;/td&gt;&lt;td&gt;0.752 ms&lt;/td&gt;&lt;td&gt;0.916 ms&lt;/td&gt;&lt;td&gt;1.285 ms&lt;/td&gt;&lt;td&gt;0.663 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;release=1999/03/31 - 3,216 movies, 2 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;10.799 ms&lt;/td&gt;&lt;td&gt;10.762 ms&lt;/td&gt;&lt;td&gt;11.399 ms&lt;/td&gt;&lt;td&gt;10.676 ms&lt;/td&gt;&lt;td&gt;10.704 ms&lt;/td&gt;&lt;td&gt;10.169 ms&lt;/td&gt;&lt;td&gt;10.325 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;1.912 ms&lt;/td&gt;&lt;td&gt;1.462 ms&lt;/td&gt;&lt;td&gt;1.453 ms&lt;/td&gt;&lt;td&gt;1.163 ms&lt;/td&gt;&lt;td&gt;1.151 ms&lt;/td&gt;&lt;td&gt;1.157 ms&lt;/td&gt;&lt;td&gt;4.858 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;0.366 ms&lt;/td&gt;&lt;td&gt;0.350 ms&lt;/td&gt;&lt;td&gt;0.355 ms&lt;/td&gt;&lt;td&gt;1.883 ms&lt;/td&gt;&lt;td&gt;0.364 ms&lt;/td&gt;&lt;td&gt;0.345 ms&lt;/td&gt;&lt;td&gt;0.371 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;11.707 ms&lt;/td&gt;&lt;td&gt;11.548 ms&lt;/td&gt;&lt;td&gt;11.433 ms&lt;/td&gt;&lt;td&gt;11.425 ms&lt;/td&gt;&lt;td&gt;11.465 ms&lt;/td&gt;&lt;td&gt;11.450 ms&lt;/td&gt;&lt;td&gt;11.912 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;1.661 ms&lt;/td&gt;&lt;td&gt;1.511 ms&lt;/td&gt;&lt;td&gt;1.513 ms&lt;/td&gt;&lt;td&gt;1.714 ms&lt;/td&gt;&lt;td&gt;1.507 ms&lt;/td&gt;&lt;td&gt;1.612 ms&lt;/td&gt;&lt;td&gt;1.510 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;1.278 ms&lt;/td&gt;&lt;td&gt;1.364 ms&lt;/td&gt;&lt;td&gt;1.359 ms&lt;/td&gt;&lt;td&gt;1.821 ms&lt;/td&gt;&lt;td&gt;1.994 ms&lt;/td&gt;&lt;td&gt;1.429 ms&lt;/td&gt;&lt;td&gt;3.192 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;release=1999/03/31 - 17,251 movies, 3 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;12.485 ms&lt;/td&gt;&lt;td&gt;12.281 ms&lt;/td&gt;&lt;td&gt;12.323 ms&lt;/td&gt;&lt;td&gt;11.981 ms&lt;/td&gt;&lt;td&gt;12.137 ms&lt;/td&gt;&lt;td&gt;11.808 ms&lt;/td&gt;&lt;td&gt;12.552 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;8.247 ms&lt;/td&gt;&lt;td&gt;6.259 ms&lt;/td&gt;&lt;td&gt;6.007 ms&lt;/td&gt;&lt;td&gt;6.300 ms&lt;/td&gt;&lt;td&gt;6.125 ms&lt;/td&gt;&lt;td&gt;5.958 ms&lt;/td&gt;&lt;td&gt;5.921 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;0.379 ms&lt;/td&gt;&lt;td&gt;0.297 ms&lt;/td&gt;&lt;td&gt;0.285 ms&lt;/td&gt;&lt;td&gt;0.284 ms&lt;/td&gt;&lt;td&gt;0.252 ms&lt;/td&gt;&lt;td&gt;0.254 ms&lt;/td&gt;&lt;td&gt;0.251 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;61.537 ms&lt;/td&gt;&lt;td&gt;60.815 ms&lt;/td&gt;&lt;td&gt;61.014 ms&lt;/td&gt;&lt;td&gt;60.821 ms&lt;/td&gt;&lt;td&gt;61.013 ms&lt;/td&gt;&lt;td&gt;60.850 ms&lt;/td&gt;&lt;td&gt;60.820 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;11.063 ms&lt;/td&gt;&lt;td&gt;8.021 ms&lt;/td&gt;&lt;td&gt;8.414 ms&lt;/td&gt;&lt;td&gt;8.690 ms&lt;/td&gt;&lt;td&gt;7.798 ms&lt;/td&gt;&lt;td&gt;7.811 ms&lt;/td&gt;&lt;td&gt;8.313 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;5.545 ms&lt;/td&gt;&lt;td&gt;4.561 ms&lt;/td&gt;&lt;td&gt;4.956 ms&lt;/td&gt;&lt;td&gt;4.388 ms&lt;/td&gt;&lt;td&gt;4.321 ms&lt;/td&gt;&lt;td&gt;4.687 ms&lt;/td&gt;&lt;td&gt;4.396 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;release=1999/03/31 - 121,587 movies, 12 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;14.005 ms&lt;/td&gt;&lt;td&gt;14.031 ms&lt;/td&gt;&lt;td&gt;12.792 ms&lt;/td&gt;&lt;td&gt;14.354 ms&lt;/td&gt;&lt;td&gt;12.736 ms&lt;/td&gt;&lt;td&gt;13.862 ms&lt;/td&gt;&lt;td&gt;13.374 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;64.517 ms&lt;/td&gt;&lt;td&gt;61.783 ms&lt;/td&gt;&lt;td&gt;61.669 ms&lt;/td&gt;&lt;td&gt;62.418 ms&lt;/td&gt;&lt;td&gt;61.377 ms&lt;/td&gt;&lt;td&gt;61.326 ms&lt;/td&gt;&lt;td&gt;62.036 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;9.994 ms&lt;/td&gt;&lt;td&gt;0.403 ms&lt;/td&gt;&lt;td&gt;0.358 ms&lt;/td&gt;&lt;td&gt;0.351 ms&lt;/td&gt;&lt;td&gt;0.368 ms&lt;/td&gt;&lt;td&gt;0.363 ms&lt;/td&gt;&lt;td&gt;3.368 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;62.160 ms&lt;/td&gt;&lt;td&gt;62.760 ms&lt;/td&gt;&lt;td&gt;56.630 ms&lt;/td&gt;&lt;td&gt;60.929 ms&lt;/td&gt;&lt;td&gt;54.310 ms&lt;/td&gt;&lt;td&gt;53.189 ms&lt;/td&gt;&lt;td&gt;58.016 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;29.180 ms&lt;/td&gt;&lt;td&gt;28.239 ms&lt;/td&gt;&lt;td&gt;28.080 ms&lt;/td&gt;&lt;td&gt;28.054 ms&lt;/td&gt;&lt;td&gt;27.777 ms&lt;/td&gt;&lt;td&gt;27.615 ms&lt;/td&gt;&lt;td&gt;27.505 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;title=The Matrix - 9 movies, 1 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;9.248 ms&lt;/td&gt;&lt;td&gt;8.929 ms&lt;/td&gt;&lt;td&gt;9.139 ms&lt;/td&gt;&lt;td&gt;9.455 ms&lt;/td&gt;&lt;td&gt;9.609 ms&lt;/td&gt;&lt;td&gt;9.128 ms&lt;/td&gt;&lt;td&gt;9.110 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;0.163 ms&lt;/td&gt;&lt;td&gt;0.163 ms&lt;/td&gt;&lt;td&gt;0.163 ms&lt;/td&gt;&lt;td&gt;0.161 ms&lt;/td&gt;&lt;td&gt;0.160 ms&lt;/td&gt;&lt;td&gt;0.163 ms&lt;/td&gt;&lt;td&gt;0.164 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;0.167 ms&lt;/td&gt;&lt;td&gt;0.165 ms&lt;/td&gt;&lt;td&gt;0.178 ms&lt;/td&gt;&lt;td&gt;0.164 ms&lt;/td&gt;&lt;td&gt;0.164 ms&lt;/td&gt;&lt;td&gt;0.163 ms&lt;/td&gt;&lt;td&gt;0.165 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;0.733 ms&lt;/td&gt;&lt;td&gt;0.484 ms&lt;/td&gt;&lt;td&gt;0.475 ms&lt;/td&gt;&lt;td&gt;0.478 ms&lt;/td&gt;&lt;td&gt;0.481 ms&lt;/td&gt;&lt;td&gt;0.475 ms&lt;/td&gt;&lt;td&gt;0.476 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;0.575 ms&lt;/td&gt;&lt;td&gt;0.400 ms&lt;/td&gt;&lt;td&gt;0.380 ms&lt;/td&gt;&lt;td&gt;0.382 ms&lt;/td&gt;&lt;td&gt;0.379 ms&lt;/td&gt;&lt;td&gt;0.387 ms&lt;/td&gt;&lt;td&gt;0.379 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;0.226 ms&lt;/td&gt;&lt;td&gt;0.197 ms&lt;/td&gt;&lt;td&gt;0.194 ms&lt;/td&gt;&lt;td&gt;0.191 ms&lt;/td&gt;&lt;td&gt;0.191 ms&lt;/td&gt;&lt;td&gt;0.194 ms&lt;/td&gt;&lt;td&gt;0.190 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;title=The Matrix - 1,099 movies, 1 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;10.758 ms&lt;/td&gt;&lt;td&gt;10.578 ms&lt;/td&gt;&lt;td&gt;10.083 ms&lt;/td&gt;&lt;td&gt;10.230 ms&lt;/td&gt;&lt;td&gt;10.555 ms&lt;/td&gt;&lt;td&gt;10.630 ms&lt;/td&gt;&lt;td&gt;10.831 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;0.728 ms&lt;/td&gt;&lt;td&gt;0.524 ms&lt;/td&gt;&lt;td&gt;0.504 ms&lt;/td&gt;&lt;td&gt;0.501 ms&lt;/td&gt;&lt;td&gt;0.506 ms&lt;/td&gt;&lt;td&gt;0.500 ms&lt;/td&gt;&lt;td&gt;0.501 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;0.218 ms&lt;/td&gt;&lt;td&gt;0.203 ms&lt;/td&gt;&lt;td&gt;0.201 ms&lt;/td&gt;&lt;td&gt;0.198 ms&lt;/td&gt;&lt;td&gt;0.199 ms&lt;/td&gt;&lt;td&gt;0.277 ms&lt;/td&gt;&lt;td&gt;0.233 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;5.906 ms&lt;/td&gt;&lt;td&gt;5.409 ms&lt;/td&gt;&lt;td&gt;5.426 ms&lt;/td&gt;&lt;td&gt;5.453 ms&lt;/td&gt;&lt;td&gt;5.420 ms&lt;/td&gt;&lt;td&gt;5.410 ms&lt;/td&gt;&lt;td&gt;5.344 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;1.685 ms&lt;/td&gt;&lt;td&gt;1.471 ms&lt;/td&gt;&lt;td&gt;1.455 ms&lt;/td&gt;&lt;td&gt;1.455 ms&lt;/td&gt;&lt;td&gt;1.440 ms&lt;/td&gt;&lt;td&gt;1.448 ms&lt;/td&gt;&lt;td&gt;1.439 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;0.445 ms&lt;/td&gt;&lt;td&gt;0.385 ms&lt;/td&gt;&lt;td&gt;0.398 ms&lt;/td&gt;&lt;td&gt;0.373 ms&lt;/td&gt;&lt;td&gt;0.836 ms&lt;/td&gt;&lt;td&gt;0.451 ms&lt;/td&gt;&lt;td&gt;0.374 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;title=The Matrix - 3,216 movies, 1 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;10.138 ms&lt;/td&gt;&lt;td&gt;10.144 ms&lt;/td&gt;&lt;td&gt;10.652 ms&lt;/td&gt;&lt;td&gt;10.124 ms&lt;/td&gt;&lt;td&gt;10.169 ms&lt;/td&gt;&lt;td&gt;10.070 ms&lt;/td&gt;&lt;td&gt;10.547 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;2.587 ms&lt;/td&gt;&lt;td&gt;1.180 ms&lt;/td&gt;&lt;td&gt;1.198 ms&lt;/td&gt;&lt;td&gt;2.202 ms&lt;/td&gt;&lt;td&gt;1.411 ms&lt;/td&gt;&lt;td&gt;1.422 ms&lt;/td&gt;&lt;td&gt;1.288 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;0.323 ms&lt;/td&gt;&lt;td&gt;0.300 ms&lt;/td&gt;&lt;td&gt;0.306 ms&lt;/td&gt;&lt;td&gt;0.298 ms&lt;/td&gt;&lt;td&gt;0.493 ms&lt;/td&gt;&lt;td&gt;0.304 ms&lt;/td&gt;&lt;td&gt;0.304 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;15.097 ms&lt;/td&gt;&lt;td&gt;14.727 ms&lt;/td&gt;&lt;td&gt;14.692 ms&lt;/td&gt;&lt;td&gt;14.759 ms&lt;/td&gt;&lt;td&gt;14.840 ms&lt;/td&gt;&lt;td&gt;14.888 ms&lt;/td&gt;&lt;td&gt;14.791 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;3.727 ms&lt;/td&gt;&lt;td&gt;3.529 ms&lt;/td&gt;&lt;td&gt;3.558 ms&lt;/td&gt;&lt;td&gt;3.545 ms&lt;/td&gt;&lt;td&gt;3.504 ms&lt;/td&gt;&lt;td&gt;3.504 ms&lt;/td&gt;&lt;td&gt;3.520 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;0.432 ms&lt;/td&gt;&lt;td&gt;0.353 ms&lt;/td&gt;&lt;td&gt;0.345 ms&lt;/td&gt;&lt;td&gt;0.349 ms&lt;/td&gt;&lt;td&gt;0.348 ms&lt;/td&gt;&lt;td&gt;0.342 ms&lt;/td&gt;&lt;td&gt;0.692 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;title=The Matrix - 17,251 movies, 1 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;12.462 ms&lt;/td&gt;&lt;td&gt;11.871 ms&lt;/td&gt;&lt;td&gt;12.020 ms&lt;/td&gt;&lt;td&gt;11.603 ms&lt;/td&gt;&lt;td&gt;12.469 ms&lt;/td&gt;&lt;td&gt;11.850 ms&lt;/td&gt;&lt;td&gt;11.823 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;6.093 ms&lt;/td&gt;&lt;td&gt;6.096 ms&lt;/td&gt;&lt;td&gt;6.130 ms&lt;/td&gt;&lt;td&gt;5.941 ms&lt;/td&gt;&lt;td&gt;5.882 ms&lt;/td&gt;&lt;td&gt;5.959 ms&lt;/td&gt;&lt;td&gt;6.789 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;1.431 ms&lt;/td&gt;&lt;td&gt;0.304 ms&lt;/td&gt;&lt;td&gt;0.201 ms&lt;/td&gt;&lt;td&gt;0.200 ms&lt;/td&gt;&lt;td&gt;0.201 ms&lt;/td&gt;&lt;td&gt;0.199 ms&lt;/td&gt;&lt;td&gt;0.199 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;79.019 ms&lt;/td&gt;&lt;td&gt;78.831 ms&lt;/td&gt;&lt;td&gt;78.514 ms&lt;/td&gt;&lt;td&gt;78.491 ms&lt;/td&gt;&lt;td&gt;79.423 ms&lt;/td&gt;&lt;td&gt;78.506 ms&lt;/td&gt;&lt;td&gt;78.759 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;19.173 ms&lt;/td&gt;&lt;td&gt;20.160 ms&lt;/td&gt;&lt;td&gt;19.373 ms&lt;/td&gt;&lt;td&gt;19.043 ms&lt;/td&gt;&lt;td&gt;18.992 ms&lt;/td&gt;&lt;td&gt;18.961 ms&lt;/td&gt;&lt;td&gt;19.207 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;0.422 ms&lt;/td&gt;&lt;td&gt;0.344 ms&lt;/td&gt;&lt;td&gt;0.339 ms&lt;/td&gt;&lt;td&gt;0.335 ms&lt;/td&gt;&lt;td&gt;0.336 ms&lt;/td&gt;&lt;td&gt;0.339 ms&lt;/td&gt;&lt;td&gt;0.345 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;title=The Matrix - 121,587 movies, 1 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;13.367 ms&lt;/td&gt;&lt;td&gt;13.395 ms&lt;/td&gt;&lt;td&gt;12.906 ms&lt;/td&gt;&lt;td&gt;13.164 ms&lt;/td&gt;&lt;td&gt;12.856 ms&lt;/td&gt;&lt;td&gt;13.348 ms&lt;/td&gt;&lt;td&gt;12.862 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;62.625 ms&lt;/td&gt;&lt;td&gt;61.341 ms&lt;/td&gt;&lt;td&gt;61.296 ms&lt;/td&gt;&lt;td&gt;61.361 ms&lt;/td&gt;&lt;td&gt;61.248 ms&lt;/td&gt;&lt;td&gt;61.195 ms&lt;/td&gt;&lt;td&gt;61.607 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;0.328 ms&lt;/td&gt;&lt;td&gt;0.312 ms&lt;/td&gt;&lt;td&gt;0.300 ms&lt;/td&gt;&lt;td&gt;0.303 ms&lt;/td&gt;&lt;td&gt;0.301 ms&lt;/td&gt;&lt;td&gt;7.473 ms&lt;/td&gt;&lt;td&gt;0.330 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;138.148 ms&lt;/td&gt;&lt;td&gt;131.762 ms&lt;/td&gt;&lt;td&gt;130.937 ms&lt;/td&gt;&lt;td&gt;131.431 ms&lt;/td&gt;&lt;td&gt;131.471 ms&lt;/td&gt;&lt;td&gt;130.975 ms&lt;/td&gt;&lt;td&gt;130.770 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;0.833 ms&lt;/td&gt;&lt;td&gt;0.681 ms&lt;/td&gt;&lt;td&gt;0.674 ms&lt;/td&gt;&lt;td&gt;0.687 ms&lt;/td&gt;&lt;td&gt;0.665 ms&lt;/td&gt;&lt;td&gt;0.667 ms&lt;/td&gt;&lt;td&gt;0.665 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;director=Quentin Tarantino - 9 movies, 1 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;9.112 ms&lt;/td&gt;&lt;td&gt;9.540 ms&lt;/td&gt;&lt;td&gt;9.671 ms&lt;/td&gt;&lt;td&gt;9.258 ms&lt;/td&gt;&lt;td&gt;9.510 ms&lt;/td&gt;&lt;td&gt;9.597 ms&lt;/td&gt;&lt;td&gt;9.126 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;0.273 ms&lt;/td&gt;&lt;td&gt;0.243 ms&lt;/td&gt;&lt;td&gt;0.243 ms&lt;/td&gt;&lt;td&gt;0.241 ms&lt;/td&gt;&lt;td&gt;0.239 ms&lt;/td&gt;&lt;td&gt;0.239 ms&lt;/td&gt;&lt;td&gt;0.239 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;0.282 ms&lt;/td&gt;&lt;td&gt;0.243 ms&lt;/td&gt;&lt;td&gt;0.257 ms&lt;/td&gt;&lt;td&gt;0.244 ms&lt;/td&gt;&lt;td&gt;0.245 ms&lt;/td&gt;&lt;td&gt;0.243 ms&lt;/td&gt;&lt;td&gt;0.337 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;0.810 ms&lt;/td&gt;&lt;td&gt;0.547 ms&lt;/td&gt;&lt;td&gt;0.542 ms&lt;/td&gt;&lt;td&gt;0.544 ms&lt;/td&gt;&lt;td&gt;0.541 ms&lt;/td&gt;&lt;td&gt;0.554 ms&lt;/td&gt;&lt;td&gt;0.567 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;0.606 ms&lt;/td&gt;&lt;td&gt;0.410 ms&lt;/td&gt;&lt;td&gt;0.398 ms&lt;/td&gt;&lt;td&gt;0.403 ms&lt;/td&gt;&lt;td&gt;0.383 ms&lt;/td&gt;&lt;td&gt;0.459 ms&lt;/td&gt;&lt;td&gt;0.392 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;0.215 ms&lt;/td&gt;&lt;td&gt;0.204 ms&lt;/td&gt;&lt;td&gt;0.195 ms&lt;/td&gt;&lt;td&gt;0.197 ms&lt;/td&gt;&lt;td&gt;0.195 ms&lt;/td&gt;&lt;td&gt;0.208 ms&lt;/td&gt;&lt;td&gt;0.194 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;director=Quentin Tarantino - 1,099 movies, 9 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;11.574 ms&lt;/td&gt;&lt;td&gt;12.063 ms&lt;/td&gt;&lt;td&gt;11.780 ms&lt;/td&gt;&lt;td&gt;12.169 ms&lt;/td&gt;&lt;td&gt;12.253 ms&lt;/td&gt;&lt;td&gt;11.801 ms&lt;/td&gt;&lt;td&gt;11.939 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;13.775 ms&lt;/td&gt;&lt;td&gt;8.831 ms&lt;/td&gt;&lt;td&gt;9.583 ms&lt;/td&gt;&lt;td&gt;9.506 ms&lt;/td&gt;&lt;td&gt;9.193 ms&lt;/td&gt;&lt;td&gt;9.154 ms&lt;/td&gt;&lt;td&gt;9.452 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;13.332 ms&lt;/td&gt;&lt;td&gt;8.963 ms&lt;/td&gt;&lt;td&gt;10.201 ms&lt;/td&gt;&lt;td&gt;9.064 ms&lt;/td&gt;&lt;td&gt;8.925 ms&lt;/td&gt;&lt;td&gt;10.095 ms&lt;/td&gt;&lt;td&gt;8.756 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;5.173 ms&lt;/td&gt;&lt;td&gt;4.644 ms&lt;/td&gt;&lt;td&gt;4.546 ms&lt;/td&gt;&lt;td&gt;4.473 ms&lt;/td&gt;&lt;td&gt;4.552 ms&lt;/td&gt;&lt;td&gt;4.472 ms&lt;/td&gt;&lt;td&gt;4.455 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;1.137 ms&lt;/td&gt;&lt;td&gt;0.857 ms&lt;/td&gt;&lt;td&gt;0.851 ms&lt;/td&gt;&lt;td&gt;0.855 ms&lt;/td&gt;&lt;td&gt;0.844 ms&lt;/td&gt;&lt;td&gt;0.842 ms&lt;/td&gt;&lt;td&gt;0.844 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;0.898 ms&lt;/td&gt;&lt;td&gt;0.878 ms&lt;/td&gt;&lt;td&gt;0.893 ms&lt;/td&gt;&lt;td&gt;0.873 ms&lt;/td&gt;&lt;td&gt;1.000 ms&lt;/td&gt;&lt;td&gt;0.882 ms&lt;/td&gt;&lt;td&gt;0.843 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;director=Quentin Tarantino - 3,216 movies, 10 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;12.343 ms&lt;/td&gt;&lt;td&gt;12.175 ms&lt;/td&gt;&lt;td&gt;12.307 ms&lt;/td&gt;&lt;td&gt;12.004 ms&lt;/td&gt;&lt;td&gt;12.235 ms&lt;/td&gt;&lt;td&gt;12.947 ms&lt;/td&gt;&lt;td&gt;12.194 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;40.967 ms&lt;/td&gt;&lt;td&gt;37.867 ms&lt;/td&gt;&lt;td&gt;38.607 ms&lt;/td&gt;&lt;td&gt;37.618 ms&lt;/td&gt;&lt;td&gt;37.487 ms&lt;/td&gt;&lt;td&gt;37.124 ms&lt;/td&gt;&lt;td&gt;38.147 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;43.470 ms&lt;/td&gt;&lt;td&gt;36.820 ms&lt;/td&gt;&lt;td&gt;37.027 ms&lt;/td&gt;&lt;td&gt;36.779 ms&lt;/td&gt;&lt;td&gt;36.957 ms&lt;/td&gt;&lt;td&gt;36.585 ms&lt;/td&gt;&lt;td&gt;36.782 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;13.707 ms&lt;/td&gt;&lt;td&gt;13.074 ms&lt;/td&gt;&lt;td&gt;12.763 ms&lt;/td&gt;&lt;td&gt;12.740 ms&lt;/td&gt;&lt;td&gt;12.848 ms&lt;/td&gt;&lt;td&gt;12.779 ms&lt;/td&gt;&lt;td&gt;12.855 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;2.015 ms&lt;/td&gt;&lt;td&gt;1.559 ms&lt;/td&gt;&lt;td&gt;1.531 ms&lt;/td&gt;&lt;td&gt;1.525 ms&lt;/td&gt;&lt;td&gt;1.530 ms&lt;/td&gt;&lt;td&gt;1.545 ms&lt;/td&gt;&lt;td&gt;1.511 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;0.933 ms&lt;/td&gt;&lt;td&gt;0.886 ms&lt;/td&gt;&lt;td&gt;0.908 ms&lt;/td&gt;&lt;td&gt;2.944 ms&lt;/td&gt;&lt;td&gt;1.023 ms&lt;/td&gt;&lt;td&gt;1.030 ms&lt;/td&gt;&lt;td&gt;0.799 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;director=Quentin Tarantino - 17,251 movies, 13 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;13.704 ms&lt;/td&gt;&lt;td&gt;14.413 ms&lt;/td&gt;&lt;td&gt;14.331 ms&lt;/td&gt;&lt;td&gt;15.096 ms&lt;/td&gt;&lt;td&gt;14.026 ms&lt;/td&gt;&lt;td&gt;14.492 ms&lt;/td&gt;&lt;td&gt;14.205 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;307.961 ms&lt;/td&gt;&lt;td&gt;308.146 ms&lt;/td&gt;&lt;td&gt;308.565 ms&lt;/td&gt;&lt;td&gt;307.942 ms&lt;/td&gt;&lt;td&gt;308.342 ms&lt;/td&gt;&lt;td&gt;308.387 ms&lt;/td&gt;&lt;td&gt;308.991 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;308.011 ms&lt;/td&gt;&lt;td&gt;305.433 ms&lt;/td&gt;&lt;td&gt;305.347 ms&lt;/td&gt;&lt;td&gt;304.567 ms&lt;/td&gt;&lt;td&gt;304.920 ms&lt;/td&gt;&lt;td&gt;305.567 ms&lt;/td&gt;&lt;td&gt;304.404 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;72.690 ms&lt;/td&gt;&lt;td&gt;72.075 ms&lt;/td&gt;&lt;td&gt;72.005 ms&lt;/td&gt;&lt;td&gt;71.999 ms&lt;/td&gt;&lt;td&gt;71.938 ms&lt;/td&gt;&lt;td&gt;71.946 ms&lt;/td&gt;&lt;td&gt;72.108 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;7.489 ms&lt;/td&gt;&lt;td&gt;6.996 ms&lt;/td&gt;&lt;td&gt;6.877 ms&lt;/td&gt;&lt;td&gt;6.987 ms&lt;/td&gt;&lt;td&gt;7.148 ms&lt;/td&gt;&lt;td&gt;7.088 ms&lt;/td&gt;&lt;td&gt;7.021 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;1.087 ms&lt;/td&gt;&lt;td&gt;0.963 ms&lt;/td&gt;&lt;td&gt;1.010 ms&lt;/td&gt;&lt;td&gt;1.151 ms&lt;/td&gt;&lt;td&gt;1.088 ms&lt;/td&gt;&lt;td&gt;0.965 ms&lt;/td&gt;&lt;td&gt;0.959 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;director=Quentin Tarantino - 121,587 movies, 14 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;13.546 ms&lt;/td&gt;&lt;td&gt;13.955 ms&lt;/td&gt;&lt;td&gt;13.981 ms&lt;/td&gt;&lt;td&gt;13.854 ms&lt;/td&gt;&lt;td&gt;13.740 ms&lt;/td&gt;&lt;td&gt;14.114 ms&lt;/td&gt;&lt;td&gt;15.816 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;4,752.853 ms&lt;/td&gt;&lt;td&gt;2,793.690 ms&lt;/td&gt;&lt;td&gt;2,800.197 ms&lt;/td&gt;&lt;td&gt;2,795.611 ms&lt;/td&gt;&lt;td&gt;2,800.578 ms&lt;/td&gt;&lt;td&gt;2,794.765 ms&lt;/td&gt;&lt;td&gt;2,801.000 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;2,806.890 ms&lt;/td&gt;&lt;td&gt;2,789.648 ms&lt;/td&gt;&lt;td&gt;2,788.729 ms&lt;/td&gt;&lt;td&gt;2,791.168 ms&lt;/td&gt;&lt;td&gt;2,788.102 ms&lt;/td&gt;&lt;td&gt;2,790.845 ms&lt;/td&gt;&lt;td&gt;2,789.475 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;47.801 ms&lt;/td&gt;&lt;td&gt;46.303 ms&lt;/td&gt;&lt;td&gt;46.701 ms&lt;/td&gt;&lt;td&gt;46.640 ms&lt;/td&gt;&lt;td&gt;46.467 ms&lt;/td&gt;&lt;td&gt;46.862 ms&lt;/td&gt;&lt;td&gt;46.448 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;20.098 ms&lt;/td&gt;&lt;td&gt;1.260 ms&lt;/td&gt;&lt;td&gt;1.176 ms&lt;/td&gt;&lt;td&gt;1.162 ms&lt;/td&gt;&lt;td&gt;1.156 ms&lt;/td&gt;&lt;td&gt;1.149 ms&lt;/td&gt;&lt;td&gt;1.148 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;T* - 9 movies, 9 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;17.303 ms&lt;/td&gt;&lt;td&gt;17.072 ms&lt;/td&gt;&lt;td&gt;16.927 ms&lt;/td&gt;&lt;td&gt;16.539 ms&lt;/td&gt;&lt;td&gt;16.816 ms&lt;/td&gt;&lt;td&gt;16.758 ms&lt;/td&gt;&lt;td&gt;16.797 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;0.547 ms&lt;/td&gt;&lt;td&gt;0.544 ms&lt;/td&gt;&lt;td&gt;0.547 ms&lt;/td&gt;&lt;td&gt;0.541 ms&lt;/td&gt;&lt;td&gt;0.541 ms&lt;/td&gt;&lt;td&gt;0.546 ms&lt;/td&gt;&lt;td&gt;0.544 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;0.553 ms&lt;/td&gt;&lt;td&gt;0.549 ms&lt;/td&gt;&lt;td&gt;0.554 ms&lt;/td&gt;&lt;td&gt;0.553 ms&lt;/td&gt;&lt;td&gt;0.658 ms&lt;/td&gt;&lt;td&gt;0.547 ms&lt;/td&gt;&lt;td&gt;0.544 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;2.525 ms&lt;/td&gt;&lt;td&gt;2.302 ms&lt;/td&gt;&lt;td&gt;2.423 ms&lt;/td&gt;&lt;td&gt;2.415 ms&lt;/td&gt;&lt;td&gt;2.372 ms&lt;/td&gt;&lt;td&gt;2.356 ms&lt;/td&gt;&lt;td&gt;2.305 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;3.086 ms&lt;/td&gt;&lt;td&gt;2.871 ms&lt;/td&gt;&lt;td&gt;2.947 ms&lt;/td&gt;&lt;td&gt;2.893 ms&lt;/td&gt;&lt;td&gt;3.104 ms&lt;/td&gt;&lt;td&gt;3.022 ms&lt;/td&gt;&lt;td&gt;3.126 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;T* - 1,099 movies, 1,098 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;358.775 ms&lt;/td&gt;&lt;td&gt;355.830 ms&lt;/td&gt;&lt;td&gt;350.287 ms&lt;/td&gt;&lt;td&gt;349.816 ms&lt;/td&gt;&lt;td&gt;347.998 ms&lt;/td&gt;&lt;td&gt;356.585 ms&lt;/td&gt;&lt;td&gt;347.143 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;64.679 ms&lt;/td&gt;&lt;td&gt;142.927 ms&lt;/td&gt;&lt;td&gt;143.776 ms&lt;/td&gt;&lt;td&gt;142.847 ms&lt;/td&gt;&lt;td&gt;145.319 ms&lt;/td&gt;&lt;td&gt;147.244 ms&lt;/td&gt;&lt;td&gt;135.600 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;62.383 ms&lt;/td&gt;&lt;td&gt;151.941 ms&lt;/td&gt;&lt;td&gt;144.456 ms&lt;/td&gt;&lt;td&gt;144.108 ms&lt;/td&gt;&lt;td&gt;141.330 ms&lt;/td&gt;&lt;td&gt;173.728 ms&lt;/td&gt;&lt;td&gt;169.799 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;199.108 ms&lt;/td&gt;&lt;td&gt;213.355 ms&lt;/td&gt;&lt;td&gt;202.793 ms&lt;/td&gt;&lt;td&gt;196.659 ms&lt;/td&gt;&lt;td&gt;194.937 ms&lt;/td&gt;&lt;td&gt;194.708 ms&lt;/td&gt;&lt;td&gt;195.267 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;419.323 ms&lt;/td&gt;&lt;td&gt;516.929 ms&lt;/td&gt;&lt;td&gt;677.357 ms&lt;/td&gt;&lt;td&gt;591.280 ms&lt;/td&gt;&lt;td&gt;599.091 ms&lt;/td&gt;&lt;td&gt;643.124 ms&lt;/td&gt;&lt;td&gt;497.649 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;T* - 3,216 movies, 3,204 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;842.413 ms&lt;/td&gt;&lt;td&gt;968.828 ms&lt;/td&gt;&lt;td&gt;958.367 ms&lt;/td&gt;&lt;td&gt;1,002.383 ms&lt;/td&gt;&lt;td&gt;932.222 ms&lt;/td&gt;&lt;td&gt;946.388 ms&lt;/td&gt;&lt;td&gt;1,004.821 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;327.669 ms&lt;/td&gt;&lt;td&gt;415.921 ms&lt;/td&gt;&lt;td&gt;440.198 ms&lt;/td&gt;&lt;td&gt;408.543 ms&lt;/td&gt;&lt;td&gt;432.575 ms&lt;/td&gt;&lt;td&gt;537.572 ms&lt;/td&gt;&lt;td&gt;412.061 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;310.218 ms&lt;/td&gt;&lt;td&gt;432.201 ms&lt;/td&gt;&lt;td&gt;413.221 ms&lt;/td&gt;&lt;td&gt;404.165 ms&lt;/td&gt;&lt;td&gt;479.691 ms&lt;/td&gt;&lt;td&gt;431.758 ms&lt;/td&gt;&lt;td&gt;436.533 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;727.867 ms&lt;/td&gt;&lt;td&gt;711.970 ms&lt;/td&gt;&lt;td&gt;722.046 ms&lt;/td&gt;&lt;td&gt;717.685 ms&lt;/td&gt;&lt;td&gt;719.927 ms&lt;/td&gt;&lt;td&gt;713.077 ms&lt;/td&gt;&lt;td&gt;713.843 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;1,442.238 ms&lt;/td&gt;&lt;td&gt;1,470.821 ms&lt;/td&gt;&lt;td&gt;1,415.183 ms&lt;/td&gt;&lt;td&gt;1,392.164 ms&lt;/td&gt;&lt;td&gt;1,437.493 ms&lt;/td&gt;&lt;td&gt;1,464.149 ms&lt;/td&gt;&lt;td&gt;1,520.747 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;T* - 17,251 movies, ≥ 10,000 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;3,006.139 ms&lt;/td&gt;&lt;td&gt;3,127.174 ms&lt;/td&gt;&lt;td&gt;3,136.617 ms&lt;/td&gt;&lt;td&gt;3,151.197 ms&lt;/td&gt;&lt;td&gt;3,131.469 ms&lt;/td&gt;&lt;td&gt;3,141.155 ms&lt;/td&gt;&lt;td&gt;3,056.497 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;1,481.321 ms&lt;/td&gt;&lt;td&gt;1,388.573 ms&lt;/td&gt;&lt;td&gt;1,468.062 ms&lt;/td&gt;&lt;td&gt;1,533.263 ms&lt;/td&gt;&lt;td&gt;1,422.012 ms&lt;/td&gt;&lt;td&gt;1,442.638 ms&lt;/td&gt;&lt;td&gt;1,456.166 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;1,346.717 ms&lt;/td&gt;&lt;td&gt;1,451.410 ms&lt;/td&gt;&lt;td&gt;1,508.228 ms&lt;/td&gt;&lt;td&gt;1,411.643 ms&lt;/td&gt;&lt;td&gt;1,460.563 ms&lt;/td&gt;&lt;td&gt;1,514.390 ms&lt;/td&gt;&lt;td&gt;1,391.342 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;2,945.536 ms&lt;/td&gt;&lt;td&gt;2,938.230 ms&lt;/td&gt;&lt;td&gt;2,957.149 ms&lt;/td&gt;&lt;td&gt;2,959.569 ms&lt;/td&gt;&lt;td&gt;2,972.291 ms&lt;/td&gt;&lt;td&gt;2,933.668 ms&lt;/td&gt;&lt;td&gt;2,936.655 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;3,391.825 ms&lt;/td&gt;&lt;td&gt;3,490.307 ms&lt;/td&gt;&lt;td&gt;3,474.203 ms&lt;/td&gt;&lt;td&gt;3,483.310 ms&lt;/td&gt;&lt;td&gt;3,560.886 ms&lt;/td&gt;&lt;td&gt;3,505.060 ms&lt;/td&gt;&lt;td&gt;3,398.937 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
 &lt;tbody&gt;&lt;tr class=&quot;group separator&quot;&gt;&lt;td colspan=&quot;8&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
 &lt;tbody&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th colspan=&quot;7&quot;&gt;T* - 121,587 movies, ≥ 10,000 matches&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;1&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;2&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;3&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;4&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;5&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/th&gt;&lt;th&gt;t&lt;sub&gt;7&lt;/sub&gt;&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;bm_lucene++&lt;/th&gt;&lt;td&gt;3,627.408 ms&lt;/td&gt;&lt;td&gt;3,625.588 ms&lt;/td&gt;&lt;td&gt;3,546.610 ms&lt;/td&gt;&lt;td&gt;3,508.233 ms&lt;/td&gt;&lt;td&gt;3,599.160 ms&lt;/td&gt;&lt;td&gt;4,597.857 ms&lt;/td&gt;&lt;td&gt;4,101.686 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite&lt;/th&gt;&lt;td&gt;2,182.548 ms&lt;/td&gt;&lt;td&gt;2,109.730 ms&lt;/td&gt;&lt;td&gt;2,109.812 ms&lt;/td&gt;&lt;td&gt;2,121.573 ms&lt;/td&gt;&lt;td&gt;2,104.320 ms&lt;/td&gt;&lt;td&gt;2,117.912 ms&lt;/td&gt;&lt;td&gt;2,145.342 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_sqlite_index&lt;/th&gt;&lt;td&gt;2,108.863 ms&lt;/td&gt;&lt;td&gt;2,103.648 ms&lt;/td&gt;&lt;td&gt;2,131.009 ms&lt;/td&gt;&lt;td&gt;2,132.823 ms&lt;/td&gt;&lt;td&gt;2,109.655 ms&lt;/td&gt;&lt;td&gt;2,137.286 ms&lt;/td&gt;&lt;td&gt;2,106.779 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker&lt;/th&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_tracker_flat&lt;/th&gt;&lt;td&gt;8,757.130 ms&lt;/td&gt;&lt;td&gt;9,316.640 ms&lt;/td&gt;&lt;td&gt;8,708.298 ms&lt;/td&gt;&lt;td&gt;8,781.584 ms&lt;/td&gt;&lt;td&gt;8,788.042 ms&lt;/td&gt;&lt;td&gt;8,699.770 ms&lt;/td&gt;&lt;td&gt;8,721.099 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;bm_xapian&lt;/th&gt;&lt;td&gt;4,805.474 ms&lt;/td&gt;&lt;td&gt;4,528.004 ms&lt;/td&gt;&lt;td&gt;4,692.763 ms&lt;/td&gt;&lt;td&gt;4,640.065 ms&lt;/td&gt;&lt;td&gt;4,618.215 ms&lt;/td&gt;&lt;td&gt;4,647.170 ms&lt;/td&gt;&lt;td&gt;4,674.588 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;</description>
	<pubDate>Wed, 25 Apr 2012 07:48:45 +0000</pubDate>
</item>
<item>
	<title>Mathias Hasselmann: Full Text Search Engines, Part I</title>
	<guid>http://taschenorakel.de/mathias/2012/04/18/fulltext-search-benchmarks/</guid>
	<link>http://taschenorakel.de/mathias/2012/04/18/fulltext-search-benchmarks/</link>
	<description>&lt;p&gt;&lt;a href=&quot;http://openismus.com/&quot;&gt;Openismus&lt;/a&gt; asked me to research how best to index media files and
provide full text searching. For the last two years, I have used
&lt;a href=&quot;http://projects.gnome.org/tracker/&quot;&gt;Tracker&lt;/a&gt; for this kind of thing. I like Tracker, but I want to avoid
being biased. Therefore, I decided to evaluate alternatives.&lt;/p&gt;
&lt;p&gt;Performance is an obvious requirement. We also want to provide a library to
permit other applications to access the data we collected. Therefore,
&lt;a href=&quot;http://sqlite.org/&quot;&gt;SQLite&lt;/a&gt; and &lt;a href=&quot;http://lucene.apache.org/&quot;&gt;Lucene&lt;/a&gt; (in its C++ incarnations) are
obvious contenders. &lt;a href=&quot;http://lucene.apache.org/&quot;&gt;Lucene++&lt;/a&gt; is an emerging project that got
suggested by &lt;a href=&quot;http://www.grillbar.org/&quot;&gt;Mikkel Kamstrup Erlandsen&lt;/a&gt; at Canonical.
&lt;a href=&quot;https://qt.gitorious.org/qt/qt/trees/4.8/tools/assistant/lib/fulltextsearch&quot;&gt;QtCLucene&lt;/a&gt; is a bit special: So far Qt doesn't provide official
support for this library and doesn't install its headers files. Still it is
used by Qt's help system, which makes QtCLucene a widely deployed and well
tested C++ implementation of Lucene.&lt;/p&gt;
&lt;p&gt;Sadly, the big names like &lt;a href=&quot;http://mysql.com/&quot;&gt;MySQL&lt;/a&gt; or &lt;a href=&quot;http://postgresql.org/&quot;&gt;PostgreSQL&lt;/a&gt; do not fit:
MySQL's embedded server library is licensed under GPL (instead of LGPL, for
instance), which greatly limits legal use cases. PostgreSQL doesn't provide any
embedding at all. Because I enjoy RDF and &lt;a href=&quot;http://en.wikipedia.org/wiki/SPARQL&quot;&gt;SPARQL&lt;/a&gt; I also wondered
about testing the &lt;a href=&quot;http://librdf.org/&quot;&gt;Redland RDF&lt;/a&gt; libraries, but I found that they don't
provide any full text search at all.&lt;/p&gt;
&lt;h3&gt;Contenders&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://projects.gnome.org/tracker/&quot;&gt;Tracker&lt;/a&gt; 0.14.0-2ubuntu1&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://sqlite.org/&quot;&gt;SQLite&lt;/a&gt; 3.7.9-2ubuntu1&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ustramooner/LucenePlusPlus&quot;&gt;Lucene++&lt;/a&gt; 3.0.3.4 (e28b15b02ff9de2208965e9af8eb80983380cdcd)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://qt.gitorious.org/qt/qt/trees/4.8/tools/assistant/lib/fulltextsearch&quot;&gt;QtCLucene&lt;/a&gt; as provided by libqtcore4 4.8.1-0ubuntu4&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://xapian.org/&quot;&gt;Xapian&lt;/a&gt; 1.2.8-1&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Test Platform&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Ubuntu 12.04&lt;/li&gt;
&lt;li&gt;Intel Core 2 Duo P8400 (2.26GHz), 4 GiB RAM&lt;/li&gt;
&lt;li&gt;HDD: WDC WD2500BEVT-2, encrypted (aes-cbc-essiv:sha256)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Test Scenario&lt;/h3&gt;
&lt;p&gt;To get somewhat realistic data I've fetched a copy of the &lt;a href=&quot;http://imdb.com/&quot;&gt;Internet Movie Database&lt;/a&gt;
from &lt;a href=&quot;ftp://ftp.fu-berlin.de/pub/misc/movies/database/&quot;&gt;ftp.fu-berlin.de&lt;/a&gt;.
Since it is a quite huge database (about 1 GiB when compressed with gzip) I've
extracted a few subsets of it: All movies with at least 500,000, 50,000, 15,000
1,000 and 50 user votes. This data then got imported into a fresh instance of
Tracker, SQLite, Lucene++ and QtCLucene. After that I've run a few trivial
full text searches:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;The Matrix&quot;
Fast Furious
&quot;Star Trek&quot; OR &quot;Star Wars&quot;
Lord Rings King
Keanu Reeves
&quot;Brad Pitt&quot; OR &quot;Bruce Willis&quot;
Jackson Samuel
Quentin Tarantino
Wachowski
Thomas Neo Anderson
Neo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each scenario was repeated five times. To avoid cache effects each engine was
tested after the others for a given set of parameters. Tracker was tested with
two different scenarios: First I've tried the Nepomuk based multimedia ontology
shipped with Tracker (&lt;a href=&quot;http://git.gnome.org/browse/tracker/tree/data/ontologies/38-nmm.ontology?id=0.14.0&quot;&gt;nmm&lt;/a&gt;), after that I've also tried a flattened ontology
(&lt;a href=&quot;https://gitorious.org/openismus-playground/fts-benchmark/blobs/releases/0.2/src/99-fmm.ontology&quot;&gt;fmm&lt;/a&gt;) which is a much better fit for the data model of pure full text
search indices like Lucene. All engines where used with default parameters. No
magic configuration options or pragmas were applied. Feel free to repeat the
tests with your own optimized settings, and report the results when doing so.&lt;/p&gt;
&lt;h3&gt;Source Code and Data&lt;/h3&gt;
&lt;p&gt;The source code of these benchmarks can be found at &lt;a href=&quot;https://gitorious.org/openismus-playground/fts-benchmark&quot;&gt;Gitorious&lt;/a&gt;,
and can be built using autotools or qmake. Just like you prefer.&lt;/p&gt;
&lt;p&gt;Run &lt;a href=&quot;https://gitorious.org/openismus-playground/fts-benchmark/blobs/releases/0.2/src/benchmark.sh&quot;&gt;src/benchmark.sh&lt;/a&gt;
to reproduce the tests. The &lt;a href=&quot;https://gitorious.org/openismus-playground/fts-benchmark/trees/releases/0.2/logs&quot;&gt;log files&lt;/a&gt;
can be turned into a &lt;a href=&quot;https://gitorious.org/openismus-playground/fts-benchmark/blobs/releases/0.2/logs/report.csv&quot;&gt;CSV file&lt;/a&gt;
by running &lt;a href=&quot;https://gitorious.org/openismus-playground/fts-benchmark/blobs/releases/0.2/src/report.sh&quot;&gt;src/report.sh&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The charts have been created with LibreOffice:
It should be sufficient to copy the CSV data into the data sheet of
&lt;a href=&quot;https://gitorious.org/openismus-playground/fts-benchmark/blobs/releases/0.2/logs/report.ods&quot;&gt;logs/report.ods&lt;/a&gt;.
Select &quot;English (USA)&quot; as language in the import dialog, to ensure that
numbers are recognized properly. After that you still might have to sort
the rows by the columns &lt;code&gt;suite&lt;/code&gt;, &lt;code&gt;num_movies&lt;/code&gt; and &lt;code&gt;experiment&lt;/code&gt;. The data
sorting dialog provides an option for marking the first row as column header.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I've pushed some more changes, so to exactly reproduce the results
discussed in this post, checkout the tags &lt;a href=&quot;http://gitorious.org/openismus-playground/fts-benchmark/trees/releases/0.1&quot;&gt;&lt;code&gt;releases/0.1&lt;/code&gt;&lt;/a&gt; for the
initial results, and &lt;a href=&quot;http://gitorious.org/openismus-playground/fts-benchmark/trees/releases/0.2&quot;&gt;&lt;code&gt;releases/0.2&lt;/code&gt;&lt;/a&gt; to also include Xapian tests.&lt;/p&gt;
&lt;h3&gt;Results&lt;/h3&gt;
&lt;p&gt;&lt;img alt=&quot;Populating the Index&quot; src=&quot;http://taschenorakel.de/files/fts-benchmark/fts-chart1.png&quot; /&gt;&lt;/p&gt;
&lt;table class=&quot;results&quot;&gt;
 &lt;colgroup&gt;
  &lt;col width=&quot;*&quot; /&gt;
  &lt;col width=&quot;15%&quot; /&gt;
  &lt;col width=&quot;15%&quot; /&gt;
  &lt;col width=&quot;15%&quot; /&gt;
  &lt;col width=&quot;15%&quot; /&gt;
  &lt;col width=&quot;15%&quot; /&gt;
  &lt;col width=&quot;15%&quot; /&gt;
 &lt;/colgroup&gt;
 &lt;tbody&gt;
  &lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Lucene++&lt;/th&gt;&lt;th&gt;QtCLucene&lt;/th&gt;&lt;th&gt;SQLite&lt;/th&gt;&lt;th&gt;Tracker (Nepomuk)&lt;/th&gt;&lt;th&gt;Tracker (Flat)&lt;/th&gt;&lt;th&gt;Xapian&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;9&lt;/th&gt;&lt;td&gt;6.84 ms&lt;/td&gt;&lt;td&gt;3.46 ms&lt;/td&gt;&lt;td&gt;&lt;i&gt;43.2 ms&lt;/i&gt;&lt;a href=&quot;http://taschenorakel.de/rss/mathias/#note1&quot;&gt;¹⁾&lt;/a&gt;&lt;/td&gt;&lt;td&gt;36.2 ms&lt;/td&gt;&lt;td&gt;7.13 ms&lt;/td&gt;&lt;td&gt;52.561 ms&lt;a href=&quot;http://taschenorakel.de/rss/mathias/#note1&quot;&gt;¹⁾&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;1,099&lt;/th&gt;&lt;td&gt;2.93 ms&lt;/td&gt;&lt;td&gt;5.72 ms&lt;/td&gt;&lt;td&gt;3.63 ms&lt;/td&gt;&lt;td&gt;26.4 ms&lt;/td&gt;&lt;td&gt;3.32 ms&lt;/td&gt;&lt;td&gt;5.94 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;3,216&lt;/th&gt;&lt;td&gt;2.32 ms&lt;/td&gt;&lt;td&gt;5.37 ms&lt;/td&gt;&lt;td&gt;2.87 ms&lt;/td&gt;&lt;td&gt;21.2 ms&lt;/td&gt;&lt;td&gt;2.89 ms&lt;/td&gt;&lt;td&gt;4.97 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;17,251&lt;/th&gt;&lt;td&gt;1.98 ms&lt;/td&gt;&lt;td&gt;5.10 ms&lt;/td&gt;&lt;td&gt;2.50 ms&lt;/td&gt;&lt;td&gt;14.2 ms&lt;/td&gt;&lt;td&gt;2.19 ms&lt;/td&gt;&lt;td&gt;3.58 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;121,587&lt;/th&gt;&lt;td&gt;1.21 ms&lt;/td&gt;&lt;td&gt;5.21 ms&lt;/td&gt;&lt;td&gt;&lt;i&gt;3.96 ms&lt;/i&gt;&lt;a href=&quot;http://taschenorakel.de/rss/mathias/#note2&quot;&gt;²⁾&lt;/a&gt;&lt;/td&gt;&lt;td&gt;10.4 ms&lt;/td&gt;&lt;td&gt;1.80 ms&lt;/td&gt;&lt;td&gt;2.30 ms&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a name=&quot;note1&quot;&gt;&lt;/a&gt;The dataset is tiny. I suspect that some startup overhead is invalidating this result.&lt;/li&gt;
&lt;li&gt;&lt;a name=&quot;note2&quot;&gt;&lt;/a&gt;We might see first signs of a memory barrier here.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt=&quot;Query Execution Time&quot; src=&quot;http://taschenorakel.de/files/fts-benchmark/fts-chart2.png&quot; /&gt;&lt;/p&gt;
&lt;table class=&quot;results&quot;&gt;
 &lt;colgroup&gt;
  &lt;col width=&quot;*&quot; /&gt;
  &lt;col width=&quot;15%&quot; /&gt;
  &lt;col width=&quot;15%&quot; /&gt;
  &lt;col width=&quot;15%&quot; /&gt;
  &lt;col width=&quot;15%&quot; /&gt;
  &lt;col width=&quot;15%&quot; /&gt;
  &lt;col width=&quot;15%&quot; /&gt;
 &lt;/colgroup&gt;
 &lt;tbody&gt;
  &lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Lucene++&lt;/th&gt;&lt;th&gt;QtCLucene&lt;/th&gt;&lt;th&gt;SQLite&lt;/th&gt;&lt;th&gt;Tracker (Nepomuk)&lt;/th&gt;&lt;th&gt;Tracker (Flat)&lt;/th&gt;&lt;th&gt;Xapian&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;9&lt;/th&gt;&lt;td&gt;2.23 ms&lt;/td&gt;&lt;td&gt;0.572 ms&lt;/td&gt;&lt;td&gt;0.159 ms&lt;/td&gt;&lt;td&gt;1.33 ms&lt;/td&gt;&lt;td&gt;0.494 ms&lt;/td&gt;&lt;td&gt;0.271 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;1,099&lt;/th&gt;&lt;td&gt;6.06 ms&lt;/td&gt;&lt;td&gt;2.18 ms&lt;/td&gt;&lt;td&gt;1.17 ms&lt;/td&gt;&lt;td&gt;90.3 ms&lt;/td&gt;&lt;td&gt;1.67 ms&lt;/td&gt;&lt;td&gt;0.955 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;3,216&lt;/th&gt;&lt;td&gt;8.72 ms&lt;/td&gt;&lt;td&gt;3.41 ms&lt;/td&gt;&lt;td&gt;1.55 ms&lt;/td&gt;&lt;td&gt;335 ms&lt;/td&gt;&lt;td&gt;3.57 ms&lt;/td&gt;&lt;td&gt;1.50 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;17,251&lt;/th&gt;&lt;td&gt;13.1 ms&lt;/td&gt;&lt;td&gt;5.33 ms&lt;/td&gt;&lt;td&gt;1.92 ms&lt;/td&gt;&lt;td&gt;2,380 ms&lt;/td&gt;&lt;td&gt;7.52 ms&lt;/td&gt;&lt;td&gt;2.35 ms&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;121,587&lt;/th&gt;&lt;td&gt;17.0 ms&lt;/td&gt;&lt;td&gt;&lt;i&gt;44.2 ms&lt;/i&gt;&lt;/td&gt;&lt;td&gt;&lt;i&gt;17.4 ms&lt;/i&gt;&lt;/td&gt;&lt;td&gt;&lt;i&gt;86,800 ms&lt;/i&gt;&lt;/td&gt;&lt;td&gt;19.885 ms&lt;/td&gt;&lt;td&gt;&lt;i&gt;18.1 ms&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;Complexity&lt;/th&gt;&lt;td&gt;O(log(n)²)&lt;/td&gt;&lt;td&gt;O(log(n)²)&lt;/td&gt;&lt;td&gt;O(log(n)²)&lt;/td&gt;&lt;td&gt;O(n log(n))&lt;/td&gt;&lt;td&gt;O(sqrt(n))&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;td&gt;O(log(n)²)&lt;/td&gt;
 


&lt;p&gt;QtCLucene, SQLite, Tracker (Nepomuk) and Xapian seem to hit a memory barrier at 121,587 movies.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Consumed Disk Space&quot; src=&quot;http://taschenorakel.de/files/fts-benchmark/fts-chart3.png&quot; /&gt;&lt;/p&gt;
&lt;table class=&quot;results&quot;&gt;
 &lt;colgroup&gt;
  &lt;col width=&quot;*&quot; /&gt;
  &lt;col width=&quot;13%&quot; /&gt;
  &lt;col width=&quot;13%&quot; /&gt;
  &lt;col width=&quot;13%&quot; /&gt;
  &lt;col width=&quot;13%&quot; /&gt;
  &lt;col width=&quot;13%&quot; /&gt;
  &lt;col width=&quot;13%&quot; /&gt;
  &lt;col width=&quot;13%&quot; /&gt;
 &lt;/colgroup&gt;
 &lt;tbody&gt;
  &lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Lucene++&lt;/th&gt;&lt;th&gt;QtCLucene&lt;/th&gt;&lt;th&gt;SQLite&lt;/th&gt;&lt;th&gt;Tracker (Nepomuk)&lt;/th&gt;&lt;th&gt;Tracker (Flat)&lt;/th&gt;&lt;th&gt;Xapian&lt;/th&gt;&lt;th&gt;Raw Data&lt;/th&gt;&lt;/tr&gt;
  &lt;tr class=&quot;group&quot;&gt;&lt;th&gt;9&lt;/th&gt;&lt;td&gt;80 KiB&lt;/td&gt;&lt;td&gt;76 KiB&lt;/td&gt;&lt;td&gt;368 KiB&lt;/td&gt;&lt;td&gt;4.4 MiB&lt;/td&gt;&lt;td&gt;2.3 MiB&lt;/td&gt;&lt;td&gt;424 KiB&lt;/td&gt;&lt;td&gt;104 KiB&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;1,099&lt;/th&gt;&lt;td&gt;4.9 MiB&lt;/td&gt;&lt;td&gt;4.8 MiB&lt;/td&gt;&lt;td&gt;32 MiB&lt;/td&gt;&lt;td&gt;59 MiB&lt;/td&gt;&lt;td&gt;29 MiB&lt;/td&gt;&lt;td&gt;21 MiB&lt;/td&gt;&lt;td&gt;7.8 MiB&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;3,216&lt;/th&gt;&lt;td&gt;12 MiB&lt;/td&gt;&lt;td&gt;12 MiB&lt;/td&gt;&lt;td&gt;75 MiB&lt;/td&gt;&lt;td&gt;114 MiB&lt;/td&gt;&lt;td&gt;53 MiB&lt;/td&gt;&lt;td&gt;47 MiB&lt;/td&gt;&lt;td&gt;18 MiB&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;17,251&lt;/th&gt;&lt;td&gt;39 MiB&lt;/td&gt;&lt;td&gt;39 MiB&lt;/td&gt;&lt;td&gt;257 MiB&lt;/td&gt;&lt;td&gt;305 MiB&lt;/td&gt;&lt;td&gt;155 MiB&lt;/td&gt;&lt;td&gt;170 MiB&lt;/td&gt;&lt;td&gt;57 MiB&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;th&gt;121,587&lt;/th&gt;&lt;td&gt;154 MiB&lt;/td&gt;&lt;td&gt;154 MiB&lt;/td&gt;&lt;td&gt;1.0 GiB&lt;/td&gt;&lt;td&gt;906 MiB&lt;/td&gt;&lt;td&gt;521 MiB&lt;/td&gt;&lt;td&gt;683 MiB&lt;/td&gt;&lt;td&gt;198 MiB&lt;/td&gt;&lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3&gt;Discussion&lt;/h3&gt;
&lt;p&gt;The performance of Tracker is devastating. Entirely not the result you want to
see for a project you actually like and enjoy using. You clearly see the bad
impact of the many joins it must perform for mapping the ontologies and queries
to SQL. This is surprising since in my opinion Nepomuk's multimedia ontology is
a quite typical ontology. Also the datasets itself are not that huge for
something that initially started as file indexer. The (sadly quite unrealistic)
flat ontology might give a few hints on how to improve Tracker. The execution
times with this ontology are comparable with them of the other engines. Still
the observed (and only estimated) complexity class for executing queries is
worrying.&lt;/p&gt;
&lt;p&gt;Lucene++ shines at writing data, it is just incredibly fast when building its
index. In contrast to the other engines it even spends less time per movie, the
bigger its index grows. It is noticable slower than QtCLucene or SQLite when
looking up terms. Still I'd call an average time of 17 ms for finding matches
within 122k documents a quite good achievement. Additionally Lucene++ seems to
be implemented sufficiently efficient to &lt;em&gt;not hit any memory barrier&lt;/em&gt; yet at
this scale.&lt;/p&gt;
&lt;p&gt;QtCLucene is about two times slower than Lucene++ or SQLite when building its
index, still the index size doesn't seem to impact insertion time per movie.
It pays back with good lookup performance. It is about 2 to 3 times faster
than Lucene++. It seems to hit a memory barrier at 122k documents.&lt;/p&gt;
&lt;p&gt;SQLite's performance is just in the middle between Lucene++ and QtCLucene when
building the index. When searching terms it even beats QtCLucene, again by a
factor of 2 to 3.&lt;/p&gt;
&lt;p&gt;Lucene++ and QtCLucene consume less disk space than the original files, most
probably because the raw data stores movies and artists in separate files. The
records in this files must be linked with each other. Lucene just does this
more efficiently. SQLite and Tracker consume significantly more disk space than
Lucene or the original data. Partly this can be explained by fields being
stored twice: Once in their table and another time in the full text search
index. Column indexes also play a role. Still this doesn't explain why disk
consumption is significantly higher.&lt;/p&gt;
&lt;p&gt;Xapian's characteristics are quite similar to those of SQLite. It doesn't hit
yet that memory barrier that affects SQLite's insert performance at 122k
documents, maybe because it consumes only 2/3 of the disk space. Enjoyed its
API for being much closer to modern C++ than any other engine. It gives more
low-level access to all the FTS mechanics: For instance you have to attach
values and feed the indexer yourself. Also you have to deal with token
prefixes. Details that Lucene just hides behind a Field class and its
attributes. Not sure yet, what approach I prefer.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Tracker is out. Lucene++, QtCLucene and SQLite are quite comparable in terms of
performance, with Lucene++ being the fastest engine when building the index, and
with SQLite being the fastest when performing full text searches. There are some
first signs that Lucene++ is more memory efficient than its competitors. This
needs further investigation. Also we should investigate capabilities for doing
point and range searches, instead of full text searches.&lt;/p&gt;</description>
	<pubDate>Wed, 18 Apr 2012 16:51:56 +0000</pubDate>
</item>

</channel>
</rss>
