Skip navigation

Sometime soon after the beta 8 code freeze, the Places team will be merging the Places branch into mozilla-central. There are a lot of changes we’ve been working on, the most important of which is some major re-architecting how we store data.

The Benefits

The work on the Places branch brings us a number of benefits. In general, we’ve parallelized work, and made it substantially less likely that we’ll block on the GUI thread. Some of the important fixes we have landed are:

  • Faster Location Bar
    The location bar is faster because other database work no longer blocks us from searching, and the queries are much simpler.
  • Asynchronous Bookmark Notifications
    Indicating if the current page is bookmarked in the location bar (with the star) is now an asynchronous operation that does not block the page load.
  • Faster Bookmarks & History Management/Searches
    Simpler queries and other improvements should make this all work faster.
  • Faster Link Coloring
    Link coloring is now executed on a separate database connection so it cannot block other database work.
  • Expiration Work
    Less work at startup, less work at shutdown, and less work when we run expiration.
  • Less Data Stored
    Embedded pages are now tracked only in memory and never hit the disk.
  • Better Battery Management
    Much less work during idle time, which will improve our power consumption behaviors.
  • Fixes 29 blockers and 18 other issues

A bit of History

Way back in the days leading up to Firefox 3.5, we moved from storing all of our history and location data in disk tables to in-memory tables that we’d flush out to disk every two minutes off of the GUI thread. The benefit of this was two-fold:

  1. No longer performing the vast majority of our disk writes on the GUI thread
  2. No longer performing the vast majority of our fsyncs/Flushes on the GUI thread

More details about how we came up with this solution can be found in a series of blog posts.

The Problem

This solution has worked out pretty well for us for a while, but recently, especially on OS X, it has not been. The short story is that our architecture did not scale well due to lock contention between our GUI thread and our background I/O thread. While the common case access case may be fine, the failure case (when we hit lock contention) is pretty terrible. The problem is so terrible that I once described it like this:

the failure case makes us fall on our faces, skid about 100 feet, and then fall off a cliff without a parachute.

Ultimately, the only way we can avoid this situation is to not do any database work on separate threads with the same database connection. It was not an issue in the past because we just did not do enough work on the I/O thread, but as we have added to the workload of that thread, we increase the likelihood of it holding the lock, which means there is a higher probability that the GUI thread will not be able to instantly acquire the lock and do whatever it needs to do. This essentially leaves us with two options:

  1. Move the rest of our database work off of the GUI thread.
  2. Move database work from the I/O thread back to the GUI thread.

The Solution

The second choice is not actually a viable option. Disk I/O completes in a non-deterministic amount of time, which is why we have been moving it from the GUI thread to an I/O thread since Firefox 3.5. The first choice is not entirely viable either due to schedule constraints either (we have tons of API calls that are not used heavily but still synchronous). A hybrid solution exists, however. We can reduce the amount of work we do on the I/O thread by using additional I/O threads. Additionally, we can move the remaining synchronous operations during browsing to an I/O thread. In the end, Places ends up with one read/write thread, and multiple read-only threads.

This wasn’t really an option back in the Firefox 3.5 days because in SQLite readers and writers blocked each other. However, the SQLite developers recently devised a new journaling method called WAL that lets readers not block writers, and writers not block readers. When the Places branch merges into mozilla-central, we will end up with three read-only I/O threads and our original read-write I/O thread. The three read-only threads are used for location bar searches, visited checks (is a given hyperlink visited), and some bookmark operations. Each I/O thread has its own connection to the database, allowing operations to happen in parallel (SQLite is only threadsafe because it serializes all access on each connection object, which is why we had the lock contention in the first place).

Performance Test Issues

One of the things that made this work especially difficult is seemingly random changes in performance numbers. We often had regressions suddenly appear (according to talos) on changesets that would have zero impact on performance, and then backing out the change would cause an additional regression. Other times, when we would merge mozilla-central into Places, we would suddenly get new regressions when comparing to mozilla-central. This could be indicative of a bad interaction with our code and the changes on mozilla-central, however after looking at the changes on mozilla-central that landed with the merge, that appeared to be highly unlikely.

I’m also quite certain that some of our performance tests do not actually test/measure what we actually want to test/measure. I’ll leave that discussion to a future blog posts, however.

8 Comments

    • njn
    • Posted December 15, 2010 at 20:23 (8:23 pm)
    • Permalink

    That’s a great list of benefits :)

    • Harsh
    • Posted December 16, 2010 at 04:00 (4:00 am)
    • Permalink

    Awesome work!

    • Dan
    • Posted December 16, 2010 at 18:21 (6:21 pm)
    • Permalink

    Is there a way to define an SQLite connection as read-only, or is that something you’ve just expressed in Mozilla code, i.e. any writing should be done on this thread, the other three should just be used for reading?

  1. You can tell SQLite to open it read-only by passing in SQLITE_OPEN_READONLY to sqlite3_open_v2.

    • jr
    • Posted December 20, 2010 at 17:41 (5:41 pm)
    • Permalink

    Looks good! Will this fix GUI freezes in sidebar/library?

    • No, that’s a different issue that requires substantially more work that likely won’t make it for Firefox 4. It is being tracked in bug 556068.

    • Margaret
    • Posted December 21, 2010 at 07:38 (7:38 am)
    • Permalink

    Great work, Shawn!

    • Neil from Ohio
    • Posted January 15, 2011 at 18:53 (6:53 pm)
    • Permalink

    My “places.sqlite” file hogs 10 MEG of disk space! Does it have to be that large??


11 Trackbacks/Pingbacks

  1. […] novinka, o které bych se cht?l zmínit, je výrazn?jší úprava pozadí práce se záložkami a historii prohlíže?e. Navenek si žádné funk?ní zm?ny nevšimnete, ale […]

  2. By Mozilla Firefox 4.0 Bêta 9 on 14 Jan 2011 at 10:43 am

    […] complète du code de l’historique et des marques-pages, permettant le démarrage et le bookmarking de façon plus […]

  3. By Firefox 4.0 beta 9 · Radiocool.lt on 14 Jan 2011 at 11:13 am

    […] ir adresyno saugojimo variklio optimizavimas paspartins ne tik adreso juost?, bet ir pa?ios naršykl?s […]

  4. By MozillaES la comunidad de Mozilla en español on 14 Jan 2011 at 11:47 am

    […] e ha revisado el código de marcadores e historial, permitiendo de esta manera, un mejor rendimiento al usar los marcadores y un arranque de Firefox […]

  5. […] of the bookmarks and history code, enabling faster bookmarking and startup […]

  6. […] Places ?????????????? ?????????????????????????? […]

  7. […] Historikk og bokmerker har fått en overhaling, noe som gjør at Firefox starter raskere, og at adresselinjen er enda mer behagelig å jobbe med! […]

  8. […] aren’t any new or exciting features with this release — just tweaks and bug fixes. The bookmarks and history code has been overhauled, which will improve browser startup and bookmarking speed (was bookmarking ever […]

  9. […] was an overhaul of the bookmarks and history code, which this enables faster startup performance and better […]

  10. By First Look: Firefox 4 Beta 9 | ZDNet on 17 Jan 2011 at 5:47 am

    […] of the bookmarks and history code, enabling faster bookmarking and startup […]

  11. By Download Firefox 4 Beta 9 on 17 Jan 2011 at 8:10 am

    […] of the bookmarks and history code, enabling faster bookmarking and startup […]

Comments are closed.