<?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>Labix Blog</title>
	<atom:link href="http://blog.labix.org/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.labix.org</link>
	<description>by Gustavo Niemeyer</description>
	<lastBuildDate>Mon, 09 Apr 2012 02:31:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>The Easter mgo release</title>
		<link>http://blog.labix.org/2012/04/08/the-easter-mgo-release</link>
		<comments>http://blog.labix.org/2012/04/08/the-easter-mgo-release#comments</comments>
		<pubDate>Mon, 09 Apr 2012 02:31:56 +0000</pubDate>
		<dc:creator>niemeyer</dc:creator>
				<category><![CDATA[Other]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=965</guid>
		<description><![CDATA[It wasn&#8217;t just the bunny that was active over the holidays. The r2012.04.08 release of the mgo MongoDB driver for Go has just been tagged. This release is supposed to be entirely compatible with the last release, and there are &#8230; <a href="http://blog.labix.org/2012/04/08/the-easter-mgo-release">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>It wasn&#8217;t just the bunny that was active over the holidays. The <b>r2012.04.08</b> release of the <a href="http://labix.org/mgo">mgo MongoDB driver for Go</a> has just been tagged. This release is supposed to be entirely compatible with the last release, and there are some nice improvements and a few important bug fixes, so upgrading is recommended.</p>
<p>For the impatient, here is a quick summary of the changes performed:</p>
<p><span id="more-965"></span>
<ul>
<li>Bug in Limit method fixed
<li>Overflow in marshaling of time.Time fixed
<li>omitempty support for time.Time fields
<li>Better slave selection
<li>Hard per-server connection limit
<li>Improved performance of query error checking
<li>Sort method arguments simplified
<li>Added Session.Fsync, FsyncLock, and FsyncUnlock methods
<li>Added Query.Snapshot method
</ul>
<p>If you want more details about any of these, keep reading.</p>
<p><b>Bug in Limit method fixed</b></p>
<p>The Limit method was fixed. It was improperly causing the data to be returned in a single chunk from the server, which would mean less documents being processed if the data retrieved went over 4MB. Thanks to Jeff Wendling for reporting the issue.</p>
<p><b>Overflow in marshaling of time.Time fixed</b></p>
<p>The marshaling of time.Time was overflowing due to the use of UnixNano, which means certain times would be marshaled as an arbitrarily wrong time. The zero time is an important case that was mishandled, for example. If there&#8217;s a chance your application may be affected, you may look for this date in the database to confirm:</p>
<blockquote><p>
1754-08-30 22:43:41.128654848 +0000 UTC
</p></blockquote>
<p>If you find it, that&#8217;s actually a zero time.</p>
<p>The problem was fixed and such times will now be marshaled correctly. Thanks to Mikael for reporting the issue on the mgo-users mailing list.</p>
<p><b>omitempty support for time.Time fields</b></p>
<p>The omitempty bson tag flag is now supported for time.Time values as well. If used, the time is only marshalled into the bson document if IsZero is false. For example:</p>
<blockquote><p>
type Person struct {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Birthday time.Time `bson:&#8221;,omitempty&#8221;`<br />
}
</p></blockquote>
<p><b>Better slave selection</b></p>
<p>The slave selection algorithm was changed so that mgo will now pick the server for which it has the least number of connections open at the moment, rather than being a random selection. More improvements in this area will come soon.</p>
<p><b>Hard per-server connection limit</b></p>
<p>There&#8217;s now a hard limit for the number of concurrent connections to a single server. If that limit is reached, the client will block waiting for connections to be released.</p>
<p>The default limit is currently 4096 connections per server for each mgo client, but this logic will be improved in the near future as well to take into account the number of connections currently available at the server side.</p>
<p>Note that this is a fire protection mechanism. This limit is not supposed to be touched under normal operation. If you have higher needs right now, please get in touch.</p>
<p>The development of this feature was sponsored by Iron.io.</p>
<p><b>Improved performance of query error checking</b></p>
<p>The logic that verified query results for errors was on the expensive side for large documents, as pointed out by Nils Hasenbanck in the mailing list. This has been significantly improved.</p>
<p><b>Sort method arguments simplified</b></p>
<p>The Sort method now takes a list of field names as arguments rather than a document. Field names may be potentially prefixed by &#8211; (minus) to sort in descending order.</p>
<p>For example, what would previously be written as:</p>
<blockquote><p>
query := c.Find(q).Sort(bson.M{&#8220;a&#8221;: 1, &#8220;b&#8221;: -1})
</p></blockquote>
<p>Is now written as:</p>
<blockquote><p>
query := c.Find(q).Sort(&#8220;a&#8221;, &#8220;-b&#8221;)
</p></blockquote>
<p>The previous format is still supported right now for compatibility reasons, but it is deprecated and will eventually be dropped entirely.</p>
<p>More details at:</p>
<blockquote><p>
<a href="http://godoc.labix.org/mgo#Query.Sort">http://godoc.labix.org/mgo#Query.Sort</a>
</p></blockquote>
<p><b>Added Session.Fsync, FsyncLock, and FsyncUnlock methods</b></p>
<p>The new Session Fsync method requests a synchronous or asynchronous flush of in-memory changes to disk, while the FsyncLock and FsyncUnlock methods do the opposite: they handle a lock at the server side that blocks any follow up write requests (and read requests too, see the documentation). This is useful, for example, to perform backups reliably.</p>
<p>See the documentation of these methods for more details: </p>
<blockquote><p>
<a href="http://godoc.labix.org/mgo#Session.Fsync">http://godoc.labix.org/mgo#Session.Fsync</a><br />
<a href="http://godoc.labix.org/mgo#Session.FsyncLock">http://godoc.labix.org/mgo#Session.FsyncLock</a><br />
<a href="http://godoc.labix.org/mgo#Session.FsyncUnlock">http://godoc.labix.org/mgo#Session.FsyncUnlock</a>
</p></blockquote>
<p><b>Added Query.Snapshot method</b></p>
<p>The new helper method wraps the snapshot command. More details in the documentation:</p>
<blockquote><p>
<a href="http://godoc.labix.org/mgo#Query.Snapshot">http://godoc.labix.org/mgo#Query.Snapshot</a>
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2012/04/08/the-easter-mgo-release/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bazaar, the git way</title>
		<link>http://blog.labix.org/2012/01/16/bazaar-the-git-way</link>
		<comments>http://blog.labix.org/2012/01/16/bazaar-the-git-way#comments</comments>
		<pubDate>Mon, 16 Jan 2012 04:02:51 +0000</pubDate>
		<dc:creator>niemeyer</dc:creator>
				<category><![CDATA[Conference]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[RCS]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=935</guid>
		<description><![CDATA[Back at the Ubuntu Platform Rally last week, I&#8217;ve pestered some of the Bazaar team with questions about co-location of branches in the same directory with Bazaar. The great news is that this seems to be really coming for the &#8230; <a href="http://blog.labix.org/2012/01/16/bazaar-the-git-way">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Back at the Ubuntu Platform Rally last week, I&#8217;ve pestered some of the Bazaar team with questions about co-location of branches in the same directory with Bazaar. The great news is that this seems to be really coming for the next release, with first-class integration of the feature in the command set. Unfortunately, though, it&#8217;s not quite yet ready for prime time, or even for <i>I&#8217;m-crazy-and-want-this-feature</i> time.</p>
<p>Some background on why this feature turns out to be quite important right now may be interesting, since life with Bazaar in the past years hasn&#8217;t really brought that up as a blocker. <span id="more-935"></span>The cause for the new interest lies in some recent changes in the toolset of the Go language. The new <i>go</i> tool not only makes building and interacting with Go packages a breeze, but it also solves a class of problems previously existent. For the <i>go</i> tool to work, though, it requires the use of $GOPATH consistently, and this means that the package has to live in a <i>well defined directory</i>. The traditional way that Bazaar manages branches into their own directories becomes a deal breaker then.</p>
<p>So, last week I had the chance to exchange some ideas with Jelmer Vernooij and Vincent Ladeuil (both Bazaar hackers) on these problems, and they introduced me to the approach of using lightweight checkouts to workaround some of the limitations. Lightweight checkouts in Bazaar makes the working tree resemble a little bit the old-style VCS tools, with the working tree being bound to another location that actually has the core content. The idea is great, and given how well lightweight checkouts work with Bazaar, building a full fledged solution shouldn&#8217;t be a lot of work really.</p>
<p>After that conversation, I&#8217;ve put a trivial hack together that would make bzr look like git from the outside, by wrapping the command line, and did a lightning talk demo. This got a few more people interested on the concept, which was enough motivation for me to move the idea forward onto a working implementation. Now I just needed the time to do it, but it wasn&#8217;t too hard to find it either.</p>
<p>I happen to be part of the unlucky group that too often takes more than 24 hours to get back home from these events. This is not entirely bad, though.. I also happen to be part of the lucky group that can code while flying and riding buses as means to relieve the boredom (reading helps too). This time around, <a href="http://labix.org/cobzr">cobzr</a> became the implementation of choice, and given ~10 hours of coding, we have a very neat and over-engineered wrapper for the bzr command.</p>
<p>The core of the implementation is the same as the original hack: wrap bzr and call it from outside to restructure the tree. That said, rather than being entirely lazy and hackish line parsing, it actually parses bzr&#8217;s &#8211;help output for commands to build a base of supported options, and parses the command line exactly like Bazaar itself would, validating options as it goes and distinguishing between flags with arguments from positional parameters. That enables the proxying to do much more interesting work on the intercepted arguments.</p>
<p>Here is a quick session that shows a branch being created with the tool. It should look fairly familiar for someone used to git:</p>
<p><code><br />
[~]% bzr branch lp:juju<br />
Branched 443 revisions.                                                                                                                       </p>
<p>[~]% cd juju<br />
[~/juju]% bzr branch<br />
* master</p>
<p>[~/juju]% bzr checkout -b new-feature<br />
Shared repository with trees (format: 2a)<br />
Location:<br />
  shared repository: .bzr/cobzr<br />
Branched 443 revisions.<br />
Branched 443 revisions.<br />
Tree is up to date at revision 443.<br />
Switched to branch: /home/niemeyer/juju/.bzr/cobzr/new-feature/</p>
<p>[~/juju]% bzr branch other-feature<br />
Branched 443 revisions.                                                                                                                       </p>
<p>[~/juju]% bzr branch<br />
&nbsp;&nbsp;master<br />
* new-feature<br />
&nbsp;&nbsp;other-feature<br />
</code></p>
<p>Note that cobzr will not reorganize the tree layout before the multiple branch support is required.</p>
<p>Even though the wrapping is taking place and bzr&#8217;s &#8211;help output is parsed, there&#8217;s pretty much no noticeable overhead given the use of Go for the implementation and also that the processed output of &#8211;help is cached (I <i>said</i> it was overengineered).</p>
<p>As an example, the first is the real bzr, while the second is a link to cobzr:</p>
<p><code><br />
[~/juju]% time /usr/bin/bzr status<br />
/usr/bin/bzr status  0.24s user 0.03s system 88% cpu 0.304 total</p>
<p>[~/juju]% time bzr status<br />
bzr status  0.19s user 0.08s system 88% cpu 0.307 total<br />
</code></p>
<p>This should be more than enough for surviving comfortably until bzr itself comes along with first class support for co-located branches in the next release.</p>
<p>In case you&#8217;re interested in using it or are just curious about the command set or other details, please check out the web page for the project:</p>
<ul>
<li><a href="http://labix.org/cobzr">http://labix.org/cobzr</a>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2012/01/16/bazaar-the-git-way/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Good concurrency changes the game</title>
		<link>http://blog.labix.org/2011/12/12/good-concurrency-changes-the-game</link>
		<comments>http://blog.labix.org/2011/12/12/good-concurrency-changes-the-game#comments</comments>
		<pubDate>Mon, 12 Dec 2011 17:52:47 +0000</pubDate>
		<dc:creator>niemeyer</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[Snippet]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=886</guid>
		<description><![CDATA[A long time before I seriously got into using distributed version control systems (DVCS) such as Bazaar and Git for developing software, it was already well known to me how the mechanics of these systems worked, and why people benefited &#8230; <a href="http://blog.labix.org/2011/12/12/good-concurrency-changes-the-game">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A long time before I seriously got into using distributed version control systems (DVCS) such as Bazaar and Git for developing software, it was already well known to me how the mechanics of these systems worked, and why people benefited from them. That said, it wasn&#8217;t until I indeed started to use DVCS tools that I understood how much my daily workflow around code bases would be changed and improved.</p>
<p><span id="more-886"></span>This weekend, while flying home from <a href="http://www.10gen.com/events/mongosv-2011">MongoSV</a>, I could experience that same feeling in relation to first class concurrency support in programming languages. Everybody knows how the feature may be used, but I have the feeling that until one actually experiences it in practice, it&#8217;s very hard to really understand how much the relationship with ordering while developing software may be improved.</p>
<p>I was having some fun working on improvements to <a href="https://wiki.ubuntu.com/goetveld">Goetveld</a>. This package allows <a href="http://golang.org">Go</a> programs to communicate with <a href="https://codereview.appspot.com">Rietveld</a> servers to manipulate code review entries. The Rietveld API is a bit rough in a few places, and as a result some features of the package actually parse an HTML form to extract some data, before sending it back. You may have done something similar before while attempting to script a web site that wasn&#8217;t originally intended to be.</p>
<p>The interesting fact here is that this is an intrinsically serial procedure: load a form, change it, and send it back, right? Well, not really. As one might intuitively expect, establishing an SSL session and its underlying TCP connection are not instantaneous operations.</p>
<p>To give an idea, here is part of a dump of an SSL connection being <i>initiated</i> (that is, no HTTP data was sent yet) to codereview.appspot.com, originated from my home location:</p>
<pre>
# tcpdump -ttttt -i wlan0 'host codereview.appspot.com and port 443'
(...)
00:00:00.000000 IP (...)
00:00:00.000063 IP (...)
00:00:00.000562 IP (...)
00:00:00.341627 IP (...)
00:00:00.357009 IP (...)
00:00:00.357118 IP (...)
00:00:00.360362 IP (...)
00:00:00.360550 IP (...)
00:00:00.366011 IP (...)
00:00:00.689446 IP (...)
00:00:00.727693 IP (...)
</pre>
<p>That&#8217;s more than half a second before the application layer was even touched. So, turns out that to save that roundtrip time, we can start <i>both</i> the form loading and the form sending requests <i>at the same time</i>. By the time the form loading ends, processing the data locally is extremely fast, and we can complete the sending side by just providing the request body.</p>
<p>At this time you may be thinking something like <i>&#8220;Ugh, that&#8217;s too much trouble.. why bother?&#8221;</i>, and that highlights precisely the point I&#8217;d like to make: it is too much trouble because most people are used to languages that <i>turn</i> it into too much trouble, but the issue is not inherently complex. In fact, this is the entire implementation of this logic in Go:</p>
<pre>
func (r *Rietveld) UpdateIssue(issue *Issue) error {
        op := &#038;opInfo{r: r, issue: issue}
        errs := make(chan error)
        ch := make(chan map[string]string, 1)
        go func() {
                errs <- r.do(&#038;editLoadHandler{op: op, form: ch})
                close(ch)
        }()
        go func() {
                errs <- r.do(&#038;editHandler{op: op, form: ch})
        }()
        return firstError(2, errs)
}
</pre>
<p>I'm not cheating. The procedure was being done serially before, with very similar logic. Previously it had to take the form variable itself from the first request and manually provide it to the next one. Now, instead of providing the form, it's providing a channel that will be used to send the form across.  One might even argue that the channel makes the algorithm <i>more natural</i>, curiously.</p>
<p>This is the kind of procedure that becomes fun and natural to write, after having first class concurrency at hand for some time. But, as in the case of DVCS, it takes a while to get used to the idea that concurrency and simplicity are not necessarily at opposing ends.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2011/12/12/good-concurrency-changes-the-game/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Launchpad + Rietveld == HappyCodeReviews</title>
		<link>http://blog.labix.org/2011/11/17/launchpad-rietveld-happycodereviews</link>
		<comments>http://blog.labix.org/2011/11/17/launchpad-rietveld-happycodereviews#comments</comments>
		<pubDate>Fri, 18 Nov 2011 02:28:42 +0000</pubDate>
		<dc:creator>niemeyer</dc:creator>
				<category><![CDATA[Go]]></category>
		<category><![CDATA[Patch]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[RCS]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=849</guid>
		<description><![CDATA[In the past week, I&#8217;ve finally stopped to fix something that I&#8217;ve been wishing for years: inline code reviews in Launchpad. Well, I haven&#8217;t exactly managed fix it in Launchpad, but the integration with Rietveld feels nice enough to be &#8230; <a href="http://blog.labix.org/2011/11/17/launchpad-rietveld-happycodereviews">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In the past week, I&#8217;ve finally stopped to fix something that I&#8217;ve been wishing for years: inline code reviews in Launchpad. Well, I haven&#8217;t exactly managed fix it <i>in</i> Launchpad, but the integration with Rietveld feels nice enough to be relatively painless.</p>
<p>The integration is done using the <a href="https://launchpad.net/lbox">lbox</a> tool, that was developed in <a href="http://golang.org">Go</a> using the <a href="http://goneat.org/lp/lpad">lpad package</a> for the communication with Launchpad, and a newly written <a href="http://goneat.org/lp/goetveld/rietveld">rietveld package</a> for communication with Rietveld.</p>
<p>If you want to join me in my happines, here are the few steps to get that working for you as well.</p>
<p><span id="more-849"></span>First, install lbox from the Launchpad PPA. Since it&#8217;s written in Go, it has no dependencies.</p>
<pre>
$ sudo add-apt-repository ppa:gophers/go
$ sudo apt-get update
$ sudo apt-get install lbox
</pre>
<p>Now, as an example of using it, let&#8217;s suppose we want to perform a change in the lbox code itself. First, we take the branch out of Launchpad.</p>
<pre>
$ mkdir hacking
$ cd hacking
$ bzr branch lp:lbox
Branched 9 revision(s).
</pre>
<p>Then, let&#8217;s create a feature branch based on the original trunk, and perform a change.</p>
<pre>
$ bzr branch lbox my-nice-feature
Branched 9 revision(s).

$ cd my-nice-feature
$ echo # Yo >> Makefile
$ bzr commit -m "Yo-ified makefile"
Committing to: /home/user/hacking/my-nice-feature/
modified Makefile
Committed revision 10.
</pre>
<p>Ok, we&#8217;re ready for the magic step, which is actually pushing that branch and proposing the merge on the original branch on both Launchpad and Rietveld. It&#8217;s harder to explain than to do it:</p>
<pre>
$ lbox propose -cr
2011/11/17 23:29:49 Looking up branch information for "."...
2011/11/17 23:29:49 Looking up branch information for "hacking/lbox"...
2011/11/17 23:29:49 Found landing target: bzr+ssh://bazaar.../lbox/
(...)
</pre>
<p>This command will ask you for a few details interactively, like your authentication details in Launchpad and in Rietveld (your Google Account, details sent over SSL to Google itself; you may have to visit Rietveld first for that to work), and also the change description.</p>
<p>In case something fails, feel free to simply execute the command again, as many times as you want. The command is smart enough to figure that an existing merge proposal and change in Rietveld exist and will update the existing ones with the new details you provide, rather than duplicating work.</p>
<p>Once the command finishes, you can visit the URL for the merge proposal in Launchpad that was printed, and you should see something like this:</p>
<p><a href="http://blog.labix.org/wp-content/uploads/2011/11/lbox-lp-mp.jpg"><img src="http://blog.labix.org/wp-content/uploads/2011/11/lbox-lp-mp-1024x580.jpg" alt="" title="lbox-lp-mp" width="640" height="362" class="alignnone size-large wp-image-861"/></a></p>
<p>Note that the change description already includes a link onto the Rietveld issue at codereview.appspot.com. The issue on Rietveld will look something like this:</p>
<p><a href="http://blog.labix.org/wp-content/uploads/2011/11/lbox-rietveld.jpg"><img src="http://blog.labix.org/wp-content/uploads/2011/11/lbox-rietveld.jpg" alt="" title="lbox-rietveld" width="979" height="333" class="alignnone size-full wp-image-865" /></a></p>
<p>Observe how the issue has the same description as the merge proposal, but it links back onto the merge proposal. At the left-hand side, there&#8217;s also an interesting detail: the original merge proposal email has been added as the reviewer of this change. This means that any changes performed in Rietveld will be mailed back onto the merge proposal for its record.</p>
<p>In the center you can find the meat of the whole work: the actual change set that is being reviewed. Rietveld works with patch sets, so that you can not only see a given change, but you can also review the history of proposals that the proponent has made, and any inline comments performed in them.</p>
<p>Click on the side-by-side link next to Makefile to get an overview of the actual change, and to make comments on it just click on the desired line:</p>
<p><a href="http://blog.labix.org/wp-content/uploads/2011/11/lbox-rietveld-diff.jpg"><img src="http://blog.labix.org/wp-content/uploads/2011/11/lbox-rietveld-diff.jpg" alt="" title="lbox-rietveld-diff" width="986" height="628" class="alignnone size-full wp-image-867" /></a></p>
<p>Your comments won&#8217;t be sent immediately. Once you&#8217;re done making comments and want to deliver the review, click on the &#8220;Publish+Mail Comments&#8221; link at the top-right, which will take you onto a page that enables complementing with any heading details if desired.</p>
<p>Since the merge proposal is registered as the reviewer of the issue in Rietveld, publishing the review will deliver a message back onto the merge proposal itself, including context links that enable anyone to be taken to the precise review point back in Rietveld:</p>
<p><a href="http://blog.labix.org/wp-content/uploads/2011/11/lbox-lp-comment.jpg"><img src="http://blog.labix.org/wp-content/uploads/2011/11/lbox-lp-comment.jpg" alt="" title="lbox-lp-comment" width="776" height="275" class="alignnone size-full wp-image-870" /></a></p>
<p>Then, once you do make the suggested changes and want to publish a new version of the branch, simply repeat the original command: &#8220;lbox propose -cr&#8221;. This will push the new diff onto Rietveld and create a new patch set. You&#8217;ll also be given the chance to edit the previous description, and any changes there will take place both in the merge proposal and in the Rietveld issue.</p>
<p>lbox also has other useful command line options, such as -bug, -new-bug, to associate Launchpad bugs with the merge proposal and put them in progress, or -bp to associate a blueprint with the branch and bug (if provided) being handled.</p>
<p>This should turn your code reviews in Launchpad into significantly more pleasant tasks, and maybe even save some of your precious life time for more interesting activities.</p>
<p>Happy reviewing!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2011/11/17/launchpad-rietveld-happycodereviews/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Death of goroutines under control</title>
		<link>http://blog.labix.org/2011/10/09/death-of-goroutines-under-control</link>
		<comments>http://blog.labix.org/2011/10/09/death-of-goroutines-under-control#comments</comments>
		<pubDate>Sun, 09 Oct 2011 19:53:47 +0000</pubDate>
		<dc:creator>niemeyer</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[Snippet]]></category>
		<category><![CDATA[Test]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=717</guid>
		<description><![CDATA[Certainly one of the reasons why many people are attracted to the Go language is its first-class concurrency aspects. Features like communication channels, lightweight processes (goroutines), and proper scheduling of these are not only native to the language but are &#8230; <a href="http://blog.labix.org/2011/10/09/death-of-goroutines-under-control">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Certainly one of the reasons why many people are attracted to the <a href="http://golang.org">Go</a> language is its first-class concurrency aspects. Features like communication channels, lightweight processes (<i>goroutines</i>), and proper scheduling of these are not only native to the language but are integrated in a tasteful manner.</p>
<p><span id="more-717"></span>If you stay around listening to community conversations for a few days there&#8217;s a good chance you&#8217;ll hear someone proudly mentioning the tenet:</p>
<blockquote><p>Do not communicate by sharing memory; instead, share memory by communicating.</p></blockquote>
<p>There is a <a href="http://blog.golang.org/2010/07/share-memory-by-communicating.html">blog post</a> on the topic, and also a <a href="http://golang.org/doc/codewalk/sharemem/">code walk</a> covering it.</p>
<p>That model is very sensible, and being able to approach problems this way makes a significant difference when designing algorithms, but that&#8217;s not exactly news. What I address in this post is an open aspect we have today in Go related to this design: the <i>termination</i> of background activity.</p>
<p>As an example, let&#8217;s build a purposefully simplistic goroutine that sends lines across a channel:</p>
<pre>
type LineReader struct {
        Ch chan string
        r  *bufio.Reader
}

func NewLineReader(r io.Reader) *LineReader {
        lr := &#038;LineReader{
                Ch: make(chan string),
                r:  bufio.NewReader(r),
        }
        go lr.loop()
        return lr
}
</pre>
<p>The type has a channel where the client can consume lines from, and an internal buffer<br />
used to produce the lines efficiently. Then, we have a function that creates an initialized<br />
reader, fires the reading loop, and returns. Nothing surprising there.</p>
<p>Now, let&#8217;s look at the loop itself:</p>
<pre>
func (lr *LineReader) loop() {
        for {
                line, err := lr.r.ReadSlice('n')
                if err != nil {
                        close(lr.Ch)
                        return
                }
                lr.Ch <- string(line)
        }
}
</pre>
<p>In the loop we'll grab a line from the buffer, close the channel in case of errors and stop, or otherwise send the line to the other side, perhaps blocking while the other side is busy with other activities. Should sound sane and familiar to Go developers.</p>
<p>There are two details related to the termination of this logic, though: first, the error information is being dropped, and then there's no way to interrupt the procedure from outside in a clean way. The error might be easily logged, of course, but what if we wanted to store it in a database, or send it over the wire, or even handle it taking in account its nature? Stopping cleanly is also a valuable feature in many circumstances, like when one is driving the logic from a test runner.</p>
<p>I'm not claiming this is something <i>difficult</i> to do, by any means.  What I'm saying is that there isn't today an <i>idiom</i> for handling these aspects in a simple and consistent way. Or maybe there wasn't. The <i>tomb</i> package for Go is an experiment I'm releasing today in an attempt to address this problem.</p>
<p>The model is simple: a <i>Tomb</i> tracks whether the goroutine is alive, dying, or dead, and the death reason.</p>
<p>To understand that model, let's see the concept being applied to the LineReader example. As a first step, creation is tweaked to introduce Tomb support:</p>
<pre>
type LineReader struct {
        Ch chan string
        r  *bufio.Reader
        <span style="color: blue">t  tomb.Tomb</span>
}

func NewLineReader(r io.Reader) *LineReader {
        lr := &#038;LineReader{
                Ch: make(chan string),
                r:  bufio.NewReader(r),
        }
        go lr.loop()
        return lr
}
</pre>
<p>Looks very similar. Just a new field in the struct, and the function that creates it hasn't even been touched.</p>
<p>Next, the loop function is modified to support tracking of errors and interruptions:</p>
<pre>
func (lr *LineReader) loop() {
        <span style="color: blue">defer lr.t.Done()</span>
        for {
                line, err := lr.r.ReadSlice('n')
                if err != nil {
                        close(lr.Ch)
                        <span style="color: blue">lr.t.Kill(err)</span>
                        return
                }
                select {
                case lr.Ch <- string(line):
                <span style="color: blue">case <-lr.t.Dying():</span>
                        close(lr.Ch)
                        return
                }
        }
}
</pre>
<p>Note a few interesting points here: first, <i>Done</i> is called to track the goroutine termination right before the loop function returns. Then, the previously loose error now goes into the <i>Kill</i> Tomb method, flagging the goroutine as dying. Finally, the channel send was tweaked so that it doesn't block in case the goroutine is dying for whatever reason.</p>
<p>A Tomb has both <i>Dying</i> and <i>Dead</i> channels returned by the respective methods, which are closed when the Tomb state changes accordingly. These channels enable explicit blocking until the state changes, and also to selectively unblock select statements in those cases, as done above.</p>
<p>With the loop modified as above, a Stop method can trivially be introduced to request the clean termination of the goroutine synchronously from outside:</p>
<pre>
func (lr *LineReader) Stop() error {
        <span style="color: blue">lr.t.Kill(nil)</span>
        return <span style="color: blue">lr.t.Wait()</span>
}
</pre>
<p>In this case the <i>Kill</i> method will put the tomb in a dying state from outside the running goroutine, and <i>Wait</i> will block until the goroutine terminates itself and notifies via the <i>Done</i> method as seen before. This procedure behaves correctly even if the goroutine was already dead or in a dying state due to internal errors, because only the first call to Kill with an actual error is recorded as the cause for the goroutine death. The nil value provided to t.Kill is used as a reason when terminating cleanly without an actual error, and it causes Wait to return nil once the goroutine terminates, flagging a clean stop per common Go idioms.</p>
<p>This is pretty much all that there is to it. When I started developing in Go I wondered if coming up with a good convention for this sort of problem would require more support from the language, such as some kind of goroutine state tracking in a similar way to what <a href="http://www.erlang.org/doc/reference_manual/processes.html">Erlang does</a> with its lightweight processes, but it turns out this is mostly a matter of organizing the workflow with existing building blocks.</p>
<p>The tomb package and its Tomb type are a tangible representation of a good convention for goroutine termination, with familiar method names inspired in existing idioms. If you want to make use of it, <i>go get</i> the package with:</p>
<pre>
$ go get launchpad.net/tomb
</pre>
<p>The API documentation with details is available at:</p>
<p><span style="padding-left: 2em;"><a href="http://gopkgdoc.appspot.com/pkg/launchpad.net/tomb">http://gopkgdoc.appspot.com/pkg/launchpad.net/tomb</a></span></p>
<p>Have fun!</p>
<p><b>UPDATE 1:</b> there was <a href="https://groups.google.com/d/msg/golang-nuts/OD98q7sXRGA/DHRpI1QvRsQJ">a minor simplification</a> in the API since this post was originally written, and the post was changed accordingly.</p>
<p><b>UPDATE 2:</b> there was a <a href="https://groups.google.com/d/msg/golang-nuts/RaqfO3dg02c/QtmFxM65z64J">second simplification</a> in the API since this post was originally written, and the post was changed accordingly once again to serve as reference.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2011/10/09/death-of-goroutines-under-control/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Ensemble, Go, and MongoDB at Canonical</title>
		<link>http://blog.labix.org/2011/08/05/ensemble-go-and-mongodb-at-canonical</link>
		<comments>http://blog.labix.org/2011/08/05/ensemble-go-and-mongodb-at-canonical#comments</comments>
		<pubDate>Fri, 05 Aug 2011 03:49:14 +0000</pubDate>
		<dc:creator>niemeyer</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=706</guid>
		<description><![CDATA[About 1 year after development started in Ensemble, today the stars finally aligned just the right way (review queue mostly empty, no other pressing needs, etc) for me to start writing the specification about the repository system we&#8217;ve been jointly &#8230; <a href="http://blog.labix.org/2011/08/05/ensemble-go-and-mongodb-at-canonical">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>About 1 year after development started in <a href="https://ensemble.ubuntu.com">Ensemble</a>, today the stars finally aligned just the right way (review queue mostly empty, no other pressing needs, etc) for me to start writing the specification about the repository system we&#8217;ve been jointly planning for a long time. This is the system that the Ensemble client will communicate with for discovering which <a href="https://ensemble.ubuntu.com/docs/formula.html">formulas</a> are available, for publishing new formulas, for obtaining formula files for deployment, and so on.</p>
<p><span id="more-706"></span>We of course would have liked for this part of the project to have been specified and written a while ago, but unfortunately that wasn&#8217;t possible for several reasons. That said, there are also good sides of having an important piece flying around in minds and conversations for such a long time: sitting down to specify the system and describe the inner-working details has been a breeze. Even details such as the namespacing of formulas, which hasn&#8217;t been entirely clear in my mind, was just streamed into the document as the ideas we&#8217;ve been evolving finally got together in a written form. </p>
<p>One curious detail: this is the first long term project at <a href="https://www.canonical.com">Canonical</a> that will be developed in <a href="http://golang.org">Go</a>, rather than Python or C/C++, which are the most used languages for projects within Canonical. Not only that, but we&#8217;ll also be using <a href="http://www.mongodb.org">MongoDB</a> for a change, rather than the traditional <a href="http://www.postgresql.com">PostgreSQL</a>, and will also use (you guessed) the <a href="http://labix.org/mgo">mgo driver</a> which I&#8217;ve been pushing entirely as a personal project for about 8 months now.</p>
<p>Naturally, with so many moving parts that are new to the company culture, this is still being seen as a closely watched experiment. Still, this makes me highly excited, because when I started developing mgo, the MongoDB driver for Go, my hopes that the Go, MongoDB, and mgo trio would eventually be used at Canonical were very low, precisely because they were all alien to the culture. We only got here after quite a lot of internal debate, experiments, and trust too.</p>
<p>All of that means these are happy times. Important feature in Ensemble being specified and written, very exciting tools, home grown software being useful..</p>
<p>Awesomeness.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2011/08/05/ensemble-go-and-mongodb-at-canonical/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>The job market for Go</title>
		<link>http://blog.labix.org/2011/08/05/the-job-market-for-go</link>
		<comments>http://blog.labix.org/2011/08/05/the-job-market-for-go#comments</comments>
		<pubDate>Fri, 05 Aug 2011 03:38:11 +0000</pubDate>
		<dc:creator>niemeyer</dc:creator>
				<category><![CDATA[Go]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=701</guid>
		<description><![CDATA[I know there&#8217;s a lot of curiosity regarding Go&#8217;s growth and usage, and some people often ponder about whether they should invest on it since they don&#8217;t see hundreds of jobs in public sites, so would like to point something &#8230; <a href="http://blog.labix.org/2011/08/05/the-job-market-for-go">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I know there&#8217;s a lot of curiosity regarding <a href="http://golang.org">Go&#8217;s</a> growth and usage, and some people often ponder about whether they should invest on it since they don&#8217;t see hundreds of jobs in public sites, so would like to point something obvious, but which people often don&#8217;t realize:</p>
<p><i>You</i> are responsible for the market.</p>
<p><span id="more-701"></span>If you appreciate programming in Go, and understand the qualities of the language and the principles that the core team behind its development follow, it&#8217;s in your hands to make the language well known or not.</p>
<p>This can be as simple as blogging about it, or telling your coworkers or programmer friends about it, or maybe talking in user groups and conferences, running coding contests, etc. The core idea in all of that is making sure the right people are exposed to the language.</p>
<p>Note that this is not some kind of evil plan. We all like hearing about nice tools, and I would personally be glad to hear about other tools and languages people have to expose as well. The real point is just that we&#8217;re the ones building the future marketplace right now, and if we want Go to have a significant chunk of that marketplace because we like using it for our daily tasks, we better talk about why that is so.</p>
<p>It&#8217;s not about convincing.. it&#8217;s about exposing and explaining. People will have gone through similar pain as you have and will correlate to your experience, and then they can easily decide by themselves if Go is in a position to offer them a less painful life.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2011/08/05/the-job-market-for-go/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cut the rope, a tablet is NOT a laptop</title>
		<link>http://blog.labix.org/2011/07/19/cut-the-rope-a-tablet-is-not-a-laptop</link>
		<comments>http://blog.labix.org/2011/07/19/cut-the-rope-a-tablet-is-not-a-laptop#comments</comments>
		<pubDate>Tue, 19 Jul 2011 09:20:04 +0000</pubDate>
		<dc:creator>niemeyer</dc:creator>
				<category><![CDATA[Article]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Puzzle]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=662</guid>
		<description><![CDATA[Back in 2009 I quickly talked about the obvious revolution in computing that was rolling in the form of mobile phone as computer, and mentioned as well the fact that touch-based interfaces were going to dominate the marketplace because of &#8230; <a href="http://blog.labix.org/2011/07/19/cut-the-rope-a-tablet-is-not-a-laptop">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Back in 2009 I quickly <a href="http://blog.labix.org/2009/06/23/are-you-ready-for-the-mobile-revolution">talked about</a> the obvious revolution in computing that was rolling in the form of <i>mobile phone as computer</i>, and mentioned as well the fact that touch-based interfaces were going to dominate the marketplace because of that.</p>
<p>Move forward a couple of years, and last week I got my first tablet, running Android (a Samsung Galaxy Tab 10.1, if you&#8217;re curious).  I didn&#8217;t know exactly why I needed one, but being in the tech industry I always have that nice excuse for myself of buying things early on for learning about the experience of using them. Last night, I could clearly see this can be a real claim in some cases (in others it&#8217;s just an excuse for the wife).</p>
<p><span id="more-662"></span>After getting the tablet last week, I&#8217;ve started by experimenting with the usual stuff any person would (email, browser, etc), and then downloaded a few games to take on board a longish flight.  Some of them were pretty good.. a vertical scrolling shooter, a puzzle-solver, and so on.  On all of them, though, it took just a few minutes before the novelty of holding the screen in my hands for interacting with the game got old, and the interest went away with it.</p>
<p>This last night, though, I&#8217;ve decided to try another game from the top list, named <a href="https://www.youtube.com/watch?v=1JpdW-D6c14">Cut the Rope</a>, and this time I was immediately hooked into it.   That was certainly one of the most enjoyable gaming experiences I had in quite a while, and when going to bed I started to ponder about what was different there.</p>
<p>The game is obviously well executed, with cute drawings and sounds, and also smooth, but I think there was something else as well. In retrospect, the other games felt a lot like ports of a desktop/laptop experience.  The side scrolling game, for instance, was quite well suited for a joystick, and at least one other game had an actual joystick emulated on the screen, which is an enabler, but far from nice to be honest.</p>
<p>This one game, though, felt very well suited for a hands-based interaction: quickly drawing lines for cutting ropes, tapping on balloons to push air out, moving levers around, etc.  In some more advanced levels, it was clear that my dexterity (or lack thereof) was playing a much more important role in accomplishing the tasks than the traditional button/joystick version of it. This felt like an <i>entirely</i> novel gaming experience that just hadn&#8217;t happened yet.</p>
<p>It&#8217;s funny and ironic that I had this experience within a week from Microsoft <a href="http://www.zdnet.com/blog/mobile-news/-8216we-view-a-tablet-as-a-pc-microsoft-chooses-to-repeat-history/3267">reportedly saying</a> (<a href="http://www.ipadguys.com.au/ballmer-cracks-ipad-just-a-pc/">again!</a>) that a tablet is just another PC.  It&#8217;s not, and if they tried it out with some minimum attention they&#8217;d see why it&#8217;s so clearly not.</p>
<p>In that experience, the joystick felt familiar but at the same quite awkward to use, but using my hands naturally in an environment where that was suitable felt very pleasing. We can generalize that a bit and note a common way to relate to innovation: we first try to reuse the knowledge we have when facing a new concept, but when we understand the concept better quite often we&#8217;re able to come up with more effective and interesting ways to relate to it.</p>
<p>In the tablet vs. laptop/desktop thread, you probably won&#8217;t want to be typing long documents in a tablet, but would most likely prefer to shuffle items in an agenda with your fingers.  Also, you likely wouldn&#8217;t want to do that detailed CAD work with a fat finger in a screen, but would certainly be happy to review code or a document sitting in your backyard with the birds (no whales).</p>
<p>So, let&#8217;s please put that hammer away for a second while creating a most enjoyable touch-based experience.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2011/07/19/cut-the-rope-a-tablet-is-not-a-laptop/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Efficient algorithm for expanding circular buffers</title>
		<link>http://blog.labix.org/2010/12/23/efficient-algorithm-for-expanding-circular-buffers</link>
		<comments>http://blog.labix.org/2010/12/23/efficient-algorithm-for-expanding-circular-buffers#comments</comments>
		<pubDate>Thu, 23 Dec 2010 12:57:40 +0000</pubDate>
		<dc:creator>niemeyer</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Article]]></category>
		<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Lua]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Snippet]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=580</guid>
		<description><![CDATA[Circular buffers are based on an algorithm well known by any developer who&#8217;s got past the &#8220;Hello world!&#8221; days. They offer a number of key characteristics with wide applicability such as constant and efficient memory use, efficient FIFO semantics, etc. &#8230; <a href="http://blog.labix.org/2010/12/23/efficient-algorithm-for-expanding-circular-buffers">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Circular buffers are based on an algorithm well known by any developer who&#8217;s got past the <i>&#8220;Hello world!&#8221;</i> days.  They offer a number of key characteristics with wide applicability such as constant and efficient memory use, efficient FIFO semantics, etc.</p>
<p>One feature which is not always desired, though, it the fact that circular buffers traditionally will either overwrite the last element, or raise an overflow error, since they are generally implemented as a buffer of <i>constant</i> size.  This is an unwanted property when one is attempting to <i>consume</i> items from the buffer and it is not an option to blindly drop items, for instance.</p>
<p>This post presents an efficient (and potentially novel) algorithm for implementing circular buffers which preserves most of the key aspects of the traditional version, while also supporting dynamic expansion when the buffer would otherwise have its oldest entry overwritten. It&#8217;s not clear if the described approach is novel or not (most of my novel ideas seem to have been written down 40 years ago), so I&#8217;ll publish it below and let you decide.</p>
<p><span id="more-580"></span><b>Traditional circular buffers</b></p>
<p>Before introducing the variant which can actually expand during use, let&#8217;s go through a quick review on traditional circular buffers, so that we can then reuse the nomenclature when extending the concept.  All the snippets provided in this post are written in Python, as a better alternative to pseudo-code, but the concepts are naturally portable to any other language.</p>
<p>So, the most basic circular buffer needs the buffer itself, its total capacity, and a position where the next write should occur.  The following snippet demonstrates the concept in practice:</p>
<pre>
buf = [None, None, None, None, None]
bufcap = len(buf)
pushi = 0   

for elem in range(7):
    buf[pushi] = elem
    pushi = (pushi + 1) % bufcap

print buf # => [5, 6, 2, 3, 4]
</pre>
<p>In the example above, the first two elements of the series (0 and 1) were overwritten once the pointer wrapped around. That&#8217;s the specific feature of circular buffers which the proposal in this post will offer an alternative for.</p>
<p>The snippet below provides a full implementation of the traditional approach, this time including both the pushing and popping logic, and raising an error when an overflow or underflow would occur.  Please note that these snippets are not necessarily idiomatic Python.  The intention is to highlight the algorithm itself.</p>
<pre>
class CircBuf(object):

    def __init__(self):
        self.buf = [None, None, None, None, None]
        self.buflen = self.pushi = self.popi = 0
        self.bufcap = len(self.buf)

    def push(self, x):
        assert self.buflen == 0 or self.pushi != self.popi,
               "Buffer overflow!"
        self.buf[self.pushi] = x
        self.pushi = (self.pushi + 1) % self.bufcap
        self.buflen += 1

    def pop(self):
        assert self.buflen != 0, "Buffer underflow!"
        x = self.buf[self.popi]
        self.buf[self.popi] = None
        self.buflen -= 1
        self.popi = (self.popi + 1) % self.bufcap
        return x
</pre>
<p>With the basics covered, let&#8217;s look at how to extend this algorithm to support dynamic expansion in case of overflows.</p>
<p><b>Dynamically expanding a circular buffer</b></p>
<p>The approach consists in imagining that the same buffer can contain both a circular buffer area (referred to as <i>the ring area</i> from here on), and an overflow area, and that it is possible to transform a mixed buffer back into a pure circular buffer again.  To clarify what this means, some examples are presented below.  The full algorithm will be presented afterwards.</p>
<p>First, imagine that we have an empty buffer with a capacity of 5 elements as per the snippet above, and then the following operations take place:</p>
<pre>
for i in range(5):
    circbuf.push(i)

circbuf.pop() # => 0
circbuf.pop() # => 1

circbuf.push(5)
circbuf.push(6)

print circbuf.buf # => [<font style="color: blue">5, 6, 2, 3, 4</font>]
</pre>
<p>At this point we have a full buffer, and with the original implementation an additional push would raise an assertion error. To implement expansion, the algorithm will be changed so that those items will be appended at the end of the buffer.  Following the example, pushing two additional elements would behave the following way:</p>
<pre>
circbuf.push(7)
circbuf.push(8)

print circbuf.buf # => [<font style="color: blue">5, 6, 2, 3, 4,</font> <font color="red">7, 8</font>]
</pre>
<p>In that example, elements 7 and 8 are part of the overflow area, and the ring area remains with the same capacity and length of the original buffer. Let&#8217;s perform a few additional operations to see how it would behave when items are popped and pushed while the buffer is split:</p>
<pre>
circbuf.pop() # => 2
circbuf.pop() # => 3
circbuf.push(9)

print circbuf.buf # => [<font style="color: blue">5, 6,</font> None, None, <font style="color: blue">4,</font> <font style="color: red">7, 8, 9</font>]
</pre>
<p>In this case, even though there are two free slots available in the ring area, the last item pushed was still appended at the overflow area.  That&#8217;s necessary to preserve the FIFO semantics of the circular buffer, and means that the buffer may expand more than strictly necessary given the space available. In most cases this should be a reasonable trade off, and should stop happening once the circular buffer size stabilizes to reflect the production vs. consumption pressure (if you have a producer which constantly operates faster than a consumer, though, please look at the literature for plenty of advice on the problem).</p>
<p>The remaining interesting step in that sequence of events is the moment when the ring area capacity is expanded to cover the full allocated buffer again, with the previous overflow area being integrated into the ring area.  This will happen when the content of the previous partial ring area is fully consumed, as shown below:</p>
<pre>
circbuf.pop() # => 4
circbuf.pop() # => 5
circbuf.pop() # => 6
circbuf.push(10)

print circbuf.buf # => [<font style="color: blue">10,</font> None, None, None, None, <font style="color: blue">7, 8, 9</font>]
</pre>
<p>At this point, the whole buffer contains just a ring area and the overflow area is again empty, which means it becomes a traditional circular buffer.</p>
<p><b>Sample algorithm</b></p>
<p>With some simple modifications in the traditional implementation presented previously, the above semantics may be easily supported. Note how the additional properties did not introduce significant overhead. Of course, this version will incur in additional memory allocation to support the buffer expansion, bu that&#8217;s inherent to the problem being solved.</p>
<pre>
class ExpandingCircBuf(object):

    def __init__(self):
        self.buf = [None, None, None, None, None]
        self.buflen = self.ringlen = self.pushi = self.popi = 0
        self.bufcap = self.ringcap = len(self.buf)

    def push(self, x):
        if self.ringlen == self.ringcap or
           self.ringcap != self.bufcap:
            self.buf.append(x)
            self.buflen += 1
            self.bufcap += 1
            if self.pushi == 0: # Optimization.
                self.ringlen = self.buflen
                self.ringcap = self.bufcap
        else:
            self.buf[self.pushi] = x
            self.pushi = (self.pushi + 1) % self.ringcap
            self.buflen += 1
            self.ringlen += 1

    def pop(self):
        assert self.buflen != 0, "Buffer underflow!"
        x = self.buf[self.popi]
        self.buf[self.popi] = None
        self.buflen -= 1
        self.ringlen -= 1
        if self.ringlen == 0 and self.buflen != 0:
            self.popi = self.ringcap
            self.pushi = 0
            self.ringlen = self.buflen
            self.ringcap = self.bufcap
        else:
            self.popi = (self.popi + 1) % self.ringcap
        return x
</pre>
<p>Note that the above algorithm will allocate each element in the list individually, but in sensible situations it may be better to allocate additional space for the overflow area in advance, to avoid potentially frequent reallocation.  In a situation when the rate of consumption of elements is about the same as the rate of production, for instance, there are advantages in doubling the amount of allocated memory per expansion.  Given the way in which the algorithm works, the previous ring area will be exhausted before the mixed buffer becomes circular again, so with a constant rate of production and an equivalent consumption it will effectively have its size doubled on expansion.</p>
<p><b>UPDATE:</b> Below is shown a version of the same algorithm which not only allows allocating more than one additional slot at a time during expansion, but also incorporates it in the overflow area immediately so that the allocated space is used optimally.</p>
<pre>
class ExpandingCircBuf2(object):

    def __init__(self):
        self.buf = []
        self.buflen = self.ringlen = self.pushi = self.popi = 0
        self.bufcap = self.ringcap = len(self.buf)

    def push(self, x):
        if self.ringcap != self.bufcap:
            expandbuf = (self.pushi == 0)
            expandring = False
        elif self.ringcap == self.ringlen:
            expandbuf = True
            expandring = (self.pushi == 0)
        else:
            expandbuf = False
            expandring = False

        if expandbuf:
            self.pushi = self.bufcap
            expansion = [None, None, None]
            self.buf.extend(expansion)
            self.bufcap += len(expansion)
            if expandring:
                self.ringcap = self.bufcap

        self.buf[self.pushi] = x
        self.buflen += 1
        if self.pushi < self.ringcap:
            self.ringlen += 1
        self.pushi = (self.pushi + 1) % self.bufcap

    def pop(self):
        assert self.buflen != 0, "Buffer underflow!"
        x = self.buf[self.popi]
        self.buf[self.popi] = None
        self.buflen -= 1
        self.ringlen -= 1
        if self.ringlen == 0 and self.buflen != 0:
            self.popi = self.ringcap
            self.ringlen = self.buflen
            self.ringcap = self.bufcap
        else:
            self.popi = (self.popi + 1) % self.ringcap
        return x
</pre>
<p><b>Conclusion</b></p>
<p>This blog post presented an algorithm which supports the expansion of circular buffers while preserving most of their key characteristics.  When not faced with an overflowing buffer, the algorithm should offer very similar performance characteristics to a normal circular buffer, with a few additional instructions and constant space for registers only. When faced with an overflowing buffer, the algorithm maintains the FIFO property and enables using contiguous allocated memory to maintain both the original circular buffer and the additional elements, and follows up reusing the full area as part of a new circular buffer in an attempt to find the proper size for the given use case.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2010/12/23/efficient-algorithm-for-expanding-circular-buffers/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Vector clock support for Go</title>
		<link>http://blog.labix.org/2010/12/21/vector-clock-support-for-go</link>
		<comments>http://blog.labix.org/2010/12/21/vector-clock-support-for-go#comments</comments>
		<pubDate>Tue, 21 Dec 2010 18:03:47 +0000</pubDate>
		<dc:creator>niemeyer</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[Snippet]]></category>

		<guid isPermaLink="false">http://blog.labix.org/?p=564</guid>
		<description><![CDATA[One more Go library oriented towards building distributed systems hot off the presses: govclock. This one offers full vector clock support for the Go language. Vector clocks allow recording and analyzing the inherent partial ordering of events in a distributed &#8230; <a href="http://blog.labix.org/2010/12/21/vector-clock-support-for-go">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>One more Go library oriented towards building distributed systems hot off the presses: <a href="http://labix.org/govclock">govclock</a>. This one offers full <a href="http://en.wikipedia.org/wiki/Vector_clock">vector clock</a> support for the <a href="http://golang.org">Go language</a>.  Vector clocks allow recording and analyzing the inherent partial ordering of events in a distributed system in a comfortable way.</p>
<p>The following features are offered by govclock, in addition to basic event tracking:</p>
<p><span id="more-564"></span>
<ul>
<li>Compact serialization and deserialization
<li>Flexible truncation (min/max entries, min/max update time)
<li>Unit-independent update times
<li>Traditional merging
<li>Fast and memory efficient
</ul>
<p>If you&#8217;d like to know more about vector clocks, the Basho guys did a great job in the following pair of blog posts:</p>
<ul>
<li><a href="http://blog.basho.com/2010/01/29/why-vector-clocks-are-easy/">Why vector clocks are easy</a>
<li><a href="http://blog.basho.com/2010/04/05/why-vector-clocks-are-hard/">Why vector clocks are hard</a>
</ul>
<p>The following sample program demonstrates some sequential and concurrent events, dumping and loading, as well as merging of clocks.  For more details, please look at the <a href="http://labix.org/govclock">web page</a>.  The project is available under a BSD license.</p>
<pre>

package main

import (
    "launchpad.net/govclock"
    "fmt"
)

func main() {
    vc1 := govclock.New()
    vc1.Update([]byte("A"), 1)

    vc2 := vc1.Copy()
    vc2.Update([]byte("B"), 0)

    fmt.Println(vc2.Compare(vc1, govclock.Ancestor))   // => true
    fmt.Println(vc1.Compare(vc2, govclock.Descendant)) // => true

    vc1.Update([]byte("C"), 5)

    fmt.Println(vc1.Compare(vc2, govclock.Descendant)) // => false
    fmt.Println(vc1.Compare(vc2, govclock.Concurrent)) // => true

    vc2.Merge(vc1)

    fmt.Println(vc1.Compare(vc2, govclock.Descendant)) // => true

    data := vc2.Bytes()
    fmt.Printf("%#vn", string(data))
    // => "x01x01x01x01Ax01x01x01Bx01x00x01C"

    vc3, err := govclock.FromBytes(data)
    if err != nil { panic(err.String()) }

    fmt.Println(vc3.Compare(vc2, govclock.Equal))      // => true
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.labix.org/2010/12/21/vector-clock-support-for-go/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

