<?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>JOEDREW!</title>
	<atom:link href="http://blog.mozilla.com/joe/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mozilla.com/joe</link>
	<description>o/</description>
	<lastBuildDate>Mon, 30 Mar 2009 20:19:47 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Gecko&#8217;s new image cache</title>
		<link>http://blog.mozilla.com/joe/2009/03/30/geckos-new-image-cache/</link>
		<comments>http://blog.mozilla.com/joe/2009/03/30/geckos-new-image-cache/#comments</comments>
		<pubDate>Mon, 30 Mar 2009 20:18:31 +0000</pubDate>
		<dc:creator>JOEDREW!</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[imglib]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/joe/?p=18</guid>
		<description><![CDATA[Now that I&#8217;ve finally checked bug 466586 in to the mozilla-1.9.1/Firefox 3.5 development branch, I consider the design of Imagelib&#8217;s cache finished. I planned on blogging about this a while ago, but other problems distracted me.
When I joined the Mozilla Corporation&#8217;s gfx group in February of 2008, I was tasked with what seemed like a [...]]]></description>
			<content:encoded><![CDATA[<p>Now that I&#8217;ve finally checked <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=466586">bug 466586</a> in to the mozilla-1.9.1/Firefox 3.5 development branch, I consider the design of Imagelib&#8217;s cache finished. I planned on blogging about this a while ago, but <a href="http://blog.mozilla.com/joe/2009/02/26/recent-image-library-changes-on-mozilla-central/">other problems</a> distracted me.</p>
<p>When I joined the Mozilla Corporation&#8217;s <a href="https://wiki.mozilla.org/Platform/GFX">gfx group</a> in February of 2008, I was tasked with what seemed like a simple job: create a hashtable-based cache for <a href="http://www.libpr0n.com/">imagelib</a>, so it no longer had to use necko&#8217;s memory cache. (The work to implement this new cache was tracked in <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=430061">bug 430061</a>.) While this seemed like unnecessary reimplementation, I was assured by <a href="http://blog.pavlov.net/">Stuart</a> and <a href="http://blog.vlad1.com/">Vlad</a> that necko&#8217;s memory cache was meant for an entirely different class of object, and that the large images stored in it were crowding out those objects (such as pages loaded over SSL).</p>
<p>Initially, this seemed like a simple job, but it turned out to be a multi-month effort that involved a lot of rewriting, debugging, collaboration, and patience. The last two attributes were especially embodied by <a href="http://weblogs.mozillazine.org/bz/">Boris Zbarsky</a>, who went out of his way to help me debug problems I didn&#8217;t understand, reviewed far too many iterations of patches, and was generally helpful in a way that I think exemplifies Mozilla&#8217;s community spirit. Thank you, Boris.</p>
<p>The most important fruit of all this labour is <a href="http://blog.karlt.net/2008/12/firefox-31-beta-2-on-linux-uses-less.html">the reduction in memory use it made possible</a>: a clever eviction policy lets us halve the size of the cache while maintaining the same real-world performance.</p>
<p>The remainder of this post will be a detailed explanation of the cache&#8217;s design, how it is implemented, and how I came to the decisions I made. I plan on rolling this into into an <a href="http://developer.mozilla.org/">MDC</a> article at some point, so if you have questions, please ask them.</p>
<p><span id="more-18"></span></p>
<p>Image loading is managed by two classes: imgRequest and imgRequestProxy. imgRequest is the class that takes care of the network load and decoding images, but since the same image can be loaded multiple times, when you call <a href="http://mxr.mozilla.org/mozilla-central/source/modules/libpr0n/src/imgLoader.cpp#1133">imgLoader::LoadImage()</a> you get a reference to an imgRequestProxy. imgRequestProxy is a lightweight handle that implements <a href="http://mxr.mozilla.org/mozilla-central/source/netwerk/base/public/nsIRequest.idl">nsIRequest</a> and <a href="http://mxr.mozilla.org/mozilla-central/source/modules/libpr0n/public/imgIRequest.idl">imgIRequest</a>; it gets events from, and forwards events to, its imgRequest.</p>
<p>Since imgRequest does the actual work, it&#8217;s the class that needs to be kept in the cache. To make doing this a bit easier, I created a data class, imgCacheEntry, that holds a strong reference to imgRequest (which also holds a strong reference to imgCacheEntry, creating a cycle that is broken only once the imgRequest has no more listeners), and also contains useful information, such as last touched time and size. It is these imgCacheEntries that the cache manipulates.</p>
<p>The cache itself consists of three data structures:</p>
<ol>
<li> A hash table from URI to imgCacheEntry. Every image in memory is accessible from this hash table unless it has been explicitly removed from the cache.</li>
<li>
<p>An instance of my favourite data structure of all time, the <a href="http://en.wikipedia.org/wiki/Heap_%28data_structure%29">heap</a>. (<a href="http://en.wikipedia.org/wiki/Edsger_W._Dijkstra">Dijkstra</a> invented the heap when he needed a faster way to implement his <a href="http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm">shortest-path graph algorithm</a>, because that is the sort of thing that Real Computer Scientists do.)</p>
<p>Once there are no more listeners for a given image &#8211; say, once a user has navigated away from a page &#8211; we add the image to this heap, and evaluate whether anything needs to be removed from the cache due to space restrictions. If so, the image at the top of the heap is evicted, and (since there are no other references to the image) it is deallocated. (I plan a blog post on precisely how I came to the eviction scheme used in imagelib in the near future.)</p>
<blockquote><p>(A brief aside about performance: Even though heaps are relatively quick, updating one on every change to the cache turned into a 2x performance hit. The main problem is that updating the heap implemented in the STL (I believe a binary heap) is an O(n) operation. I investigated a couple of different replacement data structures for solving this &#8211; one, described in a paper called &#8220;<a href="http://portal.acm.org/citation.cfm?id=1109603">Implicit dictionaries with O(1) modifications per update and fast search</a>&#8221; turned out to not be applicable to the problem; another, <a href="http://en.wikipedia.org/wiki/Fibonacci_heap">Fibonacci heaps</a>, looked promising, but its attributes weren&#8217;t precisely right. In the end, it turned out that lazy evaluation &#8211; marking the heap as dirty, and re-heapifying only when necessary &#8211; solved the performance problem.)</p></blockquote>
</li>
<li>
<p>Our memory tests showed that we weren&#8217;t freeing up as much data after all tabs had been closed, so I added an <a href="http://mxr.mozilla.org/mozilla-central/source/xpcom/ds/nsExpirationTracker.h">nsExpirationTracker</a> to the mix.</p>
<p>nsExpirationTracker runs a timer to forcibly expire elements from the cache after some length of inactive time. (This is currently set to 10 seconds, which feels a little quick. I suspect we&#8217;d be better off if the image cache expiry time was the same as the bfcache expiry time, 30 minutes.) Like the heap, images are only added to the expiration tracker once they have no listeners, since evicting a cache entry that has a reference count above 1 <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=466586">makes website authors depending on previously loaded images being available cry</a>.</p>
</li>
</ol>
<p>These three structures combine with imgRequest and imgRequestProxy in probably-overly-complex ways to implement our image caching strategies. I had lots of problems along the way &#8211; from many, many leaks that took weeks cumulatively to debug, to trying to understand necko&#8217;s twisty passages, to debugging topcrashes without ever having seen the crash myself &#8211; but it&#8217;s made me a better developer, and given me a chance to understand a lot more about this code which I have come to own.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/joe/2009/03/30/geckos-new-image-cache/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>How you can help with recent image library changes on mozilla-central</title>
		<link>http://blog.mozilla.com/joe/2009/02/26/recent-image-library-changes-on-mozilla-central/</link>
		<comments>http://blog.mozilla.com/joe/2009/02/26/recent-image-library-changes-on-mozilla-central/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 23:05:21 +0000</pubDate>
		<dc:creator>JOEDREW!</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[imglib]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/joe/?p=12</guid>
		<description><![CDATA[Over the course of Mozilla&#8217;s 1.9.1 branch development, I&#8217;ve made a number of pretty important changes to Gecko/Firefox&#8217;s image library. I plan on blogging more about those changes in the future, but in a nutshell, instead of using necko&#8217;s memory cache to store decoded images, imagelib (libpr0n) now uses its own hash table, eviction criteria, [...]]]></description>
			<content:encoded><![CDATA[<p>Over the course of Mozilla&#8217;s 1.9.1 branch development, I&#8217;ve made a number of pretty important changes to Gecko/Firefox&#8217;s image library. I plan on blogging more about those changes in the future, but in a nutshell, instead of using necko&#8217;s memory cache to store decoded images, imagelib (libpr0n) now uses its own hash table, eviction criteria, and resurrection methods to cache decoded images.</p>
<p>As part of the changes for <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=466586">bug 466586</a>, I&#8217;ve made it so that images that are still in use &#8211; for example, an image displayed in a webpage that you have open &#8211; are always accessible from the cache. Only once the image isn&#8217;t being used anymore do we start thinking about removing it from the cache (and freeing up its memory). Unfortunately, my current patch (available on the bug, and checked in to mozilla-central) has some latent bugs that I have never been able to reproduce. I do have proof that these bugs exist: in particular, <a href="http://crash-stats.mozilla.com/report/list?product=Firefox&amp;branch=1.9.2&amp;version=Firefox%3A3.2a1pre&amp;query_search=signature&amp;query_type=contains&amp;query=&amp;date=&amp;rangevalue=1&amp;range_unit=weeks&amp;do_query=1&amp;signature=nsExpirationTracker%3CimgCacheEntry%2C%203%3E%3A%3ARemoveObject%28imgCacheEntry*%29">several crashes have shown up when expiring images from the cache</a> since <a href="http://hg.mozilla.org/mozilla-central/rev/a6b38a1f6624">I checked in the patch</a>.</p>
<p>Currently, this code is only checked in to mozilla-central, i.e., the 1.9.2 or mozilla-central branch. I don&#8217;t have any test cases for these bugs (though I&#8217;m <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=479121">trying to get URLs for the crashes</a>), but if you see a crash in your up-to-date Minefield build (2009-02-18 or newer) that contains &#8220;img&#8221; in the stack trace, or you get an abort in your debug build in imgCacheEntry, please file a bug with what you were doing, whether it&#8217;s reproducible, what URL you were at, and any other details you can find. (<a href="http://developer.mozilla.org">MDC</a> has some good information about how to <a href="https://developer.mozilla.org/En/Crash_reporting">report and get information on crashes in Firefox</a>.)</p>
<p>The bug this patch fixes is a Firefox 3.1 beta 3 blocker, so the more users this code has (and consequently the more eyes we have on it), the better.</p>
<p><b>UPDATE</b>: <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=480352">Bug 480352</a> has been filed on this unknown crash, along with some bare-bones instructions on how you can help.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/joe/2009/02/26/recent-image-library-changes-on-mozilla-central/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sept choses</title>
		<link>http://blog.mozilla.com/joe/2009/01/09/sept-choses/</link>
		<comments>http://blog.mozilla.com/joe/2009/01/09/sept-choses/#comments</comments>
		<pubDate>Fri, 09 Jan 2009 22:49:47 +0000</pubDate>
		<dc:creator>JOEDREW!</dc:creator>
				<category><![CDATA[meme]]></category>
		<category><![CDATA[personal]]></category>

		<guid isPermaLink="false">http://blog.mozilla.com/joe/?p=4</guid>
		<description><![CDATA[Chris Blizzard tagged me, and this is as reasonable an introduction to Planet as any other. I&#8217;m Joe Drew, otherwise named JOEDREW! \o/ (apparently by Deb originally, but these things take on a life of their own). I currently work on imagelib in the Mozilla Corporation&#8217;s graphics group, out of MoCo&#8217;s Toronto office. I plan [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.0xdeadbeef.com/weblog/?p=929">Chris Blizzard tagged me</a>, and this is as reasonable an introduction to Planet as any other. I&#8217;m Joe Drew, otherwise named JOEDREW! \o/ (apparently by <a href="http://www.dria.org/wordpress/">Deb</a> originally, but these things take on a life of their own). I currently work on imagelib in the Mozilla Corporation&#8217;s graphics group, out of <a href="http://www.flickr.com/photos/menros/sets/72157604342563366/">MoCo&#8217;s Toronto office</a>. I plan to blog about pictures on the open web; the exploits of <a href="http://muizelaar.blogspot.com/">Jeff Muizelaar</a>, my partner in (graphics) crime here in the Toronto office; and non-Euclidean geometry.</p>
<p>Here are the rules for this particular meme</p>
<ol>
<li>Link to your original tagger(s) and list these rules in your post.</li>
<li>Share seven facts about yourself in the post.</li>
<li>Tag seven people at the end of your post by leaving their names and the links to their blogs.</li>
<li>Let them know they’ve been tagged.</li>
</ol>
<p>My seven things:</p>
<ol>
<li>I&#8217;ve had five non-retail jobs in my life:
<ul>
<li>In Grade 11, I had a summer job doing Microsoft Access and VB consulting at a small, now-defunct shop called Idea People. Surprisingly, this was my first job, even before any retail work I eventually did.</li>
<li>Three of my jobs came through the <a href="http://uwaterloo.ca/">University of Waterloo</a>&#8217;s <a href="http://cecs.uwaterloo.ca/">co-op program</a>:
<ul>
<li><a href="http://www.ti.com">Texas Instruments</a> in Toronto, formerly <a href="http://go-dsp.com/">GO DSP</a>, working on the UNIX port of their IDE and on various infrastructural tasks;</li>
<li><a href="http://www.somanetworks.com/">SOMA Networks</a>, doing Linux kernel device driver work and other custom development for their Linux-based wireless broadband systems.</li>
<li>A <a href="http://en.wikipedia.org/wiki/Houdini_%28software%29">Houdini</a> developer at <a href="http://www.sidefx.com">Side Effects Software</a>, where I worked on 3D animation software for films like <a href="http://en.wikipedia.org/wiki/The_Wild">Disney&#8217;s The Wild</a> (which was created almost entirely in Toronto by <a href="http://www.coredp.com/">CORE</a>).</li>
</ul>
</li>
<li>After graduating, I continued working at Side Effects Software for a couple of years, on all manner of 3D-related things. (I consider this the &#8220;same job&#8221; as my co-op terms at Side Effects.)</li>
<li>Finally, I found myself applying to and being hired by the Mozilla Corporation, my experiences at which is more or less what this entire blog will be about.</li>
</ul>
</li>
<li>Without my wife, who at the time was my girlfriend, I might not have gone to Waterloo at all. It was between <a href="http://www.utoronto.ca">U of T</a> and Waterloo; U of T had offered me a substantial scholarship, on-campus residence, and had a professor call me to sell me on the school. Waterloo gave me no money and told me to find my own place to live. Lisa convinced me that Waterloo was still the right choice, which turned out to be true: without my co-op job experience, I would be in a very different place, career-wise.</li>
<li>I&#8217;ve had precisely one significant other throughout my life: Lisa, my wife. We are literally highschool sweethearts who survived the separation of university to get married after we graduated.</li>
<li>Before I wised up and moved to <a href="http://toronto.ca">the city</a>, I owned a car &#8211; a 2005 Saturn Ion. I <a href="http://me.woot.net/2006/09/22#whoops">wrecked it</a> in a hilariously poorly-thought-out attempted U-turn to avoid a long line for left turns.</li>
<li>I have never left North America, but Lisa was born in Malta.</li>
<li>In the past, I was a fairly active <a href="http://qa.debian.org/developer.php?login=drew@debian.org">Debian developer</a>; I even organized <a href="http://debconf2.debconf.org/pages/drew/index.html">DebConf 2</a> at <a href="http://www.yorku.ca">York University</a> here in Toronto. (These days, I am <a href="http://lists.debian.org/debian-devel-announce/2008/12/msg00002.html">pretty</a> <a href="http://lists.debian.org/debian-devel-announce/2008/12/msg00005.html">disgusted</a> with Debian; it seems it&#8217;s more about forcing other people to do what you want through voting than working out the best technical solution for users.) I have not used a Linux system at home since 2004.</li>
<li>I wrote <a href="http://mpg321.sf.net">mpg321</a> as a Free alternative to <a href="http://www.mpg123.de/">mpg123</a> (back when mpg123 was still non-Free). I had all manner of plans to extend that software, but they fell by the wayside, as things do. I now use iTunes and my iPhone to listen to music.</li>
</ol>
<p>And now, as is part of this meme, I get to tag folk.</p>
<ol>
<li><a href="http://blog.vlad1.com/">Vladimir  Vukićević</a>, my manager, because he doesn&#8217;t blog enough.</li>
<li><a href="http://qwantz.livejournal.com">Ryan North</a>, because he is awesome and draws <a href="http://www.qwantz.com">Dinosaur Comics</a>.</li>
<li><a href="http://shawnwilsher.com/">Shawn Wilsher</a>, who doesn&#8217;t eat shawarma for unknown reasons.</li>
<li><a href="http://www.oxymoronical.com/">Dave Townsend</a>, who now <a href="http://flickr.com/photos/32944866@N04/3156960532/in/pool-555244@N25">looks like a little boy</a>.</li>
<li><a href="http://jboriss.wordpress.com/">Jenny Boriss</a>, because <a href="http://jboriss.files.wordpress.com/2008/12/tinderbox.png">she makes me laugh</a>.</li>
<li><a href="http://tinymurders.livejournal.com/">Katie Bonnar</a>, who I beat out for Prime Minister of Student Council because of damn dirty tricks.
<p>And finally,</li>
<li><a href="http://muizelaar.blogspot.com/">Jeff Muizelaar</a>, because he told me not to tag him.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.com/joe/2009/01/09/sept-choses/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
