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

<channel>
	<title>Roundtrip to Shanghai via Tokyo</title>
	<atom:link href="http://kohei.us/feed/" rel="self" type="application/rss+xml" />
	<link>http://kohei.us</link>
	<description>Kohei Yoshida&#039;s Webspace</description>
	<lastBuildDate>Mon, 19 Mar 2012 18:27:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Windows clipboard dumper</title>
		<link>http://kohei.us/2011/12/01/windows-clipboard-dumper/</link>
		<comments>http://kohei.us/2011/12/01/windows-clipboard-dumper/#comments</comments>
		<pubDate>Fri, 02 Dec 2011 03:40:47 +0000</pubDate>
		<dc:creator>Kohei Yoshida</dc:creator>
				<category><![CDATA[]]></category>
		<category><![CDATA[code snippet]]></category>
		<category><![CDATA[tool]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://kohei.us/?p=1292</guid>
		<description><![CDATA[Inspired by this bug report, I just wrote a small, quick and dirty utility to dump the current clipboard content on Windows. Windows development to me is still pretty much an uncharted territory, so even a utility as simple as &#8230; <a href="http://kohei.us/2011/12/01/windows-clipboard-dumper/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Inspired by <a href="https://bugs.freedesktop.org/show_bug.cgi?id=33100">this bug report</a>, I just wrote a small, quick and dirty utility to dump the current clipboard content on Windows.  Windows development to me is still pretty much an uncharted territory, so even a utility as simple as this took me some time.  Anyway, you can download the binary from here: <a href='http://kohei.us/wp-content/uploads/2011/12/clipdump.exe'>clipdump.exe</a>.  Note that this is a console utility, so you need to run this from the console window.</p>
<p>Here is the source code.</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;Windows.h&gt;</span>
&nbsp;
<span style="color: #339900;">#include &lt;cstdio&gt;</span>
<span style="color: #339900;">#include &lt;cstdlib&gt;</span>
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;vector&gt;</span>
&nbsp;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">size_t</span> char_per_line <span style="color: #000080;">=</span> <span style="color: #0000dd;">16</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">typedef</span> vector<span style="color: #000080;">&lt;</span>WORD<span style="color: #000080;">&gt;</span> line_store_type<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">void</span> dump_line<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> line_store_type<span style="color: #000040;">&amp;</span> line<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>line.<span style="color: #007788;">empty</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0000ff;">return</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">size_t</span> fill_size <span style="color: #000080;">=</span> char_per_line <span style="color: #000040;">-</span> line.<span style="color: #007788;">size</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    line_store_type<span style="color: #008080;">::</span><span style="color: #007788;">const_iterator</span> i <span style="color: #000080;">=</span> line.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, iend <span style="color: #000080;">=</span> line.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #008080;">;</span> i <span style="color: #000040;">!</span><span style="color: #000080;">=</span> iend<span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span>
        <span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%04X &quot;</span>, <span style="color: #000040;">*</span>i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>fill_size<span style="color: #000040;">--</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;     &quot;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">' '</span><span style="color: #008080;">;</span>
    i <span style="color: #000080;">=</span> line.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #008080;">;</span> i <span style="color: #000040;">!</span><span style="color: #000080;">=</span> iend<span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        WORD c <span style="color: #000080;">=</span> <span style="color: #000040;">*</span>i<span style="color: #008080;">;</span>
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #0000dd;">32</span> <span style="color: #000080;">&lt;=</span> c <span style="color: #000040;">&amp;&amp;</span> c <span style="color: #000080;">&lt;=</span> <span style="color: #0000dd;">126</span><span style="color: #008000;">&#41;</span>
            <span style="color: #666666;">// ASCII printable range</span>
            <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #0000ff;">static_cast</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">char</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>c<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">else</span>
            <span style="color: #666666;">// non-printable range</span>
            <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">'.'</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">void</span> dump_clip<span style="color: #008000;">&#40;</span>HANDLE hdl<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>hdl<span style="color: #008000;">&#41;</span>
        <span style="color: #0000ff;">return</span><span style="color: #008080;">;</span>
&nbsp;
    LPTSTR buf <span style="color: #000080;">=</span> <span style="color: #0000ff;">static_cast</span><span style="color: #000080;">&lt;</span>LPTSTR<span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>GlobalLock<span style="color: #008000;">&#40;</span>hdl<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>buf<span style="color: #008000;">&#41;</span>
        <span style="color: #0000ff;">return</span><span style="color: #008080;">;</span>
&nbsp;
    line_store_type line<span style="color: #008080;">;</span>
    line.<span style="color: #007788;">reserve</span><span style="color: #008000;">&#40;</span>char_per_line<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">size_t</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span>, n <span style="color: #000080;">=</span> GlobalSize<span style="color: #008000;">&#40;</span>hdl<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> n<span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        line.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>buf<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>line.<span style="color: #007788;">size</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">==</span> char_per_line<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            dump_line<span style="color: #008000;">&#40;</span>line<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
            line.<span style="color: #007788;">clear</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
    dump_line<span style="color: #008000;">&#40;</span>line<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    GlobalUnlock<span style="color: #008000;">&#40;</span>hdl<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>OpenClipboard<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">EXIT_FAILURE</span><span style="color: #008080;">;</span>
&nbsp;
    UINT fmt <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>fmt <span style="color: #000080;">=</span> EnumClipboardFormats<span style="color: #008000;">&#40;</span>fmt<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> fmt<span style="color: #008080;">;</span> fmt <span style="color: #000080;">=</span> EnumClipboardFormats<span style="color: #008000;">&#40;</span>fmt<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">char</span> name<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">100</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">int</span> len <span style="color: #000080;">=</span> GetClipboardFormatName<span style="color: #008000;">&#40;</span>fmt, name, <span style="color: #0000dd;">100</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>len<span style="color: #008000;">&#41;</span>
            <span style="color: #0000ff;">continue</span><span style="color: #008080;">;</span>
&nbsp;
        <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;---&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
        <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;format code: &quot;</span> <span style="color: #000080;">&lt;&lt;</span> fmt <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
        <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;name: &quot;</span> <span style="color: #000080;">&lt;&lt;</span> name <span style="color: #000080;">&lt;&lt;</span> endl <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
&nbsp;
        HANDLE hdl <span style="color: #000080;">=</span> GetClipboardData<span style="color: #008000;">&#40;</span>fmt<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        dump_clip<span style="color: #008000;">&#40;</span>hdl<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    CloseClipboard<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">EXIT_SUCCESS</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>It&#8217;s nothing sophisticated, and it could probably use more polishing and perhaps some GUI (since it&#8217;s a Windows app).  But for now it serves the purpose for me.</p>
<p><strong>Update:</strong><br />
Tor has submitted his version in the comment section.  Much more sophisticated than mine (and it&#8217;s C not C++).</p>
]]></content:encoded>
			<wfw:commentRss>http://kohei.us/2011/12/01/windows-clipboard-dumper/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Performance improvement in opening ODS documents</title>
		<link>http://kohei.us/2011/11/30/performance-improvement-in-opening-ods/</link>
		<comments>http://kohei.us/2011/11/30/performance-improvement-in-opening-ods/#comments</comments>
		<pubDate>Wed, 30 Nov 2011 21:44:04 +0000</pubDate>
		<dc:creator>Kohei Yoshida</dc:creator>
				<category><![CDATA[]]></category>
		<category><![CDATA[calc]]></category>
		<category><![CDATA[libreoffice]]></category>
		<category><![CDATA[odf]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://kohei.us/?p=1270</guid>
		<description><![CDATA[I have great news to share with you. Calc&#8217;s ODS import filter in 3.5 should be substantially faster when you have documents with a large number of named ranges. Read on if you want to know more details. What happened? &#8230; <a href="http://kohei.us/2011/11/30/performance-improvement-in-opening-ods/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I have great news to share with you.  Calc&#8217;s ODS import filter in 3.5 should be substantially faster when you have documents with a large number of named ranges.  Read on if you want to know more details.</p>
<h2>What happened?</h2>
<p>Laurent Godard, Markus Mohrhard, and myself have been working pretty hard in the past month to bring the performance of ODS import filter to a reasonable level, especially with documents containing a large number of named ranges.</p>
<p>Here is the background.  Laurent uses LibreOffice as a platform for his professional extension, which makes heavy use of named ranges.  It programmatically generates ODS documents and inserts hundred&#8217;s or thousand&#8217;s of named ranges as intermediary storage to further process the data.  The problem was, however, our import performance with that kind of documents was so suboptimal that this process was taking a prohibitively long time.  In order for his extension to perform optimally, our ODS import filter needed to be optimized, and optimized heavily.</p>
<p>During the <a href="http://kohei.us/2011/10/20/libreoffice-conference-2011/">Paris conference</a>, we got our heads together in order to come up with a strategy to make that happen.  Laurent was more than willing to participate this effort, and in the end, he did substantial amount of work profiling, analyzing code, coming up with optimization strategy and putting it altogether.  Markus and I provided mentorship, code pointers, as well as occasional coding to accelerate this effort.</p>
<p>Our hope was to make it all happen in time for our first 3.5 release.  And I&#8217;m very happy to say that we made it.</p>
<h2>Benchmark</h2>
<p>Since we are talking about performance, it won&#8217;t be complete without the actual numbers.  So here goes.</p>
<h3>Test document 1</h3>
<p><a href="http://kohei.us/wp-content/uploads/2011/11/graph1.png"><img src="http://kohei.us/wp-content/uploads/2011/11/graph1-300x168.png" alt="" title="graph1" width="300" height="168" class="alignright size-medium wp-image-1275" /></a><br />
Here is the first test document <a href='http://kohei.us/wp-content/uploads/2011/11/global500.ods'>global500.ods</a>.  It contains 500 sheets, 12,500 global named ranges, and 12,500 formulas that reference them.</p>
<p>On my development machine, the last stable release 3.4.4 takes 14 seconds to open this document.  While 14 seconds may not seem that slow, keep in mind that this machine is somewhat unfairly fast tailored for the abusive developer use, so the real world performance is likely much less impressive (you can probably multiply that number by 3 to get a rough idea of the real world performance).  Anyhow, using the latest master branch on the same machine, this document opens roughly in 2 and a half seconds.  That&#8217;s roughly <em>86% reduction in import time</em>.</p>
<h3>Test document 2</h3>
<p><a href="http://kohei.us/wp-content/uploads/2011/11/graph2.png"><img src="http://kohei.us/wp-content/uploads/2011/11/graph2-300x168.png" alt="" title="graph2" width="300" height="168" class="alignleft size-medium wp-image-1278" /></a><br />
Here is the second, somewhat larger document <a href='http://kohei.us/wp-content/uploads/2011/11/global1000.ods'>global1000.ods</a>.  This document contains 1000 sheets, 25,000 named ranges and 25,000 formulas that reference them.</p>
<p>According to my benchmark performed in the same condition as the first document, 3.4.4 opens this document in 50 seconds, whereas in 3.5.0 it opens under 5 seconds.  That&#8217;s about <em>90% reduction in import time</em>.  Pretty impressive!</p>
<h2>Real power of open source</h2>
<p>This story shows another aspect of this remarkable achievement worth mentioning.  If you use an open source product such as LibreOffice in your business, and if it doesn&#8217;t perform the way you need it to, <em>you can actually join the project as a developer and coordinate the effort with the upstream developers to make it happen.</em>  And depending on the nature of the change you want to see happen, it can happen very quickly as this story demonstrates.</p>
<p>I wanted to emphasize this because, while more and more businesses and institutions are embracing open source software, many of them tend to focus too much on the cost-saving aspect of it, thereby developing the wrong mindset that that&#8217;s what open source is all about.  It isn&#8217;t.  The real power of using open source software in your deployment is it gives you the ability to join and contribute to the project to influence the direction of its development.  That gives you real flexibility in planning, and in my opinion the best way to harness the power of using open source software.  The monetary cost-saving side of the benefit comes as a side effect but should be thought of only as an added bonus, not the primary reason for deploying open source software.</p>
]]></content:encoded>
			<wfw:commentRss>http://kohei.us/2011/11/30/performance-improvement-in-opening-ods/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Redesigned autofilter popup</title>
		<link>http://kohei.us/2011/11/21/redesigned-autofilter-popup/</link>
		<comments>http://kohei.us/2011/11/21/redesigned-autofilter-popup/#comments</comments>
		<pubDate>Mon, 21 Nov 2011 08:20:32 +0000</pubDate>
		<dc:creator>Kohei Yoshida</dc:creator>
				<category><![CDATA[]]></category>
		<category><![CDATA[autofilter]]></category>
		<category><![CDATA[calc]]></category>
		<category><![CDATA[feature]]></category>
		<category><![CDATA[libreoffice]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://kohei.us/?p=1240</guid>
		<description><![CDATA[I&#8217;m happy to announce that I&#8217;ve managed to squeeze this new feature in just in time for the 3.5 code freeze. What&#8217;s new? As I&#8217;ve mentioned briefly in G+, I&#8217;ve been working on brushing up the age-old autofilter popup window &#8230; <a href="http://kohei.us/2011/11/21/redesigned-autofilter-popup/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m happy to announce that I&#8217;ve managed to squeeze this new feature in just in time for the 3.5 code freeze.</p>
<h2>What&#8217;s new?</h2>
<p><a href="https://plus.google.com/u/0/107646708505179576030/posts/1bHKS61obGQ">As I&#8217;ve mentioned briefly in G+</a>, I&#8217;ve been working on brushing up the age-old autofilter popup window in the past few weeks.  I have no idea how old the old one is, but it&#8217;s been there for as long as I remember.  In case anyone needs a reminder as to what the old one looks like, here it is.<br />
<a href="http://kohei.us/wp-content/uploads/2011/11/old-autofilter-popup.png"><img src="http://kohei.us/wp-content/uploads/2011/11/old-autofilter-popup.png" alt="" title="old-autofilter-popup" width="230" height="308" class="alignnone size-full wp-image-1245" /></a><br />
It&#8217;s functional, yet very basic.  While this has served us for many years since the last century, it was also clear that the world has since moved on, and the people has started craving for modern looks and eye candies even in the office productivity applications.  Clearly, it was time for a change.</p>
<p>In contrast to the old, here is how the new one looks:<br />
<a href="http://kohei.us/wp-content/uploads/2011/11/new-autofilter.png"><img src="http://kohei.us/wp-content/uploads/2011/11/new-autofilter.png" alt="" title="new-autofilter" width="300" height="445" class="alignnone size-full wp-image-1242" /></a><br />
I don&#8217;t know about you, but I really like the new one better. :-)</p>
<h2>Motivation</h2>
<p>Aside from updating the aged look of the old popup, I was also motivated to introduce the new popup for its ability to allow selection of multiple values from the selection list.</p>
<p>As you can see in the screenshot, the old one allowed only one value to be selected for each given column, which was not only very limiting but also caused interoperability issues with Excel documents, especially with those created in Excel 2007 and newer.  In fact, <a href="http://kohei.us/2007/06/13/making-autofilter-more-user-friendly/">adding this feature has been my long-term goal, ever since I began working on OpenOffice.org code base professionally</a>.  Because of this background, I had my personal attachment to fulfill that goal, and I&#8217;m really glad to have finally landed this feature 4 years and one name change (OOo to LibreOffice) later!</p>
<h2>Laying the foundation</h2>
<p>You may think that this new popup looks somewhat familiar.  That&#8217;s because the same popup is also used as the pivot table (formerly data pilot) field member selection popup.  <a href="http://kohei.us/2009/12/04/updates-on-various-stuff/">I&#8217;ve touched on this previously on my blog</a>, and you&#8217;ll probably notice the similarity when comparing the screenshot of the new popup with the screenshot of the pivot table popup included in that post.</p>
<p>Internally these two use the same code.  In fact, when I developed that feature for the pivot table, I intentionally designed it to be re-usable, precisely so that I could use it for the autofilter popup at a later time.</p>
<p>So, the hard part of implementing the new popup had already been finished.  All I had to do was to put the autofilter functionality into the popup and launch it instead of the ugly old one, which is precisely what I did to bring the new popup into reality.  I also had to refactor the code that performs the filtering to allow multi-value matching, which was, while invisible to the users, not a trivial task.</p>
<h2>Going forward</h2>
<p>The work is not totally done yet.  As of this writing, the xlsx filter has not been fully adopted to take advantage of the new multi-selection capability, but that&#8217;s my next task, and I expect that to be done in time for 3.5.</p>
<p>Also, the menu still looks very basic, and contains only the same set of options that the old popup had.  This was done deliberately in order for us to ship it in time for 3.5, by avoiding the rather expensive process of re-designing the menu part of the popup.  But I expect we work on the re-design post-3.5, to make it even better and more usable.  Note that the new popup is fully capable of doing sub menus, which gives us all sorts of possibilities.</p>
<p>Anyhow, that&#8217;s all I have to say about this at the moment.  I hope you guys will enjoy the new and shiny autofilter popup! :-)</p>
<h2>Notes for testing</h2>
<p>As with any new features, this one needs lots of testing.  I&#8217;ve written new unit test to cover some parts of it, but unit test can&#8217;t cover all corners of use cases (especially those involving UI interactions), and manual testing from real users is always appreciated.  Some of the affected areas I can think of are:</p>
<ul>
<li>Built-in functions MATCH, LOOKUP, HLOOKUP and VLOOKUP that use the core filtering code which I&#8217;ve heavily refactored.</li>
<li>Import and export of the existing filtering rules, with ods, xls, and xlsx.</li>
<li>Filtering with pivot tables, which shares parts of the filtering code that has been refactored.</li>
<li>Standard and advanced filter dialogs</li>
</ul>
<p>So, watch out for the next daily build that includes this feature!</p>
]]></content:encoded>
			<wfw:commentRss>http://kohei.us/2011/11/21/redesigned-autofilter-popup/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>mdds 0.5.4 released</title>
		<link>http://kohei.us/2011/10/24/mdds-0-5-4-released/</link>
		<comments>http://kohei.us/2011/10/24/mdds-0-5-4-released/#comments</comments>
		<pubDate>Tue, 25 Oct 2011 01:45:40 +0000</pubDate>
		<dc:creator>Kohei Yoshida</dc:creator>
				<category><![CDATA[]]></category>
		<category><![CDATA[mdds]]></category>

		<guid isPermaLink="false">http://kohei.us/?p=1229</guid>
		<description><![CDATA[I&#8217;m happy to announce that version 0.5.4 of Multi-Dimensional Data Structure (mdds) is available for download from the link below. http://multidimalgorithm.googlecode.com/files/mdds_0.5.4.tar.bz2 This release fixes several bugs in segment_tree and point_quad_tree, but other than that, no other changes are made since &#8230; <a href="http://kohei.us/2011/10/24/mdds-0-5-4-released/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m happy to announce that version 0.5.4 of <a href="http://code.google.com/p/multidimalgorithm/">Multi-Dimensional Data Structure (mdds)</a> is available for download from the link below.</p>
<p><a href="http://multidimalgorithm.googlecode.com/files/mdds_0.5.4.tar.bz2">http://multidimalgorithm.googlecode.com/files/mdds_0.5.4.tar.bz2</a></p>
<p>This release fixes several bugs in segment_tree and point_quad_tree, but other than that, no other changes are made since 0.5.3.  If you use 0.5.3 and don&#8217;t use these data structures, then there is no reason to update to 0.5.4.</p>
]]></content:encoded>
			<wfw:commentRss>http://kohei.us/2011/10/24/mdds-0-5-4-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LibreOffice Conference 2011</title>
		<link>http://kohei.us/2011/10/20/libreoffice-conference-2011/</link>
		<comments>http://kohei.us/2011/10/20/libreoffice-conference-2011/#comments</comments>
		<pubDate>Thu, 20 Oct 2011 05:14:51 +0000</pubDate>
		<dc:creator>Kohei Yoshida</dc:creator>
				<category><![CDATA[]]></category>
		<category><![CDATA[france]]></category>
		<category><![CDATA[ixion]]></category>
		<category><![CDATA[libocon]]></category>
		<category><![CDATA[libreoffice]]></category>
		<category><![CDATA[orcus]]></category>

		<guid isPermaLink="false">http://kohei.us/?p=1215</guid>
		<description><![CDATA[So, it was a real pleasure to be a part of the very first LibreOffice conference held in Paris, France. Some of the faces and names were familiar from the old OOo conferences, but the atmosphere of the conference was &#8230; <a href="http://kohei.us/2011/10/20/libreoffice-conference-2011/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So, it was a real pleasure to be a part of the very first LibreOffice conference held in Paris, France.  Some of the faces and names were familiar from the old OOo conferences, but the atmosphere of the conference was very different from the OOo ones in the past.  I have been to the 2007 Barcelona conference and the 2009 Orvieto one, and I have to say, while there were some rough-edges, this is by-far my favorite OOo/LibO conference to date.</p>
<p>The only regret I have is that, because I had another international trip (to South Korea) only a week prior to the conference, I felt pretty much exhausted most of the time I was there.  But I think I managed to chat with most of the people I needed to chat with during this once-a-year event.  I intentionally tried not to hack too much during this conference, mainly because of my travel fatigue, but also because I felt it was more important to see people and talk to them to have a good feel for each other.  Working from home, I sometimes miss the human interaction that people who work in the office probably take for granted, so this conference was a perfect place to fulfill that need, to make me feel human again. ;-)  (Actually I tried to code a bit during the conference, but apparently my brain wasn&#8217;t cooperating at all I decided it probably wasn&#8217;t a good idea).</p>
<p>Anyway, it was good to see and chat with Markus Mohrhard (moggi), a very active Calc hacker who&#8217;s been instrumental in Calc&#8217;s filter test development in recent days.  We discussed on various topics on Calc development since we work together in that code.</p>
<p>Also, Laurent Godard, whom I&#8217;ve known many years from the OOo days, but never met face-to-face.</p>
<p>And Valek Filippov, who happens to be in the same timezone as I.  There aren&#8217;t many of us left in this LibreOffice circle, unfortunately.  I tried to persuade him into this wonderful world of hacking, but so far he&#8217;s successfully fended off my attack.</p>
<p>It was also nice to chat with Michael Meeks at length, to clarify the new Calc cell storage structure that he and I discussed previously.  Now the concept is very much clear, waiting to be coded.</p>
<p>Of course, many other countless hackers I&#8217;ve had beer with during the conference week, it was a real pleasure.</p>
<p>Now, I got some homework to do based on my interaction with various people during the conference.  I will list them up item by item to use as a reminder.</p>
<ul>
<li>Two Calc bugs from Valek.  Both are related to this 1C program that pretty much everyone in Russia uses.  I&#8217;ve already added them to my 3.5 TODO list, so it&#8217;s just a matter of finding time to tackle them unless something tricky comes out.</li>
<li>Some documentation on how to use the <a href="http://gitorious.org/ixion">ixion</a> library.  Since there were some interests on using ixion to support formula calculations in other applications, I should probably start working on producing documentation on ixion, both on how to build it, and how to use it.  I should also create a package for it while I&#8217;m at it.</li>
<li>Support for temporary cell buffer in the <a href="http://gitorious.org/orcus">orcus</a> library, to allow converting cell values before passing them to the client code.  In some cases we can&#8217;t simply push the cell value as-is but convert it first before passing it to the client code.  Typical examples are double quotes as a literal quote in CSV, as well as encoded characters (e.g. &amp;amp;) in XML/HTML.  This will unfortunately cost us a bit for the allocation of the buffer and copying of the char array, but fortunately we don&#8217;t need to do this for all cells.</li>
<li>And lots and lots more.</li>
</ul>
<p>All in all, I was glad to be a part of this successful conference.  The atmosphere was very much all inclusive and personal, exactly how an open source conference should be.</p>
]]></content:encoded>
			<wfw:commentRss>http://kohei.us/2011/10/20/libreoffice-conference-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides for my talk</title>
		<link>http://kohei.us/2011/10/18/slide-for-my-talk/</link>
		<comments>http://kohei.us/2011/10/18/slide-for-my-talk/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 03:06:07 +0000</pubDate>
		<dc:creator>Kohei Yoshida</dc:creator>
				<category><![CDATA[]]></category>
		<category><![CDATA[france]]></category>
		<category><![CDATA[libocon]]></category>
		<category><![CDATA[libreoffice]]></category>

		<guid isPermaLink="false">http://kohei.us/?p=1209</guid>
		<description><![CDATA[In case someone wants to get a hold of the slides for my talk during the LibreOffice conference, they are available here (also in PDF). I will write something up about the conference in more detail at later time. For &#8230; <a href="http://kohei.us/2011/10/18/slide-for-my-talk/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In case someone wants to get a hold of the slides for my talk during the LibreOffice conference, they are available <a href="http://kohei.us/files/slides_libocon_2011.odp">here</a> (also in <a href="http://kohei.us/files/slides_libocon_2011.pdf">PDF</a>).</p>
<p>I will write something up about the conference in more detail at later time.  For now, I&#8217;ll take some time off to recover from the several travels I did in the past few weeks, across 3 different timezones that are 17 hours apart in total.</p>
<p>So, see you guys later.</p>
]]></content:encoded>
			<wfw:commentRss>http://kohei.us/2011/10/18/slide-for-my-talk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Import performance boost with form controls</title>
		<link>http://kohei.us/2011/08/17/import-performance-boost-with-form-controls/</link>
		<comments>http://kohei.us/2011/08/17/import-performance-boost-with-form-controls/#comments</comments>
		<pubDate>Wed, 17 Aug 2011 16:27:22 +0000</pubDate>
		<dc:creator>Kohei Yoshida</dc:creator>
				<category><![CDATA[]]></category>
		<category><![CDATA[calc]]></category>
		<category><![CDATA[libreoffice]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://kohei.us/?p=1193</guid>
		<description><![CDATA[This is another performance win. I&#8217;ve just pushed changes to the master branch to improve the import performance of binary Excel documents containing tons of form controls. The test document I used had an upward of 500 form controls which, &#8230; <a href="http://kohei.us/2011/08/17/import-performance-boost-with-form-controls/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is another performance win.</p>
<p>I&#8217;ve just pushed changes to the master branch to improve the import performance of binary Excel documents containing tons of form controls.  The test document I used had an upward of 500 form controls which, prior to the change, Calc would spend <em>at least several minutes to load</em>.  I don&#8217;t know the exact amount of time it took to open the document because each time I tried to open it, I had to kill the app after I became too impatient to wait.</p>
<p>Long story short, the same document now <em>opens under 6 seconds</em> on my machine.</p>
<p>The poor performance in this particular case consisted of several different bottlenecks.  They are</p>
<ul>
<li>inefficient algorithm in registering event listeners for VBA events,</li>
<li>inefficient algorithm in querying the code name from the parent application,</li>
<li>unnecessary VBA event registration for form controls, and</li>
<li>sending unnecessary notifications to property value change listeners during import for each and every property value insertion.</li>
</ul>
<h3>Registering event listeners for VBA events</h3>
<p>When each control is inserted, we register several VBA events for it in order to handle events from the VBA code.  For each event, we would register by passing the target and listener pair to the handler that handles event notification.  As it turned out, however, each time that happens, the handler has to introspect the type of the target because it is passed as UNO&#8217;s Any object.  While each instance of that may take only a fraction of a second to complete, when calling it literally millions of times it adds up not to mention the fact that the target remains the same for 12 or so listeners that are being registered for each control.</p>
<p>To solve this, I added a new method to register multiple event listeners for an identical target in a single call, to avoid repeated and unnecessary introspection of the target type.  This alone has resulted in reducing the load time significantly (66% load-time reduction with my test document).  However, this was still not enough with a larger number of controls since, as the number of controls grew, the load time would increase almost quadratically.</p>
<h3>Querying the code name from the parent application</h3>
<p>Another issue was the algorithm responsible for looking up the &#8220;code name&#8221; of the VBA module that the control belongs to.  The code name is the name associated with each VBA module that Excel creates for each sheet.  The name of the module does not necessarily equal the name of the sheet, and is unique to each sheet.  The old algorithm would go through all existing form control instances in order to find a match, then backtrack the sheet it is on in order to determine the correct code name.  But because it had to iterate through all existing controls, as the number of the controls grew, so would the time it takes to find a match.</p>
<p>Since the code name is identical for each sheet, there was no reason to check every single control.  So I added a new method to get the code name directly from the parent container of the controls.  Since we only create one container per sheet at most, this has resulted in making the code name lookup independent of the number of controls, and has resulted in quasi-constant time lookup since the number of sheets doesn&#8217;t grow during the import.</p>
<h3>Unnecessary VBA event registration for form controls</h3>
<p>There are two types of controls that Excel supports.  One is the older form controls that you can insert via Forms toolbar, while the other is the newer, OLE controls that you can insert via Control Toolbox toolbar.  As luck would have it, Excel doesn&#8217;t support bindings to VBA with the form controls, so it was not necessary to register events for these guys when we import them (as <a href="http://noelpower.blogs.ie/">Noel</a> told me).  Turning off event registration for form control import has surely cut down the load time significantly.  Many thanks to <a href="http://noelpower.blogs.ie/">Noel</a> for giving me a patch to turn this off for form controls.</p>
<h3>Property value change listeners</h3>
<p>Even after all these performance bottlenecks squashed, the load time still didn&#8217;t feel as fast as it should be.  So, I did another round of profiling.  It indicated that, every time we set a new property value to a control via XPropertySet, we would notify all property value change listeners to allow them to react to the change or veto the change, and this happened unconditionally for every single property value insertion for every single control.</p>
<p>Since the likelihood of having to veto or change other property values based on a new property value insertion during file import is close to nil if not zero, I added a new API to temporarily turn off this notification.  This has cut down the last few seconds off the overall load time, down to 6 seconds in total.  This notification is turned back on after the loading is complete.</p>
<h3>Future consideration</h3>
<p>There are several opportunities for future work.  For one thing, the code name lookup also applies to the VBA event support in Writer.  But because I wasn&#8217;t aware of how Writer organizes form controls, I didn&#8217;t touch its lookup algorithm.  So, if the same inefficiency applies to Writer (which I&#8217;m not sure it does), then there <em>may</em> be a way to improve performance in that area.</p>
<p>Another area to consider is reducing the number of VBA events to register.  As <a href="http://noelpower.blogs.ie/">Noel</a> told me, we currently register 12 or so events unconditionally for all controls imported from Excel documents.  But technically we only have to register events that are actually needed.  So, if we can find a way to determine what events we need to register by either parsing the VBA code or any other ways, we can reduce the number of VBA event registrations during the import.</p>
<p>This is all I can think of at the moment.  Thank you ladies and gentlemen.</p>
]]></content:encoded>
			<wfw:commentRss>http://kohei.us/2011/08/17/import-performance-boost-with-form-controls/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>mdds moves to git</title>
		<link>http://kohei.us/2011/07/15/mdds-moves-to-git/</link>
		<comments>http://kohei.us/2011/07/15/mdds-moves-to-git/#comments</comments>
		<pubDate>Sat, 16 Jul 2011 01:57:40 +0000</pubDate>
		<dc:creator>Kohei Yoshida</dc:creator>
				<category><![CDATA[]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[mdds]]></category>

		<guid isPermaLink="false">http://kohei.us/?p=1184</guid>
		<description><![CDATA[Following the announcement that Google Code finally gets git support, I&#8217;ve migrated my mdds source code repository from the old mercurial one to a new git one. For anyone who has the old mercurial repository of mdds checked out, please &#8230; <a href="http://kohei.us/2011/07/15/mdds-moves-to-git/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Following the announcement that <a href="http://www.infoq.com/news/2011/07/google-git">Google Code finally gets git support</a>, I&#8217;ve migrated my <a href="http://code.google.com/p/multidimalgorithm/">mdds</a> source code repository from the old mercurial one to a new git one.  For anyone who has the old mercurial repository of mdds checked out, please switch to the new git repo.  Refer to <a href="http://code.google.com/p/multidimalgorithm/source/checkout">this page</a> on how to check out the new git-based mdds repository.</p>
<p>As for doing the actual migration, <a href="http://hivelogic.com/articles/converting-from-mercurial-to-git/">this blog post</a> was very helpful.</p>
]]></content:encoded>
			<wfw:commentRss>http://kohei.us/2011/07/15/mdds-moves-to-git/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mdds 0.5.3 released</title>
		<link>http://kohei.us/2011/07/14/mdds-0-5-3-released/</link>
		<comments>http://kohei.us/2011/07/14/mdds-0-5-3-released/#comments</comments>
		<pubDate>Thu, 14 Jul 2011 19:02:52 +0000</pubDate>
		<dc:creator>Kohei Yoshida</dc:creator>
				<category><![CDATA[]]></category>
		<category><![CDATA[mdds]]></category>

		<guid isPermaLink="false">http://kohei.us/?p=1179</guid>
		<description><![CDATA[I&#8217;m happy to announce that version 0.5.3 of Multi-Dimensional Data Structure (mdds) is available for download from the link below. http://multidimalgorithm.googlecode.com/files/mdds_0.5.3.tar.bz2 This is a bug fix release. In fact, the only change since 0.5.2 is in mixed_type_matrix, and in particular &#8230; <a href="http://kohei.us/2011/07/14/mdds-0-5-3-released/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m happy to announce that version 0.5.3 of <a href="http://code.google.com/p/multidimalgorithm/">Multi-Dimensional Data Structure (mdds)</a> is available for download from the link below.</p>
<p><a href="http://multidimalgorithm.googlecode.com/files/mdds_0.5.3.tar.bz2">http://multidimalgorithm.googlecode.com/files/mdds_0.5.3.tar.bz2</a></p>
<p>This is a bug fix release.  In fact, the only change since 0.5.2 is in <strong>mixed_type_matrix</strong>, and in particular in its filled storage implementation.  I&#8217;ve completely re-worked the fill storage backend of mixed_type_matrix in order to boost its performance on instantiation, whose effect will be evident when creating and destroying a large number of filled matrix objects.</p>
<p>There is no API-incompatible change in this release.</p>
]]></content:encoded>
			<wfw:commentRss>http://kohei.us/2011/07/14/mdds-0-5-3-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New option to specify initial number of sheets</title>
		<link>http://kohei.us/2011/06/13/new-option-to-specify-initial-number-of-sheets/</link>
		<comments>http://kohei.us/2011/06/13/new-option-to-specify-initial-number-of-sheets/#comments</comments>
		<pubDate>Tue, 14 Jun 2011 03:20:29 +0000</pubDate>
		<dc:creator>Kohei Yoshida</dc:creator>
				<category><![CDATA[]]></category>
		<category><![CDATA[calc]]></category>
		<category><![CDATA[feature]]></category>
		<category><![CDATA[libreoffice]]></category>

		<guid isPermaLink="false">http://kohei.us/?p=1167</guid>
		<description><![CDATA[This just landed on the master branch. Starting with LibreOffice 3.5, you can now specify the initial number of sheets that new documents will have. Previously, this was hard-coded to be 3 sheets in all cases no matter what. While &#8230; <a href="http://kohei.us/2011/06/13/new-option-to-specify-initial-number-of-sheets/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This just landed on the master branch.</p>
<p>Starting with LibreOffice 3.5, you can now specify the initial number of sheets that new documents will have.  Previously, this was hard-coded to be 3 sheets in all cases no matter what.  While this didn&#8217;t seem to bother a whole lot of people based on how little bug reports we&#8217;d received on this, it did bother some users enough so that one of them have decided to code up a patch to make it happen.  Now, without further ado, let&#8217;s take a look at the new option page:</p>
<p><a href="http://kohei.us/wp-content/uploads/2011/06/new-doc-options.png"><img src="http://kohei.us/wp-content/uploads/2011/06/new-doc-options-300x154.png" alt="new-doc-options" title="new-doc-options" width="300" height="154" class="alignnone size-medium wp-image-1169" /></a></p>
<p>where you can change the number of worksheets in new document, which becomes effective the next time you create a new document.</p>
<p>Last but not least, the name of the person who made this all happen is <strong>Albert Thuswaldner</strong>.  Please give kudos to him for his excellent work. :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://kohei.us/2011/06/13/new-option-to-specify-initial-number-of-sheets/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

