<?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>Shawn Wilsher &#187; mozStorage</title>
	<atom:link href="http://shawnwilsher.com/archives/tag/mozstorage/feed" rel="self" type="application/rss+xml" />
	<link>http://shawnwilsher.com</link>
	<description></description>
	<lastBuildDate>Sun, 04 Dec 2011 10:37:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Crash!  Boom!  Bang!  But I just wanted to delete some history&#8230;</title>
		<link>http://shawnwilsher.com/archives/338</link>
		<comments>http://shawnwilsher.com/archives/338#comments</comments>
		<pubDate>Fri, 30 Oct 2009 22:31:00 +0000</pubDate>
		<dc:creator>Shawn Wilsher</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[crash]]></category>
		<category><![CDATA[CrashKill]]></category>
		<category><![CDATA[mozStorage]]></category>
		<category><![CDATA[overflow]]></category>
		<category><![CDATA[SQLite]]></category>

		<guid isPermaLink="false">http://shawnwilsher.com/?p=338</guid>
		<description><![CDATA[If you&#8217;ve been experiencing crashes when trying to delete a large set of history, I have great news for you! We&#8217;ve identified the issue, and a fix will be coming to you shortly! Background This fix wouldn&#8217;t be in our hands if it was for the recent CrashKill effort here at Mozilla. Sam Sidler gave [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve been experiencing crashes when trying to delete a large set of history, I have great news for you!  We&#8217;ve identified the issue, and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=523405">a fix will be coming to you</a> shortly!<br />
<span id="more-338"></span></p>
<h3>Background</h3>
<p>This fix wouldn&#8217;t be in our hands if it was for the recent <a href="https://wiki.mozilla.org/CrashKill">CrashKill</a> effort here at Mozilla.  Sam Sidler gave me <a href="https://wiki.mozilla.org/CrashKill/Signatures/Storage">a link to a list of crashes</a> that were reported to us during a 24 hour period in SQLite and mozStorage code.  I immediately started adding links to crash reports and filing bugs to some of the more frequent crashes so we could start tracking these issues.  I also informed the SQLite team about this page in case they found the data useful, and they sure did.  They started to look into <a href="http://crash-stats.mozilla.com/report/list?product=Firefox&#038;query_search=signature&#038;query_type=exact&#038;query=sqlite3VdbeExec&#038;date=&#038;range_value=1&#038;range_unit=weeks&#038;do_query=1&#038;signature=sqlite3VdbeExec">this particular crash</a>.  It turns out that there are <a href="http://crash-stats.mozilla.com/report/list?product=Firefox&#038;query_search=signature&#038;query_type=exact&#038;query=sqlite3Step&#038;date=&#038;range_value=1&#038;range_unit=weeks&#038;do_query=1&#038;signature=sqlite3Step">two</a> <a href="http://crash-stats.mozilla.com/report/list?product=Firefox&#038;query_search=signature&#038;query_type=exact&#038;query=sqlite3DbMallocRaw&#038;date=&#038;range_value=1&#038;range_unit=weeks&#038;do_query=1&#038;signature=sqlite3DbMallocRaw">other</a> signatures that are actually the same crash, but show up differently due to compiler optimizations causing differences in the generated program.</p>
<h3>Fix Details</h3>
<p>SQLite has a virtual machine that processes queries.  The virtual machine is register-based, which is different from the usual stack-based virtual machines you might encounter with Java.  This particular crash would surface when a SQL query used an <tt>IN</tt> operator with more than ~32 thousand entries on its right-hand side and the <tt>EXISTS</tt> expression.  If either of these conditions occurred on their own, SQLite could handle this just fine.  The <tt>IN</tt> operator stores each entry in a register, and when processing the <tt>EXISTS</tt> expression, SQLite would store the number of the register in which an expression was written into into a 16-bit integer on an <tt>Expr</tt> object.  However, once you try to write a number greater than 32,767 to a 16-bit integer, you get <a href="http://en.wikipedia.org/wiki/Arithmetic_overflow">overflow</a> and you will likely end up with a negative number.  This negative number was then used to index into an array, which is all sorts of bad (and led to the crash).</p>
<p>The workaround fix is to just use a 32-bit integer for now.  This means this issue will not happen unless you have over 2,147,483,647 entries on the right-hand side of the <tt>IN</tt> operator.  You&#8217;d hit other limitations of SQLite before that would ever happen, so overflow is no longer a concern.  The SQLite team is going to do a more complicated fix which stores the value separately from <tt>Expr</tt> object it was previously stored in.  The <tt>Expr</tt> object is used a lot, so they don&#8217;t want a long-term solution that increases memory usage.</p>
<p>You might be surprised that such a small and trivial seeming bug got through.  This type of bug is more common than you might think, and overflow bugs have even <a href="http://en.wikipedia.org/wiki/Ariane_5_Flight_501">caused the destruction of an Ariane 5 rocket</a>.  It&#8217;s an unfortunate reality of software that sometimes these edge cases get missed, but we must always try to remain vigilant.</p>
<p><em>Special thanks to the SQLite team for investigating this fix, and providing information for this blog post.</em><br />
<small><a href="http://rypple.com/sdwilsh/sqlite-op-if-crash-writeup">Provide anonymous feedback on this post with Rypple.</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://shawnwilsher.com/archives/338/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asynchronous Location Bar has Landed</title>
		<link>http://shawnwilsher.com/archives/279</link>
		<comments>http://shawnwilsher.com/archives/279#comments</comments>
		<pubDate>Tue, 11 Aug 2009 20:33:07 +0000</pubDate>
		<dc:creator>Shawn Wilsher</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[location bar]]></category>
		<category><![CDATA[mozStorage]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[places]]></category>
		<category><![CDATA[SQLite]]></category>

		<guid isPermaLink="false">http://shawnwilsher.com/?p=279</guid>
		<description><![CDATA[About two weeks ago the asynchronous location bar work landed in mozilla-central without much issue. It&#8217;s also in the Firefox 3.6 alpha we just recently released. This has the potential to impact all of our users, but those on slower hard drives will notice this the most. Your location bar searches may not complete any [...]]]></description>
			<content:encoded><![CDATA[<p>About two weeks ago the asynchronous location bar work <a href="http://hg.mozilla.org/mozilla-central/pushloghtml?changeset=8cff4bd2121a">landed in mozilla-central</a> without much issue.  It&#8217;s also in the <a href="https://developer.mozilla.org/devnews/index.php/2009/08/07/firefox-3-6-alpha-1-now-available-for-download/">Firefox 3.6 alpha</a> we just recently released.  This has the potential to impact all of our users, but those on slower hard drives will notice this the most.  Your location bar searches may not complete any faster than before, but they certainly won&#8217;t be hanging your browser and locking up the UI.</p>
<h3>Background</h3>
<p>We&#8217;ve been getting reports for some time about the location bar hanging the application for some users when they are typing in it.  This wasn&#8217;t a problem that was reproducible on every machine, and even on machines that saw it, it wasn&#8217;t always 100% reproducible.  Clearly, this behavior is not desirable, so we set out to fix it.</p>
<p>I had a theory to the cause almost a year ago and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=455555">filed a bug</a> that I was hoping we could work on and fix for Firefox 3.5.  We knew that reading data off a disk can be slow (and certainly would complete in a non-deterministic amount of time).  Since SQLite uses blocking read calls (no more code can execute until the data is read from disk), this could certainly be the cause of the slowdown our users were seeing.  Some simple profiling showed that this was largely the cause of the hanging.  Work began on the project, but it was clear that enough issues were cropping up that we were not going to be able to safely take this change for Firefox 3.5, and resources were diverted elsewhere.</p>
<h3>Process and Solution</h3>
<p>This section is a bit technical, so feel free to skip it.  The short answer is &#8220;do not block the main thread while reading from the hard drive.&#8221;</p>
<p>In order to not block the main thread while reading from disk we either need to make SQLite use non-blocking read system calls, or call into SQLite off of the main thread.  Changing the SQLite code isn&#8217;t something we want to do, so that solution was out of the question.  Luckily, we had solved a similar problem with writes and fsyncs earlier in the Firefox 3.5 development with the <a href="http://shawnwilsher.com/archives/162">asynchronous Storage API</a>.</p>
<p>The first implementation that we tried essentially did the same thing that the old code did.  We would execute a query, but this time asynchronously, and then process the results and see if they match.  There were two issues with this approach, however.  The first issue was that we were filtering every history and bookmark entry on the main thread for a given search.  That could be a lot of work we end up doing, and with the additional overhead of moving data across threads, the common case would see no win.  The second issue was that once we selected a result in the location bar, and a search was not yet complete, there would be a hang as the main thread processed a bunch of events that Storage had posted to it containing results.</p>
<p>At this point, we realized we needed to do the filtering on a thread other than the main thread.  After some thought, we was figured that the easiest way to do that would be to use a SQL function that we define in the WHERE clause of our autocomplete queries.  This way, all the filtering is done on a background thread, and the code that runs on the main thread only deals with results we will actually use.  This solution exposed some things in the Storage backend like lock contention and a few other subtle issues, but nothing major came up.</p>
<p>For more details on how the location bar search results are generated, see <a href="http://stackoverflow.com/questions/540725/how-does-firefoxs-awesome-bar-match-strings/1208458#1208458">my explanation here</a>.</p>
<p>If you weren&#8217;t having a problem before, chances are you won&#8217;t notice any difference at all.</p>
]]></content:encoded>
			<wfw:commentRss>http://shawnwilsher.com/archives/279/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Asychronous Storage Statements Just Got Faster</title>
		<link>http://shawnwilsher.com/archives/275</link>
		<comments>http://shawnwilsher.com/archives/275#comments</comments>
		<pubDate>Tue, 04 Aug 2009 21:17:51 +0000</pubDate>
		<dc:creator>Shawn Wilsher</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[mozStorage]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://shawnwilsher.com/?p=275</guid>
		<description><![CDATA[One of the complaints I received early on about the asynchronous storage API was that it wasn&#8217;t faster to call executeAsync compared to execute or executeStep on the calling thread. This was largely the case because people were testing the function call without any other IO going on, which isn&#8217;t going to always be the [...]]]></description>
			<content:encoded><![CDATA[<p>One of the complaints I received early on about the asynchronous storage API was that it wasn&#8217;t faster to call <code>executeAsync</code> compared to <code>execute</code> or <code>executeStep</code> on the calling thread.  This was largely the case because people were testing the function call without any other IO going on, which isn&#8217;t going to always be the case for our users.  People tend to have more than one application running on their computer doing something, and that something can often hit the disk.  The culprit of the slowdown was recreating the sqlite3_stmt object for each call to <code>executeAsync</code>.</p>
<p>With my work on the asynchronous location bar, I wanted to speed up the call to <code>executeAsync</code> to make it as fast as possible so autocomplete look ups would be quick.  To accomplish this, we now cache the asynchronous <code>sqlite3_stmt</code> object so we don&#8217;t recreate it on every call to <code>executeAsync</code>.  This amortizes the cost that was causing the asynchronous API to be slower than the synchronous one.</p>
<p>This solution is not sufficient, however, if you bind parameters to the statement before calling <code>executeAsync</code>.  This is because binding parameters stores state on the underlying <code>sqlite3_stmt</code> object, and we can&#8217;t store that information on it because it could be in use on the background thread.  To get around this issue, I reuse a code from the <a href="http://shawnwilsher.com/archives/258">recent asynchronous storage API addition</a> to store the bound values in memory and then bind them at the time of execution on the background thread.  <a href="http://www.visophyte.org/blog/">Andrew Sutherland</a> and I were both very happy at how small this patched ended up being as a result of good API design in the past.</p>
<p>The bonus with this two step solution is that we&#8217;ve also completely removed the possibility of lock contention inside of the SQLite library on the calling thread of <code>executeAsync</code>.  If you have a long running <code>sqlite3_step</code> command on the background thread, this could block your call to one of the binding calls or <code>executeAsync</code>, which is undesirable.</p>
<p>This code is checked in on mozilla-central, and will be a part of Gecko 1.9.2.</p>
]]></content:encoded>
			<wfw:commentRss>http://shawnwilsher.com/archives/275/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>New Asynchronous Storage API Has Landed</title>
		<link>http://shawnwilsher.com/archives/258</link>
		<comments>http://shawnwilsher.com/archives/258#comments</comments>
		<pubDate>Fri, 26 Jun 2009 05:19:10 +0000</pubDate>
		<dc:creator>Shawn Wilsher</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[mozStorage]]></category>

		<guid isPermaLink="false">http://shawnwilsher.com/?p=258</guid>
		<description><![CDATA[Some time in January I spec&#8217;ed out and API to allow the binding of multiple sets of parameters to a prepared statement and execute it asynchronously. This could be done in the past, but it was difficult and resource intensive to do (you would have to first clone the statement that you had and then [...]]]></description>
			<content:encoded><![CDATA[<p>Some time in January I spec&#8217;ed out and API to allow the binding of multiple sets of parameters to a prepared statement and execute it asynchronously.  This could be done in the past, but it was difficult and resource intensive to do (you would have to first clone the statement that you had and then bind and then pass all the clones to executeAsync).  Say you want to insert a number of rows into a table now.  Your code will look something like this:</p>
<pre lang="JavaScript">
// Note: db is the mozIStorageConnection for our database.
var stmt = db.createStatement("INSERT INTO table_name (table_value)" +
                              "VALUES (:value)");
var values = [
  "val1",
  "val2",
  "val3",
];
var array = stmt.newBindingParamsArray();
for (let i = 0; i < values.length; i++) {
  let params = array.newBindingParams();
  params.bindByName("value", values[i]);
  array.addParams(params);
}
stmt.bindParameters(array);
stmt.executeAsync(); // This will insert all the values into the table.
</pre>
<p>It's not the prettiest thing in the wold, and I hope to add some language helpers for JavaScript to make this even easier to use from JavaScript.  Hope you find it useful!</p>
]]></content:encoded>
			<wfw:commentRss>http://shawnwilsher.com/archives/258/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Asynchronous Location Bar Searches</title>
		<link>http://shawnwilsher.com/archives/255</link>
		<comments>http://shawnwilsher.com/archives/255#comments</comments>
		<pubDate>Wed, 11 Mar 2009 21:43:30 +0000</pubDate>
		<dc:creator>Shawn Wilsher</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[leaks]]></category>
		<category><![CDATA[location bar]]></category>
		<category><![CDATA[mozStorage]]></category>

		<guid isPermaLink="false">http://shawnwilsher.com/?p=255</guid>
		<description><![CDATA[For those of you using the asynchronous location bar add-on, today&#8217;s nightly of both mozilla-central and mozilla-1.9.1 should show a reduction in memory use. Turns out there was a bit of a leak in mozStorage that would mean you&#8217;d get high memory usage that would never go down. My bad. For those of your programmers [...]]]></description>
			<content:encoded><![CDATA[<p>For those of you using the <a href="http://shawnwilsher.com/archives/239">asynchronous location bar add-on</a>, today&#8217;s nightly of both mozilla-central and mozilla-1.9.1 should show a reduction in memory use.  Turns out there was <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=482614" title=" mozStorageVariant leaks its internal data due to non-virtual destructor">a bit of a leak in mozStorage</a> that would mean you&#8217;d get high memory usage that would never go down.  My bad.</p>
<p>For those of your programmers out there, I have a word of advice.  Always make sure you have a virtual destructor in your base class.  If you don&#8217;t, you could spend days tracking down a leak that doesn&#8217;t seem to make sense.  Of course, this probably would have been spotted earlier if we <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=469523" title="Enable TUnit leak log in tinderbox (log)">reported leaks in xpcshell unit tests</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://shawnwilsher.com/archives/255/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Query Performance Monitoring</title>
		<link>http://shawnwilsher.com/archives/251</link>
		<comments>http://shawnwilsher.com/archives/251#comments</comments>
		<pubDate>Tue, 10 Mar 2009 20:22:49 +0000</pubDate>
		<dc:creator>Shawn Wilsher</dc:creator>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[mozStorage]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[places]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[warning]]></category>

		<guid isPermaLink="false">http://shawnwilsher.com/?p=251</guid>
		<description><![CDATA[Over in bug 481261 I am adding support in mozStorage to warn when a query doesn&#8217;t use an index to sort. This is a debug only warning that uses NS_WARNING to tell you what query is at fault, and the total number of sort operations that were used on it. Luckily, SQLite exposes a handy [...]]]></description>
			<content:encoded><![CDATA[<p>Over in <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=481261" title="Expose when queries are being inefficient in debug builds">bug 481261</a> I am adding support in mozStorage to warn when a query doesn&#8217;t use an index to sort.  This is a debug only warning that uses <a href="https://developer.mozilla.org/En/NS_WARNING"><tt>NS_WARNING</tt></a> to tell you what query is at fault, and the total number of sort operations that were used on it.</p>
<p>Luckily, SQLite exposes a <a href="http://www.sqlite.org/c3ref/stmt_status.html">handy function</a> that tells us this information.  In general, you want to use a index in your <tt>ORDER BY</tt> clause so SQLite can use it to generate the order the results a given back.  If you do not use an index, SQLite has to first get all the results in memory, then it sorts them, and then it starts to return results.  If you expect a lot of results, this can get very expensive.</p>
<p>There were suggestions on the newsgroups to also add an API so debuggers such as <a href="http://getfirebug.com/releases/">ChromeBug</a> or <a href="https://addons.mozilla.org/en-US/firefox/addon/5817">SQLite Manager</a> could listen for these types of errors.  I&#8217;ll be filing follow-up bugs for some of these suggestions later on.</p>
]]></content:encoded>
			<wfw:commentRss>http://shawnwilsher.com/archives/251/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

