<?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"
	>

<channel>
<title>Bytepawn</title>
<atom:link href="http://bytepawn.com/feed.xml" rel="self" type="application/rss+xml" />
<link>http://bytepawn.com</link>
<description>Marton Trencseni on Software, Systems and other Ideas.</description>
<language>en</language>
<item>
<title>Git Cheatsheet for The Rest of Us</title>
<link>http://bytepawn.com/2010/08/13/git-cheatsheet-for-the-rest-of-us</link>
<guid isPermaLink='false'>http://bytepawn.com/2010/08/13/git-cheatsheet-for-the-rest-of-us</guid>
<pubDate>Fri, 13 Aug 2010 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
Here at <a href="http://scalien.com">Scalien</a> we've been git users for a while now, with <a href="http://github.com/scalien/keyspace">Keyspace being hosted on github</a>. We've had great experiences with both <a href="http://git-scm.com/">git</a> and <a href="http://github.com">Github</a>.
</p><p>
The distributed nature of git is wonderful: we are able to commit locally into the local repo, and later push to the main github repo. Cloning is a great way for everyone to create forks for experimenting around and adding smaller features. Although git in itself is pretty cool, Github is the "killer app": it makes source control management beatiful, gives us a nice clicky interface for repo admin tasks, and lets everyone clone easily. We pay $12 for the small plan, this gives us 10 private repos to keep stealth mode projects in stealth mode. I bought the <a href="http://progit.org/book/">Pro Git</a> book by <a href="http://twitter.com/CHACON">Scott Chacon</a> on Amazon for $23, who incidentally works at Github.
</p><p>
Git is all about the command line switches. Over the last couple of months, I've created a nice cheatsheet for our most common (non-trivial) git commands so we don't always end up googling them, mostly based on the Pro Git book and <a href="http://stackoverflow.com/">StackOverflow</a> QAs. It also contains the 2+1 major gotchas I've encountered:
</p><p>
<ol>
<li>Do not amend commits that you have pushed to a public repository!</li>
<li>Do not rebase commits that you have  pushed to a public repository!</li>
<li>Always update to the latest git major version (currently at 1.7.x)</li>
</ol>
</p><p>
Always keep these in mind and your co-developers won't hate you.
</p><p>
Finally, <a href="http://bytepawn.com/files/git.pdf"><b>here's the cheat sheet (PDF)</b></a>, and a preview:
</p><p>
<iframe src="http://docs.google.com/gview?embedded=true&url=http://bytepawn.com/files/git.pdf"
style="width:800px; height:600px;" frameborder="0"></iframe>
</p><p>
</p>]]></content:encoded>
</item>
<item>
<title>New Scalien Offices</title>
<link>http://bytepawn.com/2010/07/30/new-scalien-offices</link>
<guid isPermaLink='false'>http://bytepawn.com/2010/07/30/new-scalien-offices</guid>
<pubDate>Fri, 30 Jul 2010 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
We just settled in to the new Scalien offices. I've posted some <a href="http://www.flickr.com/photos/mtrencseni/sets/72157624614348814/detail/">pictures on Flickr</a>! We found that doing pair programming on the projector on the especially tricky parts of the code is the best way to get past big issues. We now have these pair programming sessions almost every day.
</p><p>
The full blog post is at the <a href="http://blog.scalien.com/2010/07/30/new-scalien-offices">Scalien Blog</a>.
</p>]]></content:encoded>
</item>
<item>
<title>Making Mysql safe for transactional usage</title>
<link>http://bytepawn.com/2010/05/06/making-mysql-safe-for-transactional-usage</link>
<guid isPermaLink='false'>http://bytepawn.com/2010/05/06/making-mysql-safe-for-transactional-usage</guid>
<pubDate>Thu, 06 May 2010 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
By default, Mysql is not safe to run in transactional mode and store mission critical data such as financial transactions. By <em>safety</em> I mean correctnessi wrt. gotchas and silent undesired behaviour. For example, a Mysql server was migrated to a new one, but the new one had skip-innodb turned on, which resulted in all tables becoming non-transactional. Thanks to other settings, this only resulted in warnings which went unnoticed for months. Or, by default, Mysql will insert the value "0xyz" into an INT column instead of issuing an error, although this is clearly some type of mistake. The default configuration is optimized to work well for a website such as a blog. This is OK, because most Mysql users are using it for just that. That is also why most "advanced" articles discuss how to tune Mysql performance, but I couldn't find good guides (eg. a checklist) on making in transactionally safe. For a list of gotchas, see the <a href="http://sql-info.de/mysql/gotchas.html">Mysql gotchas page</a>.
</p><p>
Here's my list of things to make Mysql safe(r) for transactional usage:
<ol>
</p><p>
<li>
<a href="http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html">Server SQL Modes</a>:
<ul>
<li>STRICT_ALL_TABLES: Enable strict mode for all storage engines. Invalid data values are rejected.</li>
<li>NO_ENGINE_SUBSTITUTION: Control automatic substitution of the default storage engine when a statement such as CREATE TABLE or ALTER TABLE specifies a storage engine that is disabled or not compiled in.</li>
<li>NO_ZERO_DATE: In strict mode, don't allow '0000-00-00' as a valid date. You can still insert zero dates with the IGNORE option. When not in strict mode, the date is accepted but a warning is generated.</li>
<li>NO_ZERO_IN_DATE: In strict mode, do not accept dates where the year part is nonzero but the month or day part is 0 (for example, '0000-00-00' is legal but '2010-00-01' and '2010-01-00' are not).</li>
<li>TRADITIONAL: Make MySQL behave like a “traditional” SQL database system. A simple description of this mode is “give an error instead of a warning” when inserting an incorrect value into a column.</li>
</ul>
</li>
</p><p>
<li>
<a href="http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html">Transaction isolation levels</a>: set this to SERIALIZABLE, then go down if necessary. The InnoDB default is REPEATABLE READ. The <a href="http://en.wikipedia.org/wiki/Isolation_%28database_systems%29">Wikipedia page on isolation</a> explains the difference between the levels (easy to forget) and gives some examples.
<ul>
<li>READ UNCOMMITTED: Barely transactional, this setting allows for so-called 'dirty reads', where queries inside one transaction are affected by uncommitted changes in another transaction.</li>
<li>READ COMMITTED: Committed updates are visible within another transaction. This means identical queries within a transaction can return differing results. This is the default in some DBMS's.</li>
<li>REPEATABLE READ: The default isolation level for InnoDB tables. Within a transaction, all reads are consistent.</li>
<li>SERIALIZABLE: Updates are not permitted in other transactions if a transaction has run an ordinary SELECT query, i.e. queries are treated as if they had a LOCK IN SHARE MODE, which we saw in action last month.</li>
</ul>
</li>
</p><p>
<li>
Set the default engine to InnoDB: you don't want to accidently end up with MyISAM tables. Unfortunately it's not possible to disable MyISAM altogether (there's no skip-myisam).
</li>
</p><p>
<li>
Set all defaults to UTF-8 to avoid character encoding issues. Use init-connect to force users' connections to use UTF-8, too.
</li>
</p><p>
<li>
Log all warnings: as far as I can tell, this is not possible in Mysql. This is a problem, for example if you try to rollback a transaction that wrote into a MyISAM table, that will only generate a warning. The best thing would be to have Mysql generate an error in this case (not possible), the second-best thing would be to log all warnings, but it seems there's no option for this. You can specify --show-warnings to the mysql client, but that won't help if you're trying to catch warning running in a stored procedure from a cronjob.
</li>
</p><p>
<li>
Make sure your hardware doesn't do extra chaching and doesn't reorder writes. The Mysql documentation says: On ATA/SATA disk drives, a command such hdparm -W0 /dev/hda may work to disable the write-back cache. Beware that some drives or disk controllers may be unable to disable the write-back cache.
</li>
</p><p>
<li>
Log slow queries which potentially block other transactions.
</li>
</p><p>
<li>
Use <a href="http://www.linux-mag.com/cache/7646/1.html">innotop</a> to keep and eye on your transaction workload.
</li>
</p><p>
</ol>
</p><p>
With that said, here's my my.cnf:
<pre>
[client]
port			= 3306
socket			= /var/run/mysqld/mysqld.sock
</p><p>
[mysqld_safe]
socket			= /var/run/mysqld/mysqld.sock
nice			= 0
</p><p>
[mysqld]
user			= mysql
pid-file		= /var/run/mysqld/mysqld.pid
socket			= /var/run/mysqld/mysqld.sock
port			= 3306
basedir			= /usr
datadir			= /var/lib/mysql
tmpdir			= /tmp
language		= /usr/share/mysql/english
bind-address		= 127.0.0.1
key_buffer		= 16M
max_allowed_packet	= 16M
thread_stack		= 128K
thread_cache_size	= 8
myisam-recover		= BACKUP
query_cache_limit       = 1M
query_cache_size        = 16M
max_binlog_size         = 100M
</p><p>
# the settings below make Mysql safe for transactional usage
transaction-isolation	= SERIALIZABLE
sql-mode		= STRICT_ALL_TABLES,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,TRADITIONAL
default-storage_engine	= innodb
init_connect		= 'SET collation_connection = utf8_general_ci; SET NAMES utf8;'
default-character-set	= utf8
character-set-server	= utf8
collation-server	= utf8_general_ci
</p><p>
log-warnings            = 2
log                     = /var/log/mysql.log
log-error		= /var/log/mysql.err
log_slow_queries        = /var/log/mysql-slow.log
long_query_time = 2
log-queries-not-using-indexes
</p><p>
skip-external-locking
skip-bdb
</p><p>
[mysqldump]
quick
quote-names
max_allowed_packet	= 16M
</p><p>
[isamchk]
key_buffer		= 16M
</p><p>
!includedir /etc/mysql/conf.d/
</pre>
</p><p>
If you think I missed something or have any suggestions, please post a comment!
</p>]]></content:encoded>
</item>
<item>
<title>New Logitech M705 Marathon Mouse</title>
<link>http://bytepawn.com/2010/05/02/new-logitech-m705-marathon-mouse</link>
<guid isPermaLink='false'>http://bytepawn.com/2010/05/02/new-logitech-m705-marathon-mouse</guid>
<pubDate>Sun, 02 May 2010 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
My old desktop mouse was a <a href="http://www.amazon.com/Logitech-MX1000-Laser-Cordless-Mouse/dp/B0002UM0JW">Logitech MX Laser</a>. I loved that thing, it fit in my hands just the way a mouse should, it has a nice scroll wheel and a back button (and some others I never used), it just worked. Here's a picture:
</p><p>
<img src="/images/mx.png" />
</p><p>
Unfortunately, the rubber started to come off it, so I went out to buy a new mouse. I don't like Microsoft mouse, their scrollwheel doesn't feel right, so I was pretty much looking for another Logitech model. It's surprising how hard it is to find a good mouse, but finally I found a <a href="http://www.amazon.com/Logitech-910-001229-Marathon-Mouse-M705/dp/B0034XRDUA/ref=sr_1_1?ie=UTF8&s=electronics&qid=1272822468&sr=1-1">Logitech M705 Marathon mouse</a>. The salesman said it goes 3 years with a pair of AA batteries, and that is a feat of engineering I felt I should invest in! In comparison, my old Logitech MX had to be recharged every week. So my new mouse is a Logitech M705 Marathon, this is what it looks like:
</p><p>
<img src="/images/marathon.jpg" />
</p><p>
I've been using it for about a week, and I can't say I'm terribly happy with it. It just doesn't feel right. First of all, it doesn't fit into my (abnormally large) hands like the old mouse did. But I could get over that. What's more annoying is a design flaw: in order for the back button to register that you have pushed it, you have to apply just enough force to it that you I inadvertadly move the mouse, sometimes the left side even lifts up. But I could get over that. What's really pushing my buttons is the acceleration curve. As we all know, the <a href="http://superuser.com/questions/5150/make-mac-os-x-mouse-acceleration-more-windows-like">acceleration curve is as it should be on Windows, and sucks on Macs</a>. Using the mouse is one of the few things I enjoy doing on Windows. That is unless you're using a Logitech M705 Marathon Mouse, which comes with some terrible acceleration curve by default. when you're using this mouse, you don't have to drink and get high to be all over the desktop and constantly overshoot the X to close a damned window. I had to install Logitech's crappy SetPoint driver thing just to get it to behave within reason.
</p><p>
So, overall my verdict to Logitech on the Marathon M705 is a gigantic FAIL!
</p><p>
PS: The heavy scroll wheel is really nice though!
</p><p>
EDIT: Also, the Logitech control panel thing forgets my mouse settings on reboot on Windows XP. Damn you Logitech, damn you!
</p>]]></content:encoded>
</item>
<item>
<title>Write frameworkey programs</title>
<link>http://bytepawn.com/2010/03/11/write-frameworkey-programs</link>
<guid isPermaLink='false'>http://bytepawn.com/2010/03/11/write-frameworkey-programs</guid>
<pubDate>Thu, 11 Mar 2010 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
We spend many hours a day pondering what separates successful programming projects from not-so successful ones. At the beginning we are enthusiastic and write lots of code, but towards the end we are often dissatisfied with the actual code — irrespective of whether it gets the job done! The problem is, many, if not most programs turn out to be <i>brittle</i>, and we know it.
</p><p>
This often happens even if we spend a great amount of time at the beginning specifying and designing the program. This is because by the end of 1.0, and later during the lifetime of the project requirements change as features are added, irrespective of the amount of planning that happens at the beginning. But no amount of planning will make a program designed to solve the original problem solve a different problem. That's just not what planning is about: planning is about fleshing out the original problem.
</p><p>
This is why, in many cases, redesigning a large program at 2.0 still results in a brittle program: the program is still specific to a single requirement, though by now a different one.
</p><p>
My conclusion — based on comparing my programs to better programmer's programs — is that one must write a domain-specific "framework" (*) that is more general than the original requirements, but admits the original requirements as a special case. This way, if requirements change — and they will — one has a chance of accomodating them. Even so, the original framework will certainly not be general enough, but it will be easier to adapt. The trick is, of course, to find just the right dimensions to generalize and just the right amount of generalizations.
</p><p>
(*) When I say domain-specific framework, I mean that the actual domain specific functionality is generalized in the program, versus just writing general functions for handling strings and linked lists while still encoding the domain specific functionality in a brittle manner.
</p>]]></content:encoded>
</item>
<item>
<title>Recent papers (2009)</title>
<link>http://bytepawn.com/2010/01/26/recent-papers-2009</link>
<guid isPermaLink='false'>http://bytepawn.com/2010/01/26/recent-papers-2009</guid>
<pubDate>Tue, 26 Jan 2010 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
I collected a bunch of papers I wrote last year, inlcuding <a href="http://scalien.com/whitepapers">Scalien whitepapers</a>, a <a href="http://fsf.hu">Free Software Foundation</a> conference paper (in hungarian) and a short literature review of a physics book.
</p><p>
<ol>
<li><a href="http://scalien.com/pdf/Keyspace.pdf">Keyspace whitepaper</a>: the distributed database which is currently Scalien's primary product, under heavy development!</li>
<li><a href="http://scalien.com/pdf/PaxosLease.pdf">PaxosLease whitepaper</a>: describes the Paxos-varaint invented by my co-authors and myself for negotiating distributed leases (time expiring locks) in a consistent manner.</a></li>
<li><a href="http://scalien.com/pdf/FSFConf2009.pdf">Paper</a> on open-source distributed systems for the 2009 <a href="http://fsf.hu">FSF</a> conference (in hungarian)</li>
<li><a href="http://bytepawn.com/pdf/Exciting.pdf">The Exciting physics of an Excited universe</a>: a literature review paper of <a href="http://www.amazon.com/Compact-Stars-Relativity-Astronomy-Astrophysics/dp/0387989773/ref=sr_1_1?ie=UTF8&s=books&qid=1264500100&sr=8-1">Norman Glendenning's book Compact stars</a>, talks about neutron stars, pulsars and strange stars.</li>
</ol>
</p><p>
You should of course use the <a href="https://addons.mozilla.org/en-US/firefox/addon/14226/">Google Docs Preview</a> Firefox addon for previewing PDF files!
</p>]]></content:encoded>
</item>
<item>
<title>The Confused World of "NoSQL"</title>
<link>http://bytepawn.com/2009/11/28/the-confused-world-of-nosql</link>
<guid isPermaLink='false'>http://bytepawn.com/2009/11/28/the-confused-world-of-nosql</guid>
<pubDate>Sat, 28 Nov 2009 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
Non-relational datastores are usually thrown together under the umbrella term "NoSQL", which recently just got its own <a href="http://en.wikipedia.org/wiki/NoSQL">Wikipedia entry</a>. Just as the Wikipedia entry, the world of "NoSQL" is changing quickly. Here I will differentiate the different use-cases and motivations for using and building such systems.
</p><p>
<br/>
<center><img src="/images/babel.jpg" /><br/><em>Tower of Babel</em></center>
<br/>
</p><p>
<b>"NoSQL" and scalability.</b> The original inspiration for many open-source projects is that large players like Google and Amazon chose not to use Mysql or Oracle in certain cases and developed in-house systems for scalability reasons, meaning storage, availability and performance scalability (see my <a href="http://bytepawn.com/readings-in-distributed-systems/">Readings in Distributed Systems</a> for more on these). There is a number of open-source projects which follow in these steps (like our own <a href="http://scalien.com">Keyspace</a> datastore and our <a href="http://scalien.com/whitepapers">PaxosLease algorithm</a>), trying to build truly scalable software. These systems are "NoSQL" because distributing complex relational operations across nodes is complicated, and these systems are to be used in performance intensive applications anyways, where key-value datastores are a good basis for optimization in the application layer. Unfortunately, the space of truly distributed open-source software is contaminated by virtually every non-relational project claiming to be distributed and scalable.<br/>
Systems in this category: Keyspace, Apache Hadoop, Cassandra
</p><p>
<b>"NoSQL" and SQL.</b> Some have claimed that "NoSQL" is not so much about getting rid of SQL as it is about building something scalable; but this is not true in general. The primary use-case here is CouchDB, which is getting a lot of attention from web developers who like its simple, REST-based data model and query facilities. CouchDB is written in Erlang and is fairly slow, so it cannot be taken seriously as a scalable system in the sense above, and most CouchDB users are not scaling their installation. CouchDB is a light-weight solution for web apps, similar to Microsoft Access / Lotus Notes in the bussiness world. Many web developers are non-advanced users of SQL anyway, not using "advanced" features like foregin keys, JOINs, inner queries or stored procedures. These users choose CouchDB (over an ORM layer) to get rid of ugly embedded SQL code which doesn't do much for them anyway. I believe there <em>is</em> a portion of "NoSQL" users who are trying to get rid of SQL.<br/>
Systems in this category: Redis, CouchDB
</p><p>
<b>"NoSQL" and UNIX.</b> Many proponents like "NoSQL" data stores because they adhere to the UNIX philosophy of building small, lightweight tools for a specific purpose but of general applicability: "do one thing well". Uncontroversially, relational databases do not adhere to the UNIX philosophy: they are large multi-million line code bases of non-trivial complexity and runtime characteristics. (On the other hand, they have stood the test of time and become the most successful and lucrative data model in computer science). This is one of the reason why projects like Memcached are put under the "NoSQL" umbrella, even though it's not a persistent datastore and as such not competition for a relational database. Also noteworthy are BerkeleyDB and Tokyo, which are low-level key-value storage engines that can be used to build more complex datastores (Mysql used to have a BDB engine, Keyspace 1.x uses BDB).<br/>
Systems in this category: Memcached, BerkeleyDB, Tokyo
</p><p>
I believe it would be beneficial to seperate these use-cases and treat them differently (eg. call one NoSQL and the other DDS for Distributed Data Store). While some of them concentrate on implementing good distributed algorithms, others concentrate on making web developer's lifes easier. Both are valid use-cases and noble goals. Clearly, the former may have less trendy API facilities, while the latter may be easier to setup and administer but slower. This is not a put-down, though, it resembles comparing PHP to C++: one of them gives you easy entry and rapid development cycles, while the other gives you raw speed at the expense of compiled code and pointers. But treating them under the same umbrella, as many presentations do, is confusing. It gives the impression of "Pick ONE" or "ONE will survive", which goes against the basic tenet of specialization and UNIX, the starting point of "NoSQL" datastores. Also, people looking to scale terabytes of data may not be interested in CouchDB while people looking to replace Mysql for their simple in-house web apps may not be interested in Hadoop.
</p>]]></content:encoded>
</item>
<item>
<title>Google Wave Has Hit My Shores</title>
<link>http://bytepawn.com/2009/11/09/google-wave-has-hit-my-shores</link>
<guid isPermaLink='false'>http://bytepawn.com/2009/11/09/google-wave-has-hit-my-shores</guid>
<pubDate>Mon, 09 Nov 2009 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
Last week I got my <a href="http://wave.google.com/help/wave/about.html">Google Wave</a> (GW) invite, and we were able to get a group of friends, roughly ~10 people also invited within a few days. This is fortunate, because it allows me to actually use GW to communicate and collaborate with a common set of people. The short story is: Google Wave has rocked our world, we produced a high number of waves and blips within a few days (blips are the actual comments in GW terminology), much more than we would have using email in the same time period. I estimate the volume of communication increased 2-5x. Aside from volume, GW also changed the nature of communication: this group did not use IM before, but several instances of real-time chatting occured within GW. Also, GW opened new channels between people, eg. I chatted with a person I usually only talk to in real-life (and rarely). Overall, the "synchronous and asynchronous" nature of GW is a real killer feature. Even the characters-in-real-time feature (meaning you can see the other's keystrokes in real-time, which is sometimes annoying and too much) is overall a good feature, because it engages the parties. GW is such a pleasant communication platform that even the alpha-as-in-buggy-as-hell web interface, uncharacteristic of Google, has not deterred us from using it. Overall I think GW is a game-changer: this group has not exchanged a single email since we all got on GW. I'm trying to get other groups onto GW as soon as possible.
</p><p>
<img src="/images/google_wave_logo.png" />
</p><p>
Based on these experiences, GW definitely qualifies as a disruptive technology. It's pretty clear that GW is going to decrease the importance of email and IM. Also, several use-cases which required special web-based software for convenience will move to GW, such as: event planning, todos, reminders, bookmarking, notetaking, collaborative draft editing, online meetings, mini-blogs. These are all use-cases which are pretty much possible with the default GW web interface, or require little additinal functionality.
</p><p>
Google Wave is a product which will markedly increase the productivity of large corporations. Novell is already working on a <a href="http://www.google.hu/search?sourceid=chrome&ie=UTF-8&q=novell+pulse">product dubbed Google Wave for the Enterprise, called Novell Pulse</a>. I watched their <a href="http://www.novell.com/media/media.php?media=novell-pulse">video presentation</a>, and it looks good. Also look at the <a href="http://wave.google.com/help/wave/extensions.html">SAP presentation on the bottom of this page</a>, which is a bit more enterprisey, but still pretty nice. I wonder what Microsoft's answer will be. I hope they don't come up with an incompatible-but-equivalent implementation.
</p><p>
In conclusion, Google Wave is still relatively young and immature (even Google's client sucks), lots of space for movement and innovation, it will be interesting to see how the ecosystem and monetization game unfolds.
</p>]]></content:encoded>
</item>
<item>
<title>SSD Reading List</title>
<link>http://bytepawn.com/2009/10/18/ssd-reading-list</link>
<guid isPermaLink='false'>http://bytepawn.com/2009/10/18/ssd-reading-list</guid>
<pubDate>Sun, 18 Oct 2009 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
As part of the preparatory work of replacing BerkeleyDB with our own storage engine in <a href="http://scalien.com">Keyspace</a>, I've been looking at papers about SSD technology. It looks like SSDs will replace spinning disks in a couple of years, and in anticipation of this we're looking into the possibility of optimizing the engine for its characteristics: cheap random reads, potentially expensive writes because of erases behind complex on-disk logic called the Flash Tranlation Layer (FTL). Here are some good resources I found.
</p><p>
<ol>
<li><a href="http://www.anandtech.com/printarticle.aspx?i=3531">Anandtech's overview (must read)</a></li>
<li><a href="http://www.cs.arizona.edu/~bkmoon/papers/dasfaa09.pdf">In-Page Logging B-Tree for Flash Memory [pdf]</a></li>
<li><a href="http://db-event.jpn.org/idb2008/invited_talks/iDB3a_Lee.pdf">Overview slides (good) [ppt]</a></li>
<li><a href="http://arxiv.org/pdf/0909.1780">uFLIP: Understanding Flash IO Patterns (must read, CIDR best paper) [pdf]</a></li>
<li><a href="http://www.comp.hkbu.edu.hk/~pgday/2009/10th_papers/yli.pdf">Optimize write performance for DBMS on Solid State Drive [pdf]</a></li>
<li><a href="http://www.cs.umass.edu/~dganesan/papers/VLDB09-LATree.pdf">Lazy-Adaptive Tree: An Optimized Index Structure for Flash Devices (VLDB) [pdf]</a></li>
<li><a href="http://www.cse.ust.hk/catalac/users/yinanli/fdtree/fdtree_pvldb.pdf">Tree Indexing on Solid State Drives (VLDB) [pdf]</a></li>
<li><a href="http://lwn.net/Articles/353411/">Log-structured file systems: There's one in every SSD</a></li>
</ol>
</p><p>
Two notes: First, the uFLIP paper is particularly good. Second, it seems that the In-Page Logging (IPL) paper assumes direct control of read/write/erase cycles of the SSD, which is not realistic for off-the-shelf consumer drives like the <a href="http://www.google.com/search?hl=en&q=intel%20x25m&aq=f&oq=&aqi=">Intel X25-M</a>, which include a complex FTL.
</p><p>
Finally, while putting together this list I found a much <a href="http://staff.ustc.edu.cn/~jpq/flash.html">longer list of SSD papers here</a>, also worth taking a look.
</p>]]></content:encoded>
</item>
<item>
<title>Google Docs Preview Firefox Addon</title>
<link>http://bytepawn.com/2009/09/10/google-docs-preview-firefox-addon</link>
<guid isPermaLink='false'>http://bytepawn.com/2009/09/10/google-docs-preview-firefox-addon</guid>
<pubDate>Thu, 10 Sep 2009 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
<a href="https://addons.mozilla.org/en-US/firefox/addon/14226/">
<img src="/images/ffox_addons_screenshot.png" border="0" /><br/><br>
Download the Google Docs Preview Firefox Addon here.</a>
</p><p>
Google has exported their very cool web-based PDF viewer. You can use it by telling it what PDF file to open like this:
</p><p>
<pre>http://docs.google.com/gview?url=<b>PDF_URL</b></pre>
</p><p>
For example, here is the Keyspace whitepaper shown in Google Docs Preview:
</p><p>
<a href="http://docs.google.com/gview?url=http://scalien.com/pdf/Keyspace.pdf">http://docs.google.com/gview?url=http://scalien.com/pdf/Keyspace.pdf</a>
</p><p>
You can also embed it in an IFRAME like this:<pre>
&lt;iframe src="http://docs.google.com/gview?embedded=true&url=<b>PDF_URL</b>"
style="width:800px; height:600px;" frameborder="0"&gt;&lt;/iframe&gt;
</pre>
</p><p>
For example, here is the Keypspace whitepaper shown embedded:
</p><p>
<iframe src="http://docs.google.com/gview?embedded=true&url=http://scalien.com/pdf/Keyspace.pdf" style="width:800px; height:600px;" frameborder="0"></iframe>
</p><p>
I hacked together a Firefox addon that lets you open any PDF file from Firefox using the Google Docs Preview: <a href="https://addons.mozilla.org/en-US/firefox/addon/14226/">download here.</a> It lets you specify whether to
</p><p>
<ol>
<li>Open in the same or a new tab</li>
<li>Whether to focus the new tab</li>
</ol>
</p><p>
Here's a screeshot:
</p><p>
<img src="/images/gdp_preview.png" />
</p>]]></content:encoded>
</item>
<item>
<title>Keyspace whitepaper</title>
<link>http://bytepawn.com/2009/07/23/keyspace-whitepaper</link>
<guid isPermaLink='false'>http://bytepawn.com/2009/07/23/keyspace-whitepaper</guid>
<pubDate>Thu, 23 Jul 2009 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
I've added the <a href="http://scalien.com/keyspace">Keyspace</a> <a href="http://scalien.com/whitepapers">whitepaper</a> to section III of my <a href="/readings-in-distributed-systems">Readings in Distributed Systems</a>.
</p><p>
<blockquote>
This paper describes the design and architecture of Keyspace, a distributed key-value store offering strong consistency, fault-tolerance and high availability. The source code is released as free, open-source software under the GNU Affero General Public License (AGPL). Keyspace is a product of Scalien Software, available for download at http://scalien.com
</blockquote>
</p><p>
I'm one of the developers of Keyspace, have a look at it!
</p><p>
Next up: finish up the paper on PaxosLease, a diskless Paxos variant (similar to Fatlease) we have developed while working on Keyspace.
</p>]]></content:encoded>
</item>
<item>
<title>Scalable Web Architectures and Application State</title>
<link>http://bytepawn.com/2009/06/17/scalable-web-architectures-and-application-state</link>
<guid isPermaLink='false'>http://bytepawn.com/2009/06/17/scalable-web-architectures-and-application-state</guid>
<pubDate>Wed, 17 Jun 2009 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
<i>In this article we follow a hypothetical programmer, Damian, on his quest to make his web application scalable.</i>
</p><p>
In the early 2000s Damian built a website for fellow gamers interested in the magic game dungeons and dragons. The site was simple, as it listed various properties of magic items and featured a messageboard. Damian used the <a href="http://en.wikipedia.org/wiki/LAMP_(software_bundle)">LAMP stack</a>: data about items was stored in Mysql, and various PHP scripts let the visitors of the site view items and statistics.
</p><p>
Now fast forward to 2009. Damian's site has evolved to a web game for playing dungeons online, in your browser. Damian is still using LAMP. Data about types of games (including parameters such as monster strength), user data (including status information), and data about active games (including players, the monters's health) are still stored in Mysql. It's all fine until there are only a few games in session and only a couple hundred players, but as the site gets popular, Damian's server is starting to see high load numbers.
</p><p>
Damian is experiencing scalability issues --- his current setup cannot handle tens of thousands of users. He searches the web and buys some books about Mysql, and starts <i>optimizing</i>:
<ul>
<li>tweaking Mysql parameters</li>
<li>tweaking Apache parameters</li>
<li>moving to a dedicated server</li>
<li>buying more RAM</li>
<li>denormalizing tables</li>
<li>optimizing SQL queries</li>
<li>optimizing indexes</li>
</ul>
</p><p>
Each of these tweaks buys him more time, but the users keep on coming, and the load factor keeps creeping up. Damian reads even more articles, buy some more books, and gets his hands dirty <i>scaling</i> his system:
<ul>
<li>discovers <a href="http://www.danga.com/memcached/">Memcached</a>, and starts caching some SQL queries</li>
<li>discovers Lighttpd, uses it to serve static content like images</li>
<li>buys a second dedicated server to spread Mysql reads</li>
<li>buys more RAM for the second server</li>
<li>...</li>
</ul>
</p><p>
As even more users register, the load is becoming unbearable. Damian discovers <a href="http://aws.amazon.com/">Amazon EC2</a>...
</p><p>
Hold on a minute. What's going on here? Let's think for a second.
</p><p>
Most of Damian's problems are related to Mysql. Suppose we were not living the glorious Web2.0 days and you were writing what's basically an application server. Would you store <i>everything</i>, including state information in a database? No, of course not. You would store some information in the database, read it out when the application server launches, perform computation for the clients, and write data meant to be persistent back to the database. This is what Damien really needs. Damian needs a fast racecar, but his initial design resulted in a bike, and now he's frantically trying to turn the bike into a car by welding two bikes together and putting rocket boosters in the back.
</p><p>
<center><img width="500" src="/images/carbike.jpg" /></center>
<br/>
<center><img width="500" src="/images/enzo.jpg" /></center>
</p><p>
Damian does not need fundamentally new software. He does not need a custom application server, nor could you convince him to write one. What he needs is the insight to identify state, cached data and persistent data in his application. Application state goes into an in-memory key-value store like <a href="http://tokyocabinet.sourceforge.net/tyrantdoc/">Tokyo Tyrant</a>. Cache data goes into <a href="http://www.danga.com/memcached/">Memcached</a>. Persistent data goes into a database. Note that the seperation of code and application state may be beneficial later, because it allows you to scale easily by adding new memory servers. Mysql will probably need to be left behind for a persistent key-value store that is more easily distributed and replicated. As co-founder of <a href="http://scalien.com">Scalien</a> and one of the developers of our <a href="http://scalien.com/keyspace">Keyspace</a> replicated key-value store, I can only recommend it. It's devilishly fast for consistently replicated writes.
</p><p>
When the server launches, before client requests are served, a script initializes the system by loading the appropriate state data into memory. Client requests are served primarily by using state information (global and per-user, per-game, per-session, etc.), and sometimes persistent data is written back to disk. Data that isn't absolutely essential, like an in-game chat transcript are written to disk asynchronously in the background.
</p><p>
Let's call this the Code-State-Cache-Data (CSCD) pattern. What Damian originally had was a Code-Data (CD) pattern, and later he optimized to get a Code-Cache-Data (CCD) pattern. It is my opinion that writing applications in the CSCD pattern is not substantially harder than the standard CD or CCD pattern. But it is a <i>smarter</i> architecture because it identifies data for what it is: state, cache and persistent data. It is a <i>faster</i> architecture, as more clients can be served with a single server. Additionally, it is a more <i>scalable</i> architecture, especially if Mysql is replaced with a distributed key-value store. Finally, it is <i>pragmatic</i>, because it uses existing components and existing practices only change slightly.
</p><p>
Let's keep in mind that there is no silver bullet. With a CSCD pattern, Damian will still have to do optimizations like tweaking Apache or buying more RAM, but he is optimizing to make a smart architecture run fast, instead of caching the hell out of a slow architecture.
</p><p>
What I'm saying here isn't anything radical or even new, but most web application are still written in the LAMP+CD pattern. Hopefully this article will lead to more scalable designs where code, state, cache and data are seperated to yield better performance.
</p>]]></content:encoded>
</item>
<item>
<title>Thoughts on Yahoo's PNUTS distributed database</title>
<link>http://bytepawn.com/2009/02/15/thoughts-on-yahoos-pnuts-distributed-database</link>
<guid isPermaLink='false'>http://bytepawn.com/2009/02/15/thoughts-on-yahoos-pnuts-distributed-database</guid>
<pubDate>Sun, 15 Feb 2009 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
I've updated the <a href="/readings-in-distributed-systems">Readings in Distributed Databases</a> with <a href="http://www.google.com/search?client=opera&rls=en&q=yahoo+pnuts&sourceid=opera&ie=utf-8&oe=utf-8">Yahoo's new PNUTS paper.</a>
</p><p>
PNUTS is Yahoo's in-house distributed tablestore used for serving some of its web properties. The goal in this post is finding out the basics: how replication is managed, what kind of guarantees the system makes, can branching occur...
</p><p>
<em>Note: this post may contain misunderstandings and it definitely contains speculations!</em>
</p><p>
Reading the paper, it hits an interesting spot in design space. One of the major goals is geographic replication: reads and writes of data belonging to a user in India should be fast from India. But the same data is also accessed from different points on the globe, but these are most likely reads. It's acceptable if these "remote reads" see an older version of the data, as long as the versions are not branching (see below). Summing up: reads should be fast everywhere and may return older versions, writes should be fast locally (in the same datacenter).
</p><p>
The article states that they want to avoid branching versions of data. <a href="http://www.google.com/search?client=opera&rls=en&q=paxos+made+simple&sourceid=opera&ie=utf-8&oe=utf-8">Paxos</a>, however, is out of the question here, since they may have as many as 10 replicas all geographically seperated, with 50-100 ms latencys. Since they're not using Paxos, it seems it is possible for divergent versions to occur in Yahoo's system. It's not clear to me what they're doing about this, the following quote is a "future plan":
</p><p>
<blockquote>Under normal operation, if the master copy of a record fails, our system has protocols to fail over to another replica. However, if there are major outages, e.g. the entire region that had the master copy for a record becomes unreachable, updates cannot continue at another replica without potentially violating record-timeline consistency. We will allow applications to indicate, per-table, whether they want updates to continue in the presence of major outages, potentially branching the record timeline. If so, we will provide automatic conflict resolution and notifications thereof. The application will also be able to choose from several conflict resolution policies: e.g., discarding one branch, or merging updates from branches, etc.
</blockquote>
</p><p>
To come as close as possible to a "no branching" behavior, PNUTS uses a a 3-tiered architecture: there are 1. clients who initiate read and write operations, 2. the Yahoo Message Broker (MB) which they use as a basic replication primitive, and 3. geographically replicated storage nodes. The storage nodes use a master mechanism, where the master node is usually the one geographically closest to where the writes originate (in the same datacenter).
</p><p>
<center>
<img src="/images/branching.jpg" /><br/>
<em>Branching.</em>
</center>
</p><p>
As far as I can tell, a write is managed like this: the client initiates the write operation at the master storage node. The node passes the write request on to the MB. The write is considered commited if the MB says it commited it. The master, if it doesn't go down in the meanwhile, performs the write on its local data. The MB guarantees that it will deliver the write operation to the other replicas. The nice property of this setup is that if the master and the MB are in the same datacenter as the client then they don't have to wait for the replicas in distant datacenters to commit to their disks --- this is handled and waited on later by the MB.
</p><p>
The MB is not discussed in this or any other paper. I think it may be made up of n=3 Paxos cells. They say that there are many message brokers, which if I'm right means many Paxos cells. Write operations stored within a MB cell are guaranteed to be delivered in that order to the replicas (this seems easy), but what about writes (of the same data) stored in different MB cells? Here the paper is somewhat confusing to me. They write:
</p><p>
<blockquote>We provide per-record timeline consistency: all replicas of a given record apply all updates to the record in the same order.</blockquote>
</p><p>
and
</p><p>
<blockquote>.. in order to provide timeline consistency, we have developed a per-record mastership mechanism, and the updates published by a record's master to a single YMB cluster are delivered in the published order to the other replicas.</blockquote>
</p><p>
The second quote above seems to imply that the first one is only true for writes coming from the same MB cell. 
</p><p>
Basically, the trick is that write operations are handed over to a MB cell, which then acts as a single logical writer. What happens if there is a master-failover and the new master publishes to a different MB? Given that the MB cells themselves are not in some sort of higher level Paxos cell, and the storage nodes also are not in a Paxos cell, I think all bets are off at this point and branching versions can come in, as discussed at the beginning.
</p><p>
Of course, since you cannot put replicas in different datacenters in a Paxos cell, you are forced to do something like this! It's an interesting approach, as it's somewhere between a full-on Paxos like in <a href="http://labs.google.com/papers/chubby.html">Google's Chubby</a>, and full-on branching like in <a href="http://www.google.com/search?hl=en&client=opera&rls=en&hs=eS9&q=Dynamo%3A+Amazon%E2%80%99s+Highly+Available+Key-value+Store&btnG=Search">Amazon's Dynamo</a>. The architecture is interesting to say the least, but my question is this: if the user has to prepare for branching and has to write the conflict resolution code, wouldn't a Dynamo-like (with some basic logic to always choose local nodes to write to) system be simpler and possibly faster?
</p>]]></content:encoded>
</item>
<item>
<title>My Startup Manifesto</title>
<link>http://bytepawn.com/2009/01/25/my-startup-manifesto</link>
<guid isPermaLink='false'>http://bytepawn.com/2009/01/25/my-startup-manifesto</guid>
<pubDate>Sun, 25 Jan 2009 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
This is my startup manifesto.
<h2>1. Professional and/or financial success</h2>
Gauge the software market and look for a need, a use-case that is not being fulfilled properly. Build something useful and try to market it (financial success). If your bussiness fails, just release your software as open-source. Build non-trivial things, and make sure the architecture and code is examplary, so even if financial success eludes you, your software is valuable on its own and earns the respect of your peers (professional success). Use technologies that will withstand the test of time.
</p><p>
<center>
<img src="/images/ying-yang.jpg" /><br/>
<em>Professional and financial success.</em>
</center>
</p><p>
<h2>2. Compete where your strengths are</h2>
Figure out what your strengths are relative to your peers, and compete in that area. Too many people around the world can set up a <a href="http://en.wikipedia.org/wiki/LAMP_(software_bundle)">LAMP stack</a> and program in HTML/CSS/JS/PHP/Python/Ruby, so try to compete in an another area, where you have a competetive advantage. It's okay to use the mentioned technologies, but if all it takes to duplicate your product is knowledge of easy-access technologies, you're competing with millions of people, and your chances drop accordingly.
</p><p>
<center>
<img src="/images/feynman-at-blackboard.jpg" /><br/>
<em><a href="http://en.wikipedia.org/wiki/Richard_Feynman">Feynman</a>, according to himself, was an average <a href="http://en.wikipedia.org/wiki/Bongo_drum">bongo drummer</a>.</em>
</center>
</p><p>
<h2>3. Focus on fundamentals</h2>
Look for fundamental problems and propose fundamental solutions. Shoot as deep into the software stack as plausible/possible.
</p><p>
<center>
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/nRFiTwQwcNk&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/nRFiTwQwcNk&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object><br/>
<em>Rocky Balboa focusing on fundamentals.</em>
</center>
</p><p>
<h2>4. Charge money</h2>
To make money off advertising, you need insane amounts of pageviews, which is very unlikely. To make money off a company that does not make money, you need to sell the whole thing. This is hard, especially if you are outside Silicon Valley / U.S.A. Combined with the previous points, the best bet is to write software that you can either sell or realistically charge money for support for, <strong>software which is important enough</strong>.
</p><p>
<center>
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/I6IQ_FOCE6I&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/I6IQ_FOCE6I&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object><br/>
<em>Don't be part of another bubble.</em>
</center>
</p><p>
<h2>Example:</h2>
(Not my startup.) Write software to make data-based recommendations based on user-data (see <a href="http://bytepawn.com/2008/08/04/data-based-recommendations">earlier post</a>). Many websites collect user data, but only few are any good at using them. There may be a bussiness use-case here (financial success). Write high-perfomance code that will withstand the test of time (don't depend on libraries that won't be around in 5 years). This is an area that is non-trivial enough to get into that you're not competing with all programmers who can write a for-loop. You can either give away the software for free and charge for support and development, or charge money for the software. (In the latter case, you can't count on the hordes of hobbyists to download your software and blog about it.)
</p><p>
</p>]]></content:encoded>
</item>
<item>
<title>CIDR 2009 Proceedings</title>
<link>http://bytepawn.com/2009/01/08/cidr-2009-proceedings</link>
<guid isPermaLink='false'>http://bytepawn.com/2009/01/08/cidr-2009-proceedings</guid>
<pubDate>Thu, 08 Jan 2009 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
I could not attend this year's meeting, so I was waiting for the proceedings. Here it is:
</p><p>
<a href="http://www-db.cs.wisc.edu/cidr/cidr2009/program.html">http://www-db.cs.wisc.edu/cidr/cidr2009/program.html</a>
</p>]]></content:encoded>
</item>
<item>
<title>Introducing PrimoBlog</title>
<link>http://bytepawn.com/2009/01/08/introducing-primoblog</link>
<guid isPermaLink='false'>http://bytepawn.com/2009/01/08/introducing-primoblog</guid>
<pubDate>Thu, 08 Jan 2009 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
In an effort to get rid of compromisable targets on my server, I decided to roll my own "blog engine": PrimoBlog. As the name implies, it's quite primitive. It consists of 123 lines of shell code plus the framing HTML and CSS code. It generates static HTML and RSS from text files, so no PHP or Mysql is involved.
</p><p>
The decision was inspired by <a href="http://www.daemonology.net/blog/2005-09-12-blogsh.html">Colin Percival</a>:
<blockquote>
As many people who know me will be aware, I tend towards minimalism in computer software. As a result, when I decided to start writing this, I looked around for the simplest blogging software I could find (it was NanoBlogger) and decided that it was far too complex for my taste. So I wrote my own.
</blockquote>
</p><p>
I don't need most of the features of a full blown blog engine like WordPress.
<ul>
<li>PrimoBlog generates a static index of all articles. I think grouping by year and month is mostly useless.</li>
<li>For comments, I use <a href="http://www.disqus.com">disqus</a>, which only involves placing some JavaScript at the end of the HTML. It's a free lunch, really.</li>
<li>Using anything but Google for searching is stupid anyways.</li>
<li>Nobody cares about categories and tags and nifty per-category icons. Contents over style.</li>
</ul>
</p>]]></content:encoded>
</item>
<item>
<title>Shackleton's Job Advertisement</title>
<link>http://bytepawn.com/2009/01/08/shackletons-job-advertisement</link>
<guid isPermaLink='false'>http://bytepawn.com/2009/01/08/shackletons-job-advertisement</guid>
<pubDate>Thu, 08 Jan 2009 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
<a href="http://en.wikipedia.org/wiki/Ernest_Shackleton">Ernest Shackleton's</a> 1907 ad in London's Times, recruiting a crew to sail with him on his exploration of the South Pole:
</p><p>
<blockquote>
Wanted. Men for hazardous journey.<br/>
Low wages. Bitter cold.<br/>
Long hours of complete darkness.<br/>
Safe return doubtful.<br/>
Honor and recognition in the event of success.
</blockquote>
</p><p>
Would this kind of ad work on programmers?
</p>]]></content:encoded>
</item>
<item>
<title>Re: Readings in Distributed Systems</title>
<link>http://bytepawn.com/2008/12/06/re-readings-in-distributed-systems</link>
<guid isPermaLink='false'>http://bytepawn.com/2008/12/06/re-readings-in-distributed-systems</guid>
<pubDate>Sat, 06 Dec 2008 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
I've updated the <a href="http://bytepawn.com/readings-in-distributed-systems/">Readings in Distributed Systems</a> page with a few papers: 2 on implementation issues and one on Sinfonia.
</p><p>
The latest table of contents:
</p><p>
<strong>I. The Google Papers</strong><br/>
1. The Google File System<br/>
2. Bigtable: A Distributed Storage System for Structured Data<br/>
3. The Chubby Lock Service for Loosely-Coupled Distributed Systems<br/>
4. Paxos Made Live - An Engineering Perspective<br/>
5. MapReduce: Simplified Data Processing on Large Clusters<br/>
</p><p>
<strong>II. Distributed Filesystems</strong><br/>
1. Petal: Distributed Virtual Disks<br/>
2. Frangipani: A Scalable Distributed File System<br/>
3. GPFS: A shared-disk file system for large computing clusters<br/>
4. Replication in the Harp File System<br/>
5. Swift: Using distributed disk striping to provide high I/O data rates<br/>
6. Ceph: a scalable, high-performance distributed file system<br/>
7. XtreemFS - a case for object-based storage in Grid data management<br/>
8. Andrew FS<br/>
9. Lustre<br/>
10. GlusterFS<br/>
11. Sinfonia: A new paradigm for building scalable distributed systems<br/>
</p><p>
<strong>III. Non-relational Distributed Databases</strong><br/>
1. Dynamo: Amazon’s Highly Available Key-value Store<br/>
2. Facebook’s Cassandra<br/>
3. CouchDB<br/>
</p><p>
<strong>IV. The Lamport Papers</strong><br/>
1. Paxos made simple<br/>
2. Reaching Agreement in the Presence of Faults<br/>
3. Time, clocks, and the ordering of events in a distributed system<br/>
4. The Part-Time Parliament<br/>
5. Distributed snapshots: determining global states of distributed systems<br/>
</p><p>
<strong>V. Implementation Issues</strong><br/>
1. A scalable and explicit event delivery mechanism for UNIX<br/>
2. A design framework for highly concurrent systems<br/>
3. Comparing and evaluating epoll, select, and poll event mechanisms<br/>
4. Asynchronous I/O support in Linux 2.5<br/>
5. Linux AIO performance and robustness for enterprise workloads<br/>
6. Books written by the late W. Richard Stevens<br/>
</p><p>
</p>]]></content:encoded>
</item>
<item>
<title>Readings in Distributed Systems</title>
<link>http://bytepawn.com/2008/10/28/readings-in-distributed-systems</link>
<guid isPermaLink='false'>http://bytepawn.com/2008/10/28/readings-in-distributed-systems</guid>
<pubDate>Tue, 28 Oct 2008 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
I started maintaining a <a href="http://bytepawn.com/readings-in-distributed-systems/">list of papers on Distributed Systems</a>.
</p><p>
Currently, there's a section on 
<ul>
<li>the Google papers: GFS, Bigtable, MapReduce, etc.: these are classics</li>
<li>Distributed Filesystems: this is what I'm working on right now, so it's the most complete section</li>
<li>Non-relational Distributed Databases: very incomplete</li>
<li>The Lamport papers: Leslie Lamport seems to be the godfather of distributed algorithms, these are some of his most important papers. It's worth looking at them to get an idea of the problems you could run into designing / implementing distributed systems.</li>
</ul>
</p><p>
If you think something important is missing, please <a href="http://bytepawn.com/about/">email me</a>.
</p>]]></content:encoded>
</item>
<item>
<title>Entry to Photography</title>
<link>http://bytepawn.com/2008/10/14/entry-to-photography</link>
<guid isPermaLink='false'>http://bytepawn.com/2008/10/14/entry-to-photography</guid>
<pubDate>Tue, 14 Oct 2008 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
I've wanted to pick up photography as a hobby for years, and now that it's <a href="http://bytepawn.com/2008/09/22/doing-an-ironman/">off-season</a>, I finally had a chance to go out and <em>just do it</em>. First of all I watched BBC's <a href="http://www.bbc.co.uk/photography/genius/">Genius of Photography</a> --- it's the perfect way to find inspiration and see for yourself that cameras don't take good pictures, photographers take good pictures.
</p><p>
Initially I wanted to spend mega bucks on a <a href="http://en.wikipedia.org/wiki/Digital_single-lens_reflex_camera">digital SLR camera</a>. I looked at <a href="http://www.kenrockwell.com/nikon/d40.htm">Nikon D40</a> - <a href="http://www.kenrockwell.com/nikon/d90.htm">D90s</a>, and even the <a href="http://www.kenrockwell.com/nikon/18200.htm">18-200 Nikkor VR lens</a>. As I watched the BBC series, I found out that my favorite photographs were <a href="http://en.wikipedia.org/wiki/Street_photography">street photography</a>, the ones that capture the decisive moment:
</p><p>
<blockquote>
Street photography uses the techniques of straight photography in that it shows a pure vision of something, like holding up a mirror to society. This genre of photography is present in contemporary times and is usually done as black and white photographs. Street photography often tends to be ironic and can be distanced from its subject matter and often concentrates on a single human moment, caught at a decisive or poignant moment. On the other hand, much street photography takes the opposite approach and provides a very literal and extremely personal rendering of the subject matter, giving the audience a more visceral experience of walks of life they might only be passingly familiar with. In the 20th century, street photographers have provided an exemplary and detailed record of street culture in Europe and North America, and elsewhere to a somewhat lesser extent.
</blockquote>
</p><p>
<img src="/images/meyerowitz.jpg" />
</p><p>
<em>Street Photography by <a href="http://en.wikipedia.org/wiki/Joel_Meyerowitz">Joel Meyerowitz</a></em>
</p><p>
I ended up not buying a DSLR, because I found them too clunky. I wanted something lighter that I can carry around all day. Finally I settled on the high-end compact <a href="http://www.dpreview.com/reviews/canong9/">Canon PowerShot G9</a>.
</p><p>
<img src="/images/canon-g9.jpg" />
</p><p>
After a few days of usage I haven't had time to change the camera from its default settings, and still, it takes great pictures. Here is some street amateur photography I took (processed, stylized):
</p><p>
<a href="/images/Greenpeace Girl on Moricz Square (2008-10-13).jpg"><img src="/images/Thumbnail of Greenpeace Girl on Moricz Square (2008-10-13).jpg"/></a>
</p><p>
<em>Greenpeace Girl on Moricz Square (Budapest, 2008/10/13)</em>
</p><p>
</p><p>
<a href="/images/Homeless Men on Ferenciek Square (2008-10-13).jpg"><img src="/images/Thumbnail of Homeless Men on Ferenciek Square (2008-10-13).jpg"/></a>
</p><p>
<em>Homeless Men on Ferenciek Square (Budapest, 2008/10/13)</em>
</p><p>
<a href="/images/Laughing out Loud (Budapest, 2008-10-11).jpg"><img src="/images/Thumbnail of Laughing out Loud (Budapest, 2008-10-11).jpg"/></a>
</p><p>
<em>Laughing out Loud (Budapest, 2008/10/11)</em>
</p>]]></content:encoded>
</item>
<item>
<title>Doing an Ironman</title>
<link>http://bytepawn.com/2008/09/22/doing-an-ironman</link>
<guid isPermaLink='false'>http://bytepawn.com/2008/09/22/doing-an-ironman</guid>
<pubDate>Mon, 22 Sep 2008 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
Why write about the <a href="http://en.wikipedia.org/wiki/Ironman_triathlon">Ironman</a> here, a blog meant for programmers and other technical types? From personal experience I know that people have a misconception about the Ironman. They think it's about swimming, biking and running training followed by a grueling day of racing followed by some bragging, per the Ironman slogan:
</p><p>
<blockquote>
Swim 2.4 miles.<br/>
Bike 112 miles.<br/>
Run 26.2 miles.<br/>
Brag for the rest of your life!
</blockquote>
</p><p>
(That's 3.8, 180, 42 kilometers.)
</p><p>
For me at least, it was a different experience. <strong>The biggest gain is what you carry over to other aspects of your life.</strong>
</p><p>
<strong>Discipline.</strong> In the final months, I trained about 15 hours net per week. That's about 6km swimming, 200km biking and 50km running a week. Integrating this kind of workout into your life forces you to manage your time efficiently. You stop wasting time, and start getting up at 6AM for morning workouts. Maybe you'll even start drinking raw eggs...
</p><p>
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/3EYZCZvV7WM&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><embed src="http://www.youtube.com/v/3EYZCZvV7WM&hl=en&fs=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"></embed></object>
</p><p>
<strong>Focus.</strong> At the beginning of the season, I ordered <a href="http://www.amazon.com/Going-Long-Ironman-Distance-Triathlons-Multisport/dp/1931382247/ref=pd_bbs_2?ie=UTF8&s=books&qid=1222076705&sr=8-2">Joe Friel and Gordon Byrn's excellent <em>Going Long</em> book from Amazon</a>.
</p><p>
<img src="/images/going-long.jpg" />
</p><p>
This is a great book with lots of good technical help, but here I'd like to point out the advice that applies not just to triathlon (paraphrased):
</p><p>
<blockquote>
As in all aspects of life,<br/>
<strong>focus on fundamentals:</strong><br>
endurance, strength,<br/>
efficiency, recovery.<br/>
<strong>It ain't rocket science.</strong>
</blockquote>
</p><p>
Focus of fundamentals: these three words, which I read in a triathlon book a year ago, have since changed the way I approach programming, physics, pretty much everything.
</p><p>
<strong>Motivation.</strong> As you train for the Ironman, you start being very motivated about yourself. You start listening to the <a href="http://www.youtube.com/watch?v=IaNZuWld4Lo&feature=related">Rocky theme song</a>. During workouts you visualize yourself during the race or finishing the race. <strong>This motivation drips over to other aspects of your life, too.</strong>
</p><p>
<strong>Fitness.</strong> Anybody who earns his money typing away at a computer needs a workout a day. What's the point of being successful and making lots of money if you're not healthy (or won't be). Note that health is strongly correlated with body weight. I've lost 15 kg (33 pounds) during the training, and since training is now part of my daily routine, it's easy to stay fit.
</p><p>
<strong>Recommendation.</strong> I can only recommend the Ironman, and triathlon in general. It takes a lot of time and money, but the gain is tremendous. Most people I know who claim that it takes too much time are like me, they could easily convert wasted time to workouts while not taking away much time from other essential activities like work. (The only person I would not recommend it to is a  young parent.)
</p><p>
To wrap it up, here are some <a href="http://www.flickr.com/photos/mtrencseni/sets/72157606939811615/">pics from my race</a>. (Note that I was at the hungarian Ironman, called ExtremeMan.) Some <a href="http://www.youtube.com/watch?v=Bh1yMnrby3w&feature=related">more motivation here (warning: media-engineered)</a>. If you think you can't do it, wind <a href="http://www.youtube.com/watch?v=UN02AzxPZHQ">this video</a> to 0:50.
</p><p>
Have a great workout!
</p>]]></content:encoded>
</item>
<item>
<title>Show Me Your Data Structure...</title>
<link>http://bytepawn.com/2008/09/10/show-me-your-data-structure</link>
<guid isPermaLink='false'>http://bytepawn.com/2008/09/10/show-me-your-data-structure</guid>
<pubDate>Wed, 10 Sep 2008 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
There's an old programming proverb which goes something like this:
</p><p>
<blockquote>
Show me you algorithm,<br/>
and I will remain puzzled,<br/>
but show me your data structure,<br/>
and I will be enlightened.
</blockquote>
</p><p>
This is a statement about software and coding, but first and foremost it is about human cognition. The way my brain works is to first visualize the data and then imagine what the algorithm does to it.
</p><p>
Given this cognitive limitation of my brain, I favor static, strong, class-based typing (C/C++) over dynamic, weak, object-based typing (JavaScript).
</p><p>
To give a strong example and stir up some controversy, consider Chapter 9 of <a href="http://www.amazon.com/Beautiful-Code-Leading-Programmers-Practice/dp/0596510047">Beautiful Code</a>: Top Down Operator Precedence by <a href="http://www.crockford.com/">Douglas Crockford</a>. You can <a href="http://javascript.crockford.com/tdop/tdop.html">read it here</a>, and you should to really get a feeling for what's going on...
</p><p>
I think it's spaghetti code.
</p><p>
<img src="/images/baby-spaghetti.jpg" />
</p><p>
The problems with his approach are many:
</p><p>
<ul>
<li>No complete declarations of complete types, even though it would be (kind of) possible with JavaScript. So I can't start by vizualizing the data structures.</li>
<li>No type declarations, but lots of confusing variable names, so I'm constantly going back trying to figure out what's what.</li>
<li>Dynamic modification of fields in objects. For example the function <span class="code">advance()</span> adds the field <span class="code">arity</span> to the token object, which was not declared anywhere, so you only find out about this by reading this function. This goes against everything sane in programming.</li>
<li>Going completely overboard, the field <span class="code">arity</span> is used to store whether a token is a "name", "literal" or "operator" but later, for operators, changes this field to "unary", "binary", etc. (Truly bad programming, but not related to my argument about typing.)</li>
<li>To deliver the final blow to understandablity, in functional style, the member functions of the objects are dynamically added and modified. At this point, if I see an object, I don't know its "type", but even if somebody tells me that, I don't know what state that "type" is in: what the data fields are, what they are used for and what the member functions do.</li>
<li>Given the cognitive difficulties above, how does one look over the code to verify that it's correct? It's hard enough with static languages, here it seems quixotic. How about finding bugs?</li>
</ul>
</p><p>
As I was trying to understand the code, I found myself writing out on a piece of paper the different "types" of objects that come up in the code --- in other words the classes. I was writing the header files for the code in order to untangle the mess!
</p><p>
To close this rant, I'll quote a <a href="http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03615.html">thread Google turned up</a>:
</p><p>
<pre>
> A while ago there was one of those static-vs-dynamic debates (in the hackers
> and painters thread, I think), and somewhere (I'm sure) someone mentioned a
> quote along the lines of:
> 
> Early on in a project, as code is rapidly evolving, you want static typing
> to help you as much as possible. When the code has matured (it's well tested
> and not changing much), you want more dynamic typing so that the design can
> be more flexible.
> 
> Can anyone remember who said this?
> 
Not me.  But it's interesting.  Usually the argument goes the other way:
Early on in a project, as code is rapidly evolving, you want dynamic
typing to keep as many design options open as possible. When the code has
matured (it's well tested and not changing much), you want more static
typing for efficiency and to help root out obscure bugs that may be
waiting to manifest themselves.
</pre>
</p>]]></content:encoded>
</item>
<item>
<title>Transactions in Memory</title>
<link>http://bytepawn.com/2008/09/01/transactions-in-memory</link>
<guid isPermaLink='false'>http://bytepawn.com/2008/09/01/transactions-in-memory</guid>
<pubDate>Mon, 01 Sep 2008 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
I recently re-read Chapter 24 of <a href="http://www.amazon.com/Beautiful-Code-Leading-Programmers-Practice/dp/0596510047">Beautiful Code</a>, titled <a href="http://research.microsoft.com/~simonpj/Papers/stm/beautiful.pdf">Beautiful Concurrency (PDF)</a>. It's very well written, you won't regret reading it. In it, <a href="http://research.microsoft.com/~simonpj/">Simon Peyton Jones</a> makes the case for Software Transactional Memory vs. explicit locking by the programmer.
</p><p>
Getting locking right in a non-trivial system is pretty hard. SPJ's list of pitfalls is almost exhaustive:
<ol>
<li>Taking too few locks</li>
<li>Taking too many locks</li>
<li>Taking the wrong locks</li>
<li>Taking the locks in the wrong order</li>
<li>Freeing locks on error</li>
</ol>
</p><p>
<img src="/images/locks.jpg" />
</p><p>
I would a zeroth point: <strong>figuring out what to lock.</strong> This precedes everything else you do with locks.
</p><p>
Software Transactional Memory is, per <a href="http://en.wikipedia.org/wiki/Software_transactional_memory">Wikipedia</a>:
</p><p>
<blockquote>
In computer science, software transactional memory (STM) is a concurrency control mechanism analogous to database transactions for controlling access to shared memory in concurrent computing. It functions as an alternative to lock-based synchronization. A transaction in this context is a piece of code that executes a series of reads and writes to shared memory. These reads and writes logically occur at a single instant in time; intermediate states are not visible to other (successful) transactions.
</blockquote>
</p><p>
An example is worth a thousand words:
<pre>
// change a1 and a2 such that a1 + a2 = const
// like transferring money between bank accounts
&nbsp;
// lock-based version
lock l;
double a1, a2;
void transfer(double amount)
{
&nbsp;lock(l);
&nbsp;a1 = a1 - amount; // suppose this is atomic
&nbsp;a2 = a2 + amount;
&nbsp;unlock(l);
&nbsp;}
}
&nbsp;
// STM
stm_double a1, a2;
void transfer(double amount)
{
&nbsp;transaction_start(); // like 'atomic' in Haskell
&nbsp;&nbsp;a1 = a1 - amount;
&nbsp;&nbsp;a2 = a2 + amount;
&nbsp;transaction_end();
}
</pre>
</p><p>
No big difference. But wait, what if you have several a's, say several accounts. You want <span class="code">transfer(a1, a2, amount)</span>. With locks, your code just got a whole lot more complicated. With STM, it's a free lunch.
</p><p>
STM solves most of the problems listed by SPJ, but cannot solve the zeroth problem: you still have to figure out what the lockspots are, declare them to be transactional variables, and then guard them with transactions. But with STMs, <em>all</em> you have to do is guard with, you don't have to worry about locking policy.
</p><p>
But remember, there are no silver bullets. There are two problems with STM:
</p><p>
<strong>1. No transactional I/O.</strong> M stands for Memory, meaning that it can only guard memory areas, but not I/O. On some systems, like Haskell, the STM library does not even let you mix STM and I/O operations, so you can't have I/O operations inside <span class="code">atomically { }</span> (it won't compile). The reason is, you don't want to execute the I/O code twice in case the transaction has to be re-run.
</p><p>
<strong>2. Library overhead.</strong> You just went from a few instructions to write a variable to including a whole library that manages reading and writing variables for you. If the code you are writing is not high-performance, this is probably acceptable. I'd consider using STM when working in Java, .NET or Python --- here, raw speed is not possible anyway, so trading some more CPU time for simpler and less buggy code is acceptable.
</p><p>
<strong>How much speed are you sacrifying when using STM?</strong> To find out, I downloaded and compiled <a href="http://tinystm.org/tinystm">TinySTM</a>, a C library implementing the basic STM primitives like <span class="code">stm_start()</span> and <span class="code">stm_commit()</span>.
</p><p>
It turns out that the transaction manager's design matters a whole lot. Some good papers are:
<ul>
<li><a href="http://research.ihost.com/ppopp08/presentations/felber.ppt">Dynamic Performance Tuning of Word-Based Software Transactional Memory - a presentation by the TinySTM authors</a></li>
<li><a href="http://www.lib.ncsu.edu/theses/available/etd-06182007-222608/unrestricted/etd.pdf">Performance Comparison of Software Transactional Memory Implementations - Riya Kariath's M.Sc. Thesis</a></li>
</ul>
</p><p>
To test performance I created the simplest program possible (<a href="/wp-content/code/perf.c">source code</a>), with just one <span class="code">long integer</span> called <span class="code">counter</span>, <span class="code">NTHREADS</span> many threads each wanting to increment <span class="code">counter NLOOPS</span> many times. (This test is by no means representative, but it's something. You have to see what happens for your real workload.)
</p><p>
For comparison, I measured
<ol>
<li>a naive, non-locking implementation which is not correct, ie. the final value of <span class="code">counter</span> is not <span class="code">NTHREADS * NLOOPS</span>.</li>
<li>pthread mutex based implementation with one lock for <span class="code">counter</span></li>
<li>TinySTM based implementation with transactions using <strong>Write-back + Encounter Time Locking (ETL)</strong></li>
<li>TinySTM based implementation with transactions using <strong>Write-back + Commit Time Locking (CTL)</strong></li>
</ol>
</p><p>
The results are in milliseconds, first number is for naive, second for lock-based, third for STM-based implementation:
</p><p>
<table border="1">
<tr style="background-color:#cccccc;">
<td></td>
<td>NTHREADS = 10</td>
<td>NTHREADS = 100</td>
<td>NTHREADS = 1000</td>
</tr>
<td style="background-color:#cccccc;">NLOOPS = 10</td>
<td>0 | 0 | 40 | 10</td>
<td>7 | 7 | 1440 | 18</td>
<td>112 | 153 | 1148071 | 147</td>
<tr>
</tr>
<td style="background-color:#cccccc;">NLOOPS = 100</td>
<td>0 | 6 | 54 | 8</td>
<td>6 | 100 | 2065 | 20</td>
<td>93 | 1037 | 1204106 | 875</td>
<tr>
<td style="background-color:#cccccc;">NLOOPS = 1000</td>
<td>0 | 95 | 54 | 11</td>
<td>6 | 898 | 1200 | 40</td>
<td>99 | 9937 | 566714 | 379</td>
</tr>
</table>
</p><p>
Note that I didn't repeat the experiment many times and take an average value, but the trend is quite clear (and repeatable). <strong>As you get more and more threads competing for the same resource, the STM ETL implementation becomes unfeasable (third number), while the STM CTL implementation (fourth number) beats my locking code (second number).</strong>
</p><p>
What's the difference between the two STM architectures? With ETL, as soon as the transaction reads a variable, that variable is locked and not released until the transaction finishes. With CTL, the variables are not locked until the transaction attempts to commit. The problem with ETL is that whenever a thread acquires a lock on counter, and all the other threads start aborting and re-executing, hogging down the CPU. It's not clear why the CTL version is faster than ETL, I assume it's because threads get lots of timeslices during the execution of one one loop, so the ETL version aborts many more times than the CTL version. Why is it faster then the pthread version? TinySTM uses <a href="http://www.hpl.hp.com/research/linux/atomic_ops/">atomic_ops</a>, which contains machine-specific optimizations, which the pthread library probably does not.
</p><p>
The lesson is:
<ul>
<li>STM can be very slow depending on your workload and STM library</li>
<li>STM can be very fast depending on your workload and STM library</li>
<li>Look into <a href="http://www.hpl.hp.com/research/linux/atomic_ops/">atomic_ops</a> (or find bottleneck is pthread code)</li>
</ul>
</p>]]></content:encoded>
</item>
<item>
<title>Ironman</title>
<link>http://bytepawn.com/2008/08/25/ironman</link>
<guid isPermaLink='false'>http://bytepawn.com/2008/08/25/ironman</guid>
<pubDate>Mon, 25 Aug 2008 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
I've been busy this weekend finishing up my first <a href="http://en.wikipedia.org/wiki/Ironman_Triathlon">Ironman (3.8km swim, 180km bike, 42km run)</a> season.
</p><p>
<a href="http://flickr.com/photos/mtrencseni/sets/72157606939811615/">Pictures from the race.</a>
</p>]]></content:encoded>
</item>
<item>
<title>P2P vs. the Cloud</title>
<link>http://bytepawn.com/2008/08/16/p2p-vs-the-cloud</link>
<guid isPermaLink='false'>http://bytepawn.com/2008/08/16/p2p-vs-the-cloud</guid>
<pubDate>Sat, 16 Aug 2008 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
Marco Kotrotsos in a recent article claims that the cloud has failed, and instead <a href="http://struct3.com/has-the-cloud-failed-before-prime-time/">advocates a P2P cloud architecture</a>:
</p><p>
<blockquote>
I am referring to the slew of outages the last day’s and weeks of some high profile infrastructures like Amazon S3 and Google. I always thought Googles infrastructure was untouchable. But it seemed that I had woken up to a different world last week. When I saw tweets and messages going around with "Gmail is down".
<br/>...<br/>
P2P Cloud computing in general will be the future of infrastructure.
</blockquote>
</p><p>
At first, this sounds like a good idea. At least it did in 2000, when it was called <a href="http://en.wikipedia.org/wiki/Grid_computing">grid computing</a>. Unfortunately, it's not.
</p><p>
<img src="/images/small-clouds.jpg" />
</p><p>
<strong>It's been tried; it failed.</strong> This <a href="http://www.nature.com/nature/webmatters/grid/grid.html">Nature article</a> from 2000 is optimistic:
</p><p>
<blockquote>
Internet computing and Grid technologies promise to change the way we tackle complex problems. They will enable large-scale aggregation and sharing of computational, data and other resources across institutional boundaries. And harnessing these new technologies effectively will transform scientific disciplines ranging from high-energy physics to the life sciences.
</blockquote>
</p><p>
At the end of the article is a list of companies trying to commercialize the concept: Entropia, United Devices, Parabon and Popular Power. Guess what --- most of them are no longer around. The only one that is is <a href="http://www.parabon.com">Parabon</a>, which is hosting the <a href="http://www.computeagainstcancer.org/">ComputeAgainstCancer</a> project. Looking at their site, I get the feeling that their customers are mostly universities and other government agencies
</p><p>
<strong>Incentive and economics.</strong> People download <a href="http://setiathome.berkeley.edu/">SETI@Home</a> out of philantrophy and because they think it's cool. You can't count on people to host your distributed app platform on their computer for philantrophy, so you'd have to pay them. Unfortunately, the amount of money their computational power is worth is so low that it wouldn't work. Would you bother to download and run some a program in the background for ~$5 / month? Also, you can't put your computer to sleep from now on. E.g. in the case of Parabon, the company mentioned above, you can't download and run their "Frontier Compute Engine", which is their distributed node software. The reason probably is that nobody wants to, anyway. So if a company wants to use Parabon's system, they either run their own nodes, or buy the capacity from Parabon's marketplace.  
</p><p>
<strong>Latency.</strong> Google serves search requests in 10-100 milliseconds, wherever you are. Can you do that with P2P? Remember, <a href="http://www.stuartcheshire.org/rants/Latency.html">latency vs. bandwidth</a>:
</p><p>
<blockquote>
Years ago David Cheriton at Stanford taught me something that seemed very obvious at the time -- that if you have a network link with low bandwidth then it's an easy matter of putting several in parallel to make a combined link with higher bandwidth, but if you have a network link with bad latency then no amount of money can turn any number of them into a link with good latency.
</blockquote>
</p><p>
<strong>It's not attacking the right problems.</strong> I'm not sure about the Gmail outage, but <a href="http://developer.amazonwebservices.com/connect/message.jspa?messageID=79978#79978">Amazon posted a short explanation of their problem</a>:
</p><p>
<blockquote>
Early this morning, at 3:30am PST, we started seeing elevated levels of authenticated requests from multiple users in one of our locations.  While we carefully monitor our overall request volumes and these remained within normal ranges, we had not been monitoring the proportion of authenticated requests.  Importantly, these cryptographic requests consume more resources per call than other request types.
<br/><br/>
Shortly before 4:00am PST, we began to see several other users significantly increase their volume of authenticated calls.  The last of these pushed the authentication service over its maximum capacity before we could complete putting new capacity in place.  In addition to processing authenticated requests, the authentication service also performs account validation on every request Amazon S3 handles.  This caused Amazon S3 to be unable to process any requests in that location, beginning at 4:31am PST.  By 6:48am PST, we had moved enough capacity online to resolve the issue.
</blockquote>
</p><p>
Even in a P2P architecture, I imagine that the authentication service would be located in the grid provider's own network, so P2P wouldn't make a difference. Also note that today's clouds (Google, Amazon, etc.) are explicitly designed to be unaffected by disk, machine or switch failure. So the only way to bring them down is either through an allocation mismatch (human error?), which is basically what happened with Amazon, a software bug / protocol bug (human error), some extreme power outage that outlasts the local generators (extremely unlikely?), or some kind of <a href="http://en.wikipedia.org/wiki/Denial-of-service_attack">DDoS attack</a> against the entire data center. Even with a P2P architecture, you still have to have some components running in the grid provider's local datacenter, so a DDoS against that would still bring the whole thing down. I think that the Gmail and Amazon problems were not really scalability problems, so P2P wouldn't have helped.
</p><p>
To close the article, I'll include one last quote from <a href="http://en.wikipedia.org/wiki/Jim_Gray_(computer_scientist)">Jim Gray's</a> short <a href="http://research.microsoft.com/research/pubs/view.aspx?tr_id=655">Distributed Computing Economics (2003) paper</a> (emphasis mine):
</p><p>
<blockquote>
Computing economics are changing. Today there is rough price parity between (1) one database access, (2) ten bytes of network traffic, (3) 100,000 instructions, (4) 10 bytes of disk storage, and (5) a megabyte of disk bandwidth. This has implications for how one structures Internet-scale distributed computing: <strong>one puts computing as close to the data as possible in order to avoid expensive network traffic.</strong>
<br/>...<br/>
<strong>The ideal mobile task is stateless (no database or database access), has a tiny network input and output, and has huge computational demand.</strong> For example, a cryptographic search problem: given the encrypted text, the clear text, and a key search range. This kind of problem has a few kilobytes input and output, is stateless, and can compute for days. Computing zeros of the zeta function is a good example.  Monte Carlo simulation for portfolio risk analysis is another good example. And of course, SETI@Home is a good example: it computes for 12 hours on half a megabyte of input.
<br/>...<br/>
<strong>Most web and data processing applications are network or state intensive and are not economically viable as mobile applications.</strong> An FTP server, an HTML web server, a mail server, and Online Transaction Processing (OLTP) server represent a spectrum of services with increasing database state and data access. A 100MB FTP task costs 10 cents, and is 99% network cost. An HTML web access costs 10 microdollars and is 88% network cost. A Hotmail transaction costs 10 microdollars and is more cpu intensive so that networking and cpu are approximately balanced. None of these applications fits the cpu-intensive stateless requirement.
</blockquote>
</p>]]></content:encoded>
</item>
<item>
<title>Data-based Recommendations</title>
<link>http://bytepawn.com/2008/08/04/data-based-recommendations</link>
<guid isPermaLink='false'>http://bytepawn.com/2008/08/04/data-based-recommendations</guid>
<pubDate>Mon, 04 Aug 2008 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
Social recommendation sites like <a href="http://www.slashdot.org">Slashdot</a>, <a href="http://www.digg.com">Digg</a> or the smaller <a href="http://news.ycombinator.com">Hacker News</a> are used by millions to find interesting content on the web. Some are supposed to be <a href="http://www.techcrunch.com/2008/07/22/google-in-final-negotiations-to-acquire-digg-for-around-200-million/">worth a lot of dollars</a>. Although these sites are <strong>useful in the sense of being better than nothing, the signal to noise ratio is still very low</strong>. Hacker News' feed features roughly 75 posts a day of which maybe 5-10% are interesting to me. In the long run, scanning through 75 posts a day to find 8 mildly interesting ones is not very good. Granted, for discovering "breaking news" social recommendation sites are ideal --- but in reality, most posted links are not new, they're just supposed to be interesting. 
</p><p>
One alternative to social recommendations is data-based recommendations, where some site or company records my habits and points me to interesting stuff. The champion here is without a doubt <a href="http://www.amazon.com">Amazon</a>. Their recomendation engine simply rocks:
</p><p>
<img src="/images/amazon1.jpg" />
</p><p>
Amazon makes recommendations based on my browsing history, my shopping history, other user's browsing history, other user's shopping history, the category tree of their books or the assumption that if I liked something from the author I might also like his other books. Here's a <a href="http://agents.csie.ntu.edu.tw/~yjhsu/courses/u2010/papers/Amazon%20Recommendations.pdf">short PDF</a> describing their system in greater detail:
</p><p>
<blockquote>
<strong>Summary:</strong> Recommendation algorithms are best known for their use on e-commerce Web sites, where they use input about a customer's interests to generate a list of recommended items. Many applications use only the items that customers purchase and explicitly rate to represent their interests, but they can also use other attributes, including items viewed, demographic data, subject interests, and favorite artists. At Amazon.com, we use recommendation algorithms to personalize the online store for each customer. The store radically changes based on customer interests, showing programming titles to a software engineer and baby toys to a new mother. There are three common approaches to solving the recommendation problem: traditional collaborative filtering, cluster models, and search-based methods. Here, we compare these methods with our algorithm, which we call item-to-item collaborative filtering. Unlike traditional collaborative filtering, our algorithm's online computation scales independently of the number of customers and number of items in the product catalog. Our algorithm produces recommendations in real-time, scales to massive data sets, and generates high quality recommendations.
</blockquote>
</p><p>
In the case of Amazon, I don't have to buy the recommendation --- being on-topic is enough to get me to click on the book, kicking off a browsing session which may result in a purchase (or pushing books to my shopping list).
</p><p>
<strong>The real question is, why is Amazon the only site that gets it right?</strong> 
</p><p>
I can name two sites that I visit many times a day where data-based recommendations would rock:
</p><p>
<strong>Internet Movie Database</strong>. I use <a href="http://www.imdb.com">IMDb</a> all the time for checking movies before watching them and to see what other people thought after I saw a movie. IMDb should have massive amounts of data about my movie habits, yet their recommendation engine sucks. (Note that IMDb is owned by Amazon, so this is just weird.) For example, I open the page for the movie <a href="http://www.imdb.com/title/tt0478134/">In the Valley of Elah</a>, and at the bottom of the page I see 5 recommendations. These are not personal recommendations, my preferences / history have not been taken into account. It's simply a list of movies deemed similar to the movie I'm viewing. (You can verify this by logging off and visiting the page again.) And they suck too. They recommend <a href="http://www.imdb.com/title/tt0462499/">Rambo</a>, which is pretty pointless since everybody's seen Rambo.
</p><p>
<strong>Google Reader</strong>. Power-users use <a href="http://reader.google.com">Google Reader</a> to avoid having to visit all the blogs they read. I'm always looking for blogs that might be interesting to read. Google has a large database of data telling it what feeds users subscribe to and what articles users click. It should be possible to make good recommendations based on this data, not to mention all the other data Google has on us. Still, Google Reader's recommendations suck. They don't even attempt to recommend individual articles, only entire feeds / blogs.
</p><p>
For Amazon recommendations are a core of part of their business. Unfortunately for users, IMDb and Google Reader probably don't see a good way to monetize such a feature, hence the lack of effort.
</p><p>
The <a href="http://www.netflixprize.com">NetFlix challenge</a> was a great way to draw attention to recommendation algorithms, but I'm not aware of any startups coming out of it. This should be a call-to-arms for entrepeneurs to figure out a way to make money off recommendations. The task is a difficult one, since --- apart from finding a viable business plan --- you also face the classic <a href="http://en.wikipedia.org/wiki/Chicken-and-egg_problem">chicken-or-the-egg problem</a>: <strong>you need a lot of data to make good recommendations.</strong>
</p><p>
<img src="/images/chicken.gif" />
</p>]]></content:encoded>
</item>
<item>
<title>Beautiful Migration</title>
<link>http://bytepawn.com/2008/07/28/beautiful-migration</link>
<guid isPermaLink='false'>http://bytepawn.com/2008/07/28/beautiful-migration</guid>
<pubDate>Mon, 28 Jul 2008 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
<img src="/images/beautiful-code.gif" />
</p><p>
<em>O'Reilly's <a href="http://www.amazon.com/Beautiful-Code-Leading-Programmers-Practice/dp/0596510047/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1217183383&sr=8-1">Beautiful Code</a> is an excellent book with 33 short, bite-sized chapters about <strong>interesting code</strong>. After I read the book I thought it'd be a good retrospective exercise to <strong>write your own Chapter 34</strong> to share insights with other programmers. So here it goes:</em>
</p><p>
Some time ago I worked at a fairly large one-product software company. Roughly every 2 years they would come out with a new version of their software (let's call it Software X) to keep the cash flowing in. On the side, the company also sold customized versions of the software to the far-east, where it's customary for large companies to request custom versions of software tailored to their needs. I was part of the Customization Team.
</p><p>
As a matter of company policy, the changes the Customization Team produced never made it back to the base source tree of Software X. To put it in perspective, each customized version contained roughly 1% changes if measured in lines of code. There were several customized versions, on the order of 10. The customized version shared some customized features, so there was overlap in the code. As the Base Team working on Software X created new stable builds, we had to obtain a copy of their new source tree and merge in our custom code. We had to do this every time a major milestone was reached on Software X, roughly every 3-6 months. This is what we called migration: take the old customized version, call it Custom-old, the new base version, call it Base-new, and produce the new customized version Custom-new.
</p><p>
Unfortunately, our changes were not only in source code: we had a custom build system built on top of theirs, so we could build all our custom versions from the same source tree. This involved changing the source tree at certain points in a systematic way. For example, we had to keep files in different places, such as keeping a copy of all the original resource files in one place, and product specific resource files for each custom version (such as the splash screen), and our build system would manage these before calling the base build system. To sum it up, we not only changed source code, but moved files around, duplicated some, created some, etc.
</p><p>
<strong>Human Labor.</strong> Before the group started using a tool to aid migraiton, a human (one of the programmers) would manually migrate by copying files and directories, set up our custom directory structure and merge the source and resource files.
</p><p>
<strong>Imitation.</strong> The programmer given this problem before me implemented an <a href="http://en.wikipedia.org/wiki/Imperative_programming">imperative</a> migrator in C++ which mimicked what previously the human would have done: copy this, rename that, merge these files, etc. This is what it looked like:
</p><p>
<pre>
CopyFiles(from1, to1);
...
std::vector<string> exceptions;
exceptions.push_back(filename1);
exceptions.push_back(filename2);
...
CopyFiles(from2, to2, exceptions);
</pre>
</p><p>
Obviously, C++ is not the best language for such a tool. However, this was not the core problem with this implementation, had he used Perl I would still be writing this article. The problem was that the source tree was highly unstable from version to version, in the sense that files appeared, disappeared or moved around the directory tree. The tool had to be patched often, and even when we considered running it a success after manually checking and verifying the migration we always had to fix the source tree up by hand to get a working version.
</p><p>
It was obvious that the imperative program telling the computer to move around files and then present certain files for merging to the user was too complicated because the source tree was too complex (over a gigabyte). When given the chance, I convinced my manager that it had to be replaced.
</p><p>
<strong>Evolution.</strong> My first improvement over the original was evolutionary. In the last step of migration, the tool would present all source files that we modified for manual merging. This meant sitting there for hours and clicking CTRL + right-arrow in Araxis Merge to bring over our modifications. The idea here was simple: if given the base source file BaseFile, which we modified to get CustomFile-old, the only time it was neccesary to bring up a merge window is if BaseFile actually changed in the new base version, eg. if BaseFile-old != BaseFile-new. In terms of pseudo-code:
</p><p>
<pre>
if (BaseFile-new == BaseFile-old)
&nbsp;&nbsp;CustomFile-new := CustomFile-old;
else
&nbsp;&nbsp;CustomFile-new := Merge(..);
</pre>
</p><p>
This is, of course, trivial to anyone who has ever used a source control system like cvs. (In fact, source control systems are even smarter since they detect where in a file changes occurred.) In terms of our migration process, this involved bringing the old base version Base-old into the game. This improvement reduced the number of diffs presented to the human migrator by 90%, saving hours of work on each migration. Unfortuantely, the process was still highly unstable.
</p><p>
<strong>Revolution.</strong> After convincing my manager that the migration tool could be improved, I set out to design my version. I was guided by two main design principles:
<ul>
<li>design special-purpose meta-languages for your problem domain</li>
<li>use <a href="http://en.wikipedia.org/wiki/Declarative_programming">declarative</a> syntax whenever possible</li>
The first point is best illustrated by John Carmack’s <a href="http://en.wikipedia.org/wiki/QuakeC">QuakeC</a>, an interpreted language used to script the Quake engine. My knowledge of declarative languages is due to several semesters of <a href="http://en.wikipedia.org/wiki/Prolog">Prolog</a> at University.
</ul>
</p><p>
The beautiful idea was to think in terms of migration rules instead of concrete migration operations such as copying or merging files. The rules are declarative, and make up the meta-language of the first point.
</p><p>
The migrator’s central object is a <strong>multi-file iterator</strong>. (I cannot find a case of someone else doing this, so I may have invented something?). The migrator is told to iterate n directories in parallel by matching filenames. On each iteration, it calls the user supplied ruleset, which tells it how to create the file in the resulting source tree.
</p><p>
Suppose the following three directories (colors denote different file contents):
</p><p>
<table border="1" style="padding:4px;">
<thead style="font-weight:bold;">
<td>Directory1</td>
<td>Directory2</td>
<td>Directory3</td>
</thead>
<tr>
<td>Apple.txt</td>
<td><span style="color:blue;">Apple.txt<span></td>
<td><em>Null</em></td>
</tr>
<tr>
<td><em>Null</em></td>
<td>Banana.txt</td>
<td>Banana.txt</td>
</tr>
<tr>
<td>Orange.txt</td>
<td>Orange.txt</td>
<td><span style="color:green;">Orange.txt</span></td>
</tr>
<tr>
<td>Peach.txt</td>
<td><em>Null</em></td>
<td><em>Null</em></td>
</tr>
</table>
</p><p>
In the example above, we are iterating three directories is parallel. Directory1 contains three files, Apple.txt, Orange.txt and Peach.txt, Directory2 contains three files, Apple.txt, Banana.txt and Orange.txt, Directory3 contains two files, Banana.txt and Orange.txt. The iterator would return four times. The first time for Apple.txt, which exists in Directory1 and 2 but not in 3, the second time for Banana.txt, and so on. Every time the iterator returns, the user supplied ruleset is called. The return value of the rule determines how the given file (Apple.txt, Banana.txt, Orange.txt, Peach.txt) is created in the target directory. Suppose the ruleset looks like this:
</p><p>
<pre>
// rules for files
if (exists in Directory3)
&nbsp;&nbsp;copy from Directory3
else if (exists in Directory1 and Directory2)
{
&nbsp;&nbsp;if (same in Directory1 and Directory2)
&nbsp;&nbsp;&nbsp;&nbsp;copy from Directory1
&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;copy from Directory1 and Merge from Directory2
}
else if (exists in Directory1)
&nbsp;&nbsp;copy from Directory1
else
&nbsp;&nbsp;copy from Directory2
</pre>
</p><p>
The ruleset would produce the following result:
</p><p>
<table border="1" style="padding:4px;">
<thead style="font-weight:bold;">
<td>Directory1</td>
<td>Directory2</td>
<td>Directory3</td>
<td>TargetDirectory</td>
</thead>
<tr>
<td>Apple.txt</td>
<td><span style="color:blue;">Apple.txt</span></td>
<td><em>Null</em></td>
<td>Copy Apple.txt then merge with <span style="color:blue;">Apple.txt</span></td>
</tr>
<tr>
<td><em>Null</em></td>
<td>Banana.txt</td>
<td>Banana.txt</td>
<td>Banana.txt</td>
</tr>
<tr>
<td>Orange.txt</td>
<td>Orange.txt</td>
<td><span style="color:green;">Orange.txt</span></td>
<td><span style="color:green;">Orange.txt</span></td>
</tr>
<tr>
<td>Peach.txt</td>
<td><em>Null</em></td>
<td><em>Null</em></td>
<td>Peach.txt</td>
</tr>
</table>
</p><p>
Following the declarative approach, the ruleset itself doesn’t perform any operations (such as copy), instead it signals what its desired action is by returning an appropriate object to the framework. In other words, the rulesets are callback functions. The above example tells most of the story, with one exception: directories can contain other directories. Thus, the user actually supplies <strong>two rulesets, one for files and one for directories</strong>. The above ruleset is thus accompanied by another one for directories:
</p><p>
<pre>
// rules for directories
if (exists in Directory1 and Directory2 and Directory3)
&nbsp;&nbsp;create directory, descend and apply rulesets recursively
else if (exists in Directory1 and not in Directory2 and not in Directory3)
&nbsp;&nbsp;copy from Directory1
else if (exists in Directory1 and Directory2 and not in Directory3)
&nbsp;&nbsp;log path and do nothing
...
</pre>
</p><p>
Without reproducing actual code these examples tell most of the story, with one exception: one ruleset does not work everywhere in the sourcetree. For our merging process, I created ~10 different rulesets, and applied them for different subtrees of our source tree. Also note that the different rulesets iterated a different number of source directories to figure out what to do, which was "free" with the framework, since the multi-file iterator is implemented for the general n-case.
</p><p>
The one aspect of this approach that is <strong>not beautiful</strong> is keeping nested subtrees apart. Imagine applying Ruleset1 to DirectoryA’s subtree, which contains DirectoryB, where we would like to use Ruleset2. This has to be included in the ruleset itself:
</p><p>
<pre>
if (directory.path == “.../DirectoryB”)
&nbsp;&nbsp;do not descend
</pre>
</p><p>
Fortunately, these cases were rare.
</p><p>
<strong>Conclusion.</strong> The declarative migration tool worked out very well. With the new migration tool, the process went far quicker and smoother than before, while trivially supporting features such as logging of weird conditions (see previous example). The entire framework was about 1000 lines of code, but the rulesets themselves were in total about 100 – an order of magnitude less than the previous version. We went from having a special purpose “copy tool” to a general purpose migration tool with myriad of uses. Since the framework included an n-way multi-file iterator, we could have n-way rules for different parts of the tree, e.g. use a different number of source directories in each case, something we ended up doing routinely.
</p><p>
<strong>Implementation.</strong> I wrote the framework in .NET / C#, since the company was a Windows-shop. This was not emphasised in the article, since pretty much anything (Python, C++) could be used to implement this framework in no more than 1000 lines of code. (Note that the rules were given in C# using framework primitives, i.e. the framework did not include a parser.)
</p>]]></content:encoded>
</item>
<item>
<title>Book Recommendation: C Interfaces and Implementations</title>
<link>http://bytepawn.com/2008/07/21/book-recommendation-c-interfaces-and-implementations</link>
<guid isPermaLink='false'>http://bytepawn.com/2008/07/21/book-recommendation-c-interfaces-and-implementations</guid>
<pubDate>Mon, 21 Jul 2008 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
by David R. Hanson
544 pages, Addison-Wesley Professional
<a href="http://www.amazon.com/Interfaces-Implementations-Techniques-Addison-Wesley-Professional/dp/0201498413">Amazon homepage</a> - <a href="http://www.cs.princeton.edu/software/cii/">Official homepage</a>
</p><p>
<img src="/images/cii.png" />
</p><p>
<strong>Table of contents:</strong><br/>
1. Introduction 2. Interfaces and Implementations<br/>
3. Atoms 4. Exceptions and Assertions<br/>
5. Memory Management 6. More Memory Management<br/>
7. Lists 8. Tables 9. Sets 10. Dynamic Arrays 11. Sequences 12. Rings 13. Bit Vectors<br/>
14. Formatting 15. Low-Level Strings 16. High-Level Strings<br/>
17. Extended-Precision Arithmetic 18. Arbitrary-Precision Arithmetic 19. Multiple-Precision Arithmetic<br/>
20. Threads
</p><p>
<strong>Short version.</strong> This book is highly recommended for the padawan C programmer on his quest to become a master. For the experienced C programmer this will be an easy and enjoyable read with one or two tricks or useful idioms per chapter. It is often recommended to read other people's code, but reading an exceptionally well-written book about good code is much more fun. 
</p><p>
The book is written in the literate programming style, meaning that the book is interspersed with code fragments. Although it requires page flipping at times and is odd at first, it is the best technique for presenting code with the accompanying description I have come across. The worst aspect here is the author's use of the += meta-operator for appending code to a previous fragment, which almost always requires page-flipping.
</p><p>
As the book's title suggests the most basic pattern put forth is the seperation of interface into a .h file and implementation into .c files. Beginner programmers will first learn the
</p><p>
<pre>
#ifndef FOO_H
#define FOO_H
... interface for FOO
#endif
</pre>
</p><p>
pattern used in C programs to avoid duplicate <span class="code">#include</span>s.
</p><p>
The objects discussed in the book are every programmer's standard tools such as:
</p><p>
<ul>
<li>memory managers</li>
<li>lists, tables, sets, rings</li>
<li>atoms, strings</li>
<li>threads</li>
</ul>
</p><p>
Fortunately most programmers don't need to reimplement these and instead use standard libraries. In the case of C++ the Standard Template Library (STL) includes much of the functionality described by Hanson. Still, real programmers know what goes on under the hood of their libraries, so looking at the author's implementations is highly recommended. Since programmers working in high-performance, systems and database programming have to (re)implement custom versions of these modules, looking at Hanson's code is easily worth it for them.
</p><p>
C Interfaces and Implementations is one of the few books where the <strong>Further Reading</strong> and <strong>Exercises</strong> sections at the end of each chapter are worth reading. Unlike academic style enumerated bibliographies here Hanson gives a short one sentence overview about the referenced papers and books. The Exercises point to possible extensions and modifications of the modules described in each chapter. Also, if you end up using Hanson's code in your projects the <strong>Interface Summary</strong> at the end of the book will come in handy.
</p><p>
Experienced programmers will find some oddities to disagree with. Here I will mention two I have come across.
</p><p>
<strong>Typedef'd data types.</strong> Throughout the interfaces Hanson uses the convention that object type names are <span class="code">typedef</span>'d to T, so instead of writing out <span class="code">append(List* l, void* obj)</span> he would write <span class="code">append(T l, void* obj)</span>. In this case, the * would be in the <span class="code">typedef</span> making the function declarations hard to interpret. This trick seems counterproductive, more is lost in readability than gained by typing less characters.
</p><p>
<strong>Exceptions.</strong> One of the first modules described is an exception-handling mechanism implemented with the aid of the C preprocessor, in other words macro magic. If C is a motorcycle and C++ is a car, then this is like welding two motorcycles together to get a car. If I couldn't live without exceptions, I'd just use C++.
</p><p>
These issues aside, the book is highly recommended for the beginning C programmer, as it will teach through repeated use the best-practice idioms of C programming style. These patterns are demonstrated using common objects such as lists and sets, so beginners will gain additional insight from their inner workings. For experienced programmers the book will mostly be a fun read. However, advanced concepts such as the implementation of green threads will most likely be new material even for the seasoned programmer.
</p><p>
Still not convinced? Visit the <a href="http://www.cs.princeton.edu/software/cii/">book's official homepage</a> to download a sample chapter and all the C source code.
</p>]]></content:encoded>
</item>
<item>
<title>Bloatware is a Business Opportunity (Part II)</title>
<link>http://bytepawn.com/2008/07/15/bloatware-is-a-business-opportunity-part-ii</link>
<guid isPermaLink='false'>http://bytepawn.com/2008/07/15/bloatware-is-a-business-opportunity-part-ii</guid>
<pubDate>Tue, 15 Jul 2008 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
<a href="http://bytepawn.com/2008/07/15/bloatware-is-a-business-opportunity-part-i/">Read Part I first.</a>
</p><p>
Given bloatware, what is the end-user to do?
</p><p>
Ben Kenobi would tell you to use  an elegant weapon from a more civilized time.
</p><p>
<img src="/images/obi-wan-ben-kenobi.jpg" />
</p><p>
<strong>1. Use an older version.</strong> In this case, <a href="http://www.oldversion.com">oldversion.com</a> leads the way. Whenever I do a reinstall, I use it to retrieve:
<ul>
<li>Adobe Reader 6</li>
<li>Nero 6</li>
<li>WinAMP</li>
<li>PowerDVD</li>
<li>WinRAR</li>
<li>...</li>
</ul>
These older versions have acceptable disk, memory and CPU footrints.
</p><p>
<strong>2. Use a replacement.</strong> This is where it gets interesting, and why this post is tagged as <a href="http://bytepawn.com/category/entrepreneurship/">Entrepreneurship</a>. When a software corporation gets too large, management types take over decision making and start relying on releasing a new version every 12-24 months for cashflow while minimizing risk. The result is software bloat, an opportunity for startups to create a lightweight, killer version of the software. This is what happened or is happening to the bloatware I mentioned in <a href="http://bytepawn.com/2008/07/15/bloatware-is-a-business-opportunity-part-i/">Part I</a>:
<ul>
<li>Adobe Reader superseded by <a href="http://www.foxitsoftware.com/">FoxIt Reader</a></li>
<li>Nero is superseded by <a href="http://www.deepburner.com">DeepBurner</a></li>
<li>Adobe Photoshop superseded by <a href="http://www.getpaint.net">Paint.NET</a></li>
<li>Norton AntiVirus superseded by <a href="http://www.grisoft.com/">AVG</a></li>
</ul>
</p><p>
Notice the word <a href="http://www.merriam-webster.com/dictionary/supersede">supersede</a>:
</p><p>
<blockquote><span style="font-style:normal">
Main Entry: <strong>su·per·sede</strong> 
Pronunciation: \ˌsü-pər-ˈsēd\ 
Function: <em>transitive verb</em> 
...
<strong>1 a:</strong> to cause to be set aside <strong>b:</strong> to force out of use as inferior
<strong>2:</strong> to take the place or position of
<strong>3:</strong> to displace in favor of another
</span>
</blockquote>
</p><p>
<strong>There are many markets where the older players have become bloatware but no good replacements have yet popped up, presenting a business opportunity for startups.</strong> Here I will only mention one example I have personal experience with as a software developer: architectural CAD software. The standard players all have old legacy codebases which are bloated, they are very slow to add features and are unable to improve the application in fundamental ways. The market might be ripe for a small, lean and mean CAD machine. (On the other hand, CAD is not mainstream software, so marketing and sales is hard.)
</p><p>
<strong>3. Use a web application.</strong> AJAX and Flash is where all the start-up activity is in Silicon Valley. When using a web application, users innately expect less functionality that works better as compared to a desktop application, making these type of markets ideal for a <12 month startup cycle. Again sticking to the four examples in <a href="http://bytepawn.com/2008/07/15/bloatware-is-a-business-opportunity-part-i/">Part I</a>:
</p><p>
<ul>
<li>Online PDF viewing: <a href="http://www.scribd.com">Scribd</a> makes it possible, but it's a step backward since it's Flash, so there's still room to innovate; e.g. instead of rendering in Flash, render in HTML!</li>
<li>Online backup software: the user's upstream bandwidth is the only limit here; once that is surpassed, doing local backups and burns will be superseded by a company doing it for you and snail mailing the media to your postal address</li>
<li>Online image editing: there's <a href="http://www.splashup.com">SplashUp</a> but there's lots of room to innovate here</li>
<li>Online AntiVirus: since most users get viruses through the Internet there's probably a market for a scanning and blocking proxy service</li>
</ul>
</p><p>
The Web 2.0 motto is <a href="http://www.37signals.com/svn/archives2/forbes_the_20_most_important_tools.php">Do one thing and do it well</a>. In the desktop software world you have to do more, but the idea is the same: <strong>be lean and mean with a clean user interface and workflow</strong>. Bloatware always looses in the end.
</p><p>
<img src="/images/death-star.jpg" />
</p>]]></content:encoded>
</item>
<item>
<title>Bloatware is a Business Opportunity (Part I)</title>
<link>http://bytepawn.com/2008/07/15/bloatware-is-a-business-opportunity-part-i</link>
<guid isPermaLink='false'>http://bytepawn.com/2008/07/15/bloatware-is-a-business-opportunity-part-i</guid>
<pubDate>Tue, 15 Jul 2008 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
Bloatware is defined by <a href="http://en.wikipedia.org/wiki/Software_bloat">Wikipedia</a> as:
</p><p>
<blockquote>Software bloat, also known as bloatware or elephantware, is a term used in both a neutral and disparaging sense, to describe the tendency of newer computer programs to be larger, or to use larger amounts of system resources (mass storage space, processing power or memory) than necessary for the same or similar benefits from older versions to its users. Additionally, the term bloatware is used in common language for pre-installed, huge software bundles, mostly consisting of demos and trial ware.</blockquote>
<img src="/images/bloat.jpg" />
</p><p>
My favorite example of bloatware is <strong>Adobe Reader</strong>, currently at version 9. This latest version is a  33MB download, but you can't just simply download it. You first have to get the Adobe Reader Download Manager, a plugin just for downloading Adobe Reader (!). After installation the thing takes up 210MB of your harddrive (!). <a href="http://blog.micropledge.com/2008/07/adobe-reader-9/">Ben Hoyts' article</a> is especially funny:
</p><p>
<blockquote>For starters, version 8 was a 22 MB download. Version 9 is a mere 33 MB — a whole major version up, and not even twice as big. The default download includes a 19 MB eBay Desktop program, for all your “faster searching, smarter bidding” needs. So tempting … but I opted out.
</p><p>
On my cable connection, it took about 5 minutes to download, nicely allowing me enough time to brew a decent cup of coffee while I waited.
</p><p>
But it wasn’t just a simple, ordinary download. First Adobe told me to download a Firefox plugin. I assumed the plugin would help me read PDFs in my browser. But oh no, this was a special plugin, an Adobe Reader Download Manager (TM) — a plugin specially designed to help Firefox download Adobe’s powerful PDF viewer.
</p><p>
After the plugin was installed and Firefox restarted, the download began. I couldn’t wait to try Adobe’s MUCH FASTER and SMARTER product.
</p><p>
Download done, I double-clicked the installer. It spent a long time unpacking and validating the installer, which gave me warm fuzzies about Adobe’s good grasp of stability, security, and enterprisey robustness.
</p><p>
After the unpacking, the install process itself took 10 minutes. I could only thank Adobe’s engineers, presuming they were filling up my hard drive with yummy icons, tasty DLLs, and amazing 3D JavaScript add-ons. No matter — the 210 MB it required was there to be used.
</p><p>
I had just slurped down the dregs of my coffee when the installer finished. I was so thankful when it told me I needed to restart my computer, welcoming the extra time to drink coffee, as well as the pure delight I knew I’d get from starting all my applications again.
</p><p>
I could finally try out this new software. I was impressed. It started in a minuscule 13 seconds, plus the time it took me to skim their poetic and beneficent license agreement.</blockquote>
</p><p>
My other favorite is <strong>Nero</strong>, the CD and DVD burning tool. The latest version is Nero Ultra Edition 8, a 185MB download, which includes: Nero Home, StartSmart, Burning ROM, WaveEditor, SoundTrax, Vision, Recode, ShowTime, MediaHome, PhotoSnap, Cover Designer, Toolkit, BackItUp, and SoundBox. The amount of bloat here is stunning. There's actually an RSS reader in there, so you can catch up while waiting for your CD to finish. Nero went from burning CDs to wanting to "Create and Manage Your Digital Life", this coming straight from their website. Nero is so bad, there's actually a project called <a href="http://updatepack.nl">Nero Lite</a>, where they strip the bloat from the installer to bring it down to 20MB.
</p><p>
And then there is <strong>Adobe Photoshop</strong>. The latest version, Adobe Photoshop CS3 comes in at 1GB installed (that's 2GB on the Mac, probably because it includes both the PowerPC and Intel binaries) according to <a href="http://www.adobe.com/products/photoshop/photoshop/systemreqs/">adobe.com</a>. Photoshop is so bloated that one of the developers, <a href="http://blogs.adobe.com/jnack/2007/11/photoshop_as_se.html">John Nack wrote about it</a> on his personal blog:
</p><p>
<blockquote>Photoshop has been accreting power & users for the better part of two decades.  The once-little app has proven almost endlessly adaptable to new needs and workflows, but all that morphing has a price.  In many cases we've traded simplicity for power, and not all the pieces look like part of a cohesive whole.  In fact, I sometimes joke that looking at some parts of the app is like counting the rings in a tree: you can gauge when certain features arrived by the dimensions & style of the dialog.  (Cue old-timey prospector voice: "Oh, Lighting Effects--you can see the scorch marks from the great fire of '43...")
</p><p>
This isn't exactly a news flash--far from it.  So, the question is, What exactly are we gonna do about it?  <strong>No one wants to work with--or work on--some shambling, bloated monster of a program.</strong> (Emphasis added)</blockquote>
</p><p>
The last example is <strong>Norton AntiVirus</strong>. According to <a href="http://www.symantec.com/norton/antivirus">symantec.com</a>, the latest 2008 version takes up 300MB on your disk. But with Norton, it's not so much the hard disk space as it is the fact that is installs memory resident daemons that completely hijack your system. Most computers will crawl to a halt and become unusable if Norton is running. Norton AntiVirus has become the problem it was designed to eradicate: a virus. I personally would rather have viruses on my computer than run Norton AntiVirus. <a href="http://www.esquiremac.com/2008/07/norton-may-be-worse-than-any-virus-you-could-get/">Others</a> have come to a similar conclusion:
</p><p>
<blockquote>As I recall, Norton was the program that harassed her so badly that she decided to switch to Mac. I remember my experience with using a PC and having Norton. It was terrible. <strong>I finally came to the conclusion that I had to uninstall it, regardless of what perils I might be subjecting myself to. I was sure that Norton screwed with my computer’s performance far more than any virus would.</strong> (Emphasis added)</blockquote>
</p><p>
<a href="http://bytepawn.com/2008/07/15/bloatware-is-a-business-opportunity-part-ii/">Continue to Part II.</a>
</p><p>
</p>]]></content:encoded>
</item>
<item>
<title>The Hollywood Model in Software Engineering</title>
<link>http://bytepawn.com/2008/07/14/the-hollywood-model-in-software-engineering</link>
<guid isPermaLink='false'>http://bytepawn.com/2008/07/14/the-hollywood-model-in-software-engineering</guid>
<pubDate>Mon, 14 Jul 2008 00:00:00 +0000</pubDate>
<dc:creator>Marton Trencseni</dc:creator>
<content:encoded><![CDATA[<p>
One of the downsides of working at a large corporation is low work efficiency and inter-project idle-times. From my own experience, I estimate that the corporate programmer could be 2x - 3x more productive, in other words, he is performing at 33% - 50% capacity. The interesting question is, is there another way? I've always known how Hollywood movies are produced, but I've never made the connection to software project management pointed out by Sue Bushell in her piece entitled <a href="http://www.cio.com.au/index.php/id;1958786017">Replicating the Hollywood Model</a>.
</p><p>
<blockquote>McElroy believes the IT industry has much to learn from Hollywood's eventual transformation into an industry in which largely outsourced production companies primarily make films on a project-by-project basis.</blockquote>
</p><p>
<img src="/images/hollywood.jpg" />
</p><p>
What follows is my interpretation of the model.
</p><p>
In the Hollywood Model there is no continuous employment, instead, participants are handpicked and assembled on a project-by-project basis. This has some obvious benefits and drawbacks:
</p><p>
<strong>Bootstraping overhead.</strong> The producer has to re-assemble a team for each project. Depending on the size of the product, this might take several weeks or months. The model seems to be ill-suited when a quick response (e.g. to competition) is required.
</p><p>
<strong>Competition (participants).</strong> The producer can hire the best for each project. Participants who have proven themselves previously are re-hired. Poor performers are not.
</p><p>
<strong>Competition (projects).</strong> Participants may choose between different projects. High-performers will choose more interesting tasks.
</p><p>
<strong>Wages.</strong> Proven high-performers can demand higher wages. When compared to the Corporate Model, different wages introduce less friction.
</p><p>
<strong>Dynamics.</strong> There is constant change and rearrangement of projects and groups. Thus, high-performing combinations are more likely to form.
</p><p>
<strong>No job safety.</strong> Participants are likely to be left without projects for differing amounts of time. For people with families, this might be unacceptable.
</p><p>
<strong>Alternative management.</strong> In her article, Sue Bushell quotes others:
<blockquote>"I don't have to ramp up, I don't have to ramp down, I don't need a huge management layer to oversee the resources. And I don't have the cashflow crunches that you go through when you have a big staff, the work is over, and you must come up with something for everybody to do ... or let them go," says Seropian.</blockquote>
Her claim is that the Hollywood Model requires less management. This is something that must be proven by hard numbers, it certainly is not obvious to me. You could argue that a more disconnected, ad-hoc group requires more oversight.
</p><p>
The bootstraping overhead alone is enough to warrant a <strong>Corporate Hollywood Model</strong>, which is used by some large corporations such as game developers (and Google?). Participants are employees assigned to a project within the "corporate matrix". This in effect voids most of the benefits (such as wages based on merit) for employees.
</p><p>
In other corporate sectors this model is counter-productive. In desktop software publishing, the corporation's revenue stream is tied to delivering and selling new versions of the software every 12-24 months. It doesn't make sense to constantly re-assemble and disband the teams.
</p><p>
The Hollywood Model is probably well-suited for <strong>Internet startups</strong>, which are characterized by an initial surge of creativity / development followed by periods of maintenance. Only if the site is successful will there be a second surge, making continuous employment impractical.
</p><p>
Smaller web development outfits naturally use the model and refer to it as contract-based work. In this case, projects are small so the bootstrapping overhead is negligible. In my experience, these types of projects usually do not involve cutting-edge development, so top talent avoids it.
</p><p>
Others on this topic:
<ul>
	<li><a href="http://www.cio.com.au/index.php/id;1958786017">Sue Bushell: Replicating the Hollywood Model</a></li>
	<li><a href="http://voxpopdesign.com/bloomburst/?p=207">Matthew Reinbold: Exploring the Hollywood Model</a></li>
</ul>
</p>]]></content:encoded>
</item>
</channel>
</rss>
