<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Eric's Tech Blog</title>
	
	<link>http://eric.lubow.org</link>
	<description>Thoughts, musings, and other useless idealistic systems hoopla.</description>
	<lastBuildDate>Mon, 09 Nov 2009 00:03:36 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/lubow/PAyY" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>Git GUI on Mac OS X</title>
		<link>http://feedproxy.google.com/~r/lubow/PAyY/~3/hFICc2M0eK4/</link>
		<comments>http://eric.lubow.org/2009/mac/git-gui-on-mac-os-x/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 13:15:56 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=338</guid>
		<description><![CDATA[




I have been using Git a lot lately and have found a lot of things I like better in Git than in Subversion.  The one major item that was really bothering me was that there wasn&#8217;t really too many Git clients that could help you visualize the repository.  I mean show merges, commits, [...]]]></description>
			<content:encoded><![CDATA[<p>I have been using Git a lot lately and have found a lot of things I like better in Git than in Subversion.  The one major item that was really bothering me was that there wasn&#8217;t really too many Git clients that could help you visualize the repository.  I mean show merges, commits, branching, blame, etc.  Seeing that CVS and Subversion have been around for a lot longer, there are many clients for them and now that I have been using Git for a while on the command line, I decided to take a look again.</p>
<p>What I am looking for is simple.  I want 2 things:<br />
1) In the typical Mac style, I want a great looking interface.  I want to be able to see who did what, when, and why (assuming good commit messages from the developers).<br />
2) Easy navigation through all the features.  I am not planning on using any of the commands visually, I am still an archaic command line junkie.</p>
<p>One of my favorite features of git coming from Subversion is the ease of branching.  I branch for everything now that I am using git.  So in order to best track my changes, I was hoping for something to help me visualize my branches.  I didn&#8217;t count this specifically in my desires because it wasn&#8217;t a requirement to be acceptable, but it definitely would have helped to tip the scales.</p>
<p>I found a three clients that I thought were worth looking at (4 if you count <a href="http://macendeavor.com/gity">Gity</a>, but I am still using Leopard and Gity is just for Snow Leopard).</p>
<p>First I wanted to look at <a href="http://github.com/Caged/gitnub/">Gitnub</a>, but I couldn&#8217;t get it to run.  So pass on that and move on.</p>
<p>Second I looked at <a href="http://www.syntevo.com/smartgit/index.html">Smartgit</a>.  Smartgit is technically not released yet (still in the alpha/beta stages), but is still a great product.  It has that typical Java look and feel to it.  Nothing too flashy, but has a lot of potential.  I give them the benefit of the doubt since they are still in the early phases of production.  Smartgit also has a much cleaner file browser/interface than any of the other UIs tested.  Another clean item on the layout is tool tips.  They are helpful because there are quite a few buttons which are otherwise unlabelled.  There is a great button in the bottom right hand corner that maximizes the currently selected file into an automatic diff of HEAD vs. working tree.  It is worth noting that Smartgit, when released will <strong>not</strong> be free software.</p>
<p><strong>UPDATE:</strong> These are a few screen shots from SmartGit Beta 3.  This is the current release of SmartGit. </p>
<div id="attachment_342" class="wp-caption alignnone" style="width: 160px"><a href="http://eric.lubow.org/wp-content/uploads/2009/11/smartgit_filebrowser.jpg"><img src="http://eric.lubow.org/wp-content/uploads/2009/11/smartgit_filebrowser-150x150.jpg" alt="Smartgit File Browser" title="Smartgit File Browser" width="150" height="150" class="size-thumbnail wp-image-342" /></a><p class="wp-caption-text">Smartgit File Browser</p></div> <div id="attachment_343" class="wp-caption alignnone" style="width: 160px"><a href="http://eric.lubow.org/wp-content/uploads/2009/11/smartgit_filediff.jpg"><img src="http://eric.lubow.org/wp-content/uploads/2009/11/smartgit_filediff-150x150.jpg" alt="SmartGit File Diff" title="SmartGit File Diff" width="150" height="150" class="size-thumbnail wp-image-343" /></a><p class="wp-caption-text">SmartGit File Diff</p></div>
<p>Lastly I tried out <a href="http://gitx.frim.nl/">GitX</a>.  GitX is the closest thing to what I am looking for.  I would like the navigation to be a little more descriptive and the ability to see blame in a file, but it&#8217;s otherwise pretty good.  GitX provides a great branch/merge view.  Shows the line of the HEAD and where it came from.  It&#8217;s extremely handy when you&#8217;re working with a lot of branches.  The colored diffs were also very nice to look at and I have always been a fan of things are easier for me to read.  These items (visualized branches and colored diffs) are a scale tipper for me.</p>
<p><strong>UPDATE:</strong> These are a few screen shots from the stable version of GitX.</p>
<div id="attachment_345" class="wp-caption alignnone" style="width: 160px"><a href="http://eric.lubow.org/wp-content/uploads/2009/11/gitx_main.jpg"><img src="http://eric.lubow.org/wp-content/uploads/2009/11/gitx_main-150x150.jpg" alt="GitX Main Screen" title="GitX Main Screen" width="150" height="150" class="size-thumbnail wp-image-345" /></a><p class="wp-caption-text">GitX Main Screen</p></div> <div id="attachment_346" class="wp-caption alignnone" style="width: 160px"><a href="http://eric.lubow.org/wp-content/uploads/2009/11/gitx_main_browser.jpg"><img src="http://eric.lubow.org/wp-content/uploads/2009/11/gitx_main_browser-150x150.jpg" alt="GitX Main File Browser" title="GitX Main File Browser" width="150" height="150" class="size-thumbnail wp-image-346" /></a><p class="wp-caption-text">GitX Main File Browser</p></div> <div id="attachment_347" class="wp-caption alignnone" style="width: 160px"><a href="http://eric.lubow.org/wp-content/uploads/2009/11/gitx_current_changes.jpg"><img src="http://eric.lubow.org/wp-content/uploads/2009/11/gitx_current_changes-150x150.jpg" alt="GitX Current Changes" title="GitX Current Changes" width="150" height="150" class="size-thumbnail wp-image-347" /></a><p class="wp-caption-text">GitX Current Changes</p></div>
<p>I guess I still have a little time to wait for a solid Git client to meet my criteria.  If I could combine the cleanliness and branching look of GitX with the usability of SmartGit (with its up and coming featureset), then I would be set.  If you know of a good Git clients for the Mac that I don&#8217;t know about, leave it in the comments section.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/3MqK2y7OOHGZ2BKWD0H6ezUgKvo/0/da"><img src="http://feedads.g.doubleclick.net/~a/3MqK2y7OOHGZ2BKWD0H6ezUgKvo/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/3MqK2y7OOHGZ2BKWD0H6ezUgKvo/1/da"><img src="http://feedads.g.doubleclick.net/~a/3MqK2y7OOHGZ2BKWD0H6ezUgKvo/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/lubow/PAyY/~4/hFICc2M0eK4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2009/mac/git-gui-on-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://eric.lubow.org/2009/mac/git-gui-on-mac-os-x/</feedburner:origLink></item>
		<item>
		<title>One Time Modal Windows With Rails and Fancybox</title>
		<link>http://feedproxy.google.com/~r/lubow/PAyY/~3/s4RRFAiwa-M/</link>
		<comments>http://eric.lubow.org/2009/ruby/rails/one-time-modal-windows-with-rails-and-fancybox/#comments</comments>
		<pubDate>Tue, 03 Nov 2009 11:00:26 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=331</guid>
		<description><![CDATA[Let&#8217;s say that you have a situation that you want to have a modal window show up only once for each user.  It&#8217;s actually not that difficult although lots of Googling around got me nowhere.  I am choosing to use FancyBox for my modal window, but feel free to use your modal framework [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s say that you have a situation that you want to have a modal window show up only once for each user.  It&#8217;s actually not that difficult although lots of Googling around got me nowhere.  I am choosing to use <a href="http://fancybox.net/">FancyBox</a> for my modal window, but feel free to use your modal framework of choice.  So let&#8217;s get down to business.</p>
<p>First thing you&#8217;ll need to do is download <a href="http://fancybox.net/">FancyBox</a> and copy the stylesheets, images, and Javascript files to their proper/desired location in your Rails app.  Style the window according to your likings.</p>
<p>Whether it is right or wrong, I did this entirely in the view, without even pulling the Javascript out into the application.js (or even another Javascript file for that matter).  My reason was that I only want the modal window showing up on this page.  If you want your modal window to show up somewhere else (or on every page), then put the code in your layout.  But remember that this call will be executed every time the page loads. I put mine in a profile page which doesn&#8217;t get accessed that often so the conditional is not checked quite as frequently.</p>
<p>My application uses Facebook Connect and grabs the users Facebook Proxy email address (FB app developers will know what this is).  So I check if that&#8217;s the email I have for the user.  If yes, then I pop up a modal window on page load only once to get their regular email address and possibly a password so they can login to their account without Facebook Connect if they want.  When the modal window is shown, a variable is set in the cookie (note that this cookie is shared with authlogic for sessions) to ensure that the modal window isn&#8217;t shown again.</p>
<p>The explanation of the code is below with comments in the code.</p>
<p>The code that goes in the view is as follows:</p>
<div class="codecolorer-container rails default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;height:450px;"><div class="rails codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#008000; font-style:italic;"># Check the user's email and see if they have a facebook proxy email address</span><br />
<span style="color:#008000; font-style:italic;"># Check the user's cookie to see if they have already seen the Facebook modal window</span><br />
<span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006600; font-weight:bold;">%</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@user</span>.<span style="color:#9900CC;">email</span>.<span style="color:#9900CC;">match</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>^.<span style="color:#006600; font-weight:bold;">+</span>proxymail.<span style="color:#9900CC;">facebook</span>.<span style="color:#9900CC;">com</span>$<span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#006600; font-weight:bold;">&#40;</span>cookies<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:facebook_email_modal_shown</span><span style="color:#006600; font-weight:bold;">&#93;</span> != <span style="color:#996600;">&quot;1&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span><br />
&nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># Include the JS and stylesheets</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006600; font-weight:bold;">%</span>= <span style="color:#5A0A0A; font-weight:bold;">javascript_include_tag</span> <span style="color:#996600;">'jquery.fancybox-1.2.3'</span> <span style="color:#006600; font-weight:bold;">%&gt;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006600; font-weight:bold;">%</span>= <span style="color:#5A0A0A; font-weight:bold;">stylesheet_link_tag</span> <span style="color:#996600;">'jquery.fancybox'</span> <span style="color:#006600; font-weight:bold;">%&gt;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;</span>script type=<span style="color:#996600;">&quot;text/javascript&quot;</span> charset=<span style="color:#996600;">&quot;utf-8&quot;</span><span style="color:#006600; font-weight:bold;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">/*</span> Function to <span style="color:#CC0066; font-weight:bold;">load</span> the modal window by clicking the <span style="color:#996600;">&quot;invisible&quot;</span> link <span style="color:#006600; font-weight:bold;">*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; var modalLoadFunction = function<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQuery<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;a.modalGroup&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">click</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; clearInterval<span style="color:#006600; font-weight:bold;">&#40;</span>globalInterval<span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">/*</span> Hide the div on <span style="color:#CC0066; font-weight:bold;">load</span> &nbsp;<span style="color:#9966CC; font-weight:bold;">and</span> set the modal window options <span style="color:#006600; font-weight:bold;">*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; jQuery<span style="color:#006600; font-weight:bold;">&#40;</span>document<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">ready</span><span style="color:#006600; font-weight:bold;">&#40;</span>function<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQuery<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'#modalFacebookEmail'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#5A0A0A; font-weight:bold;">hide</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">/*</span> Check out the FancyBox site <span style="color:#9966CC; font-weight:bold;">for</span> more information on the options <span style="color:#006600; font-weight:bold;">*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQuery<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;a.modalGroup&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">fancybox</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#996600;">'zoomSpeedIn'</span>: <span style="color:#006666;">200</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#996600;">'zoomSpeedOut'</span>: <span style="color:#006666;">250</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#996600;">'overlayShow'</span>: <span style="color:#0000FF; font-weight:bold;">true</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#996600;">'overlayOpacity'</span>: <span style="color:#006666;">0.6</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#996600;">'enableEscapeButton'</span>: <span style="color:#0000FF; font-weight:bold;">true</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#996600;">'hideOnContentClick'</span>: <span style="color:#0000FF; font-weight:bold;">false</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#996600;">'hideOnOverlayClick'</span>: <span style="color:#0000FF; font-weight:bold;">false</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#996600;">'centerOnScroll'</span>: <span style="color:#0000FF; font-weight:bold;">true</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">/*</span> Kickoff the modal window as soon as possible <span style="color:#006600; font-weight:bold;">*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; globalInterval = setInterval<span style="color:#006600; font-weight:bold;">&#40;</span>modalLoadFunction, 50<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>; <br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;/</span>script<span style="color:#006600; font-weight:bold;">&gt;</span><br />
<br />
&nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># Invisible link for the JS to click()</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;</span>a id=<span style="color:#996600;">&quot;inline&quot;</span> href=<span style="color:#996600;">&quot;#modalFacebookEmail&quot;</span> <span style="color:#9966CC; font-weight:bold;">class</span>=<span style="color:#996600;">&quot;modalGroup&quot;</span> id=<span style="color:#996600;">&quot;modalFunction&quot;</span><span style="color:#006600; font-weight:bold;">&gt;&lt;/</span>a<span style="color:#006600; font-weight:bold;">&gt;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;</span>div style=<span style="color:#996600;">&quot;display:none&quot;</span> id=<span style="color:#996600;">'modalFacebookEmail'</span><span style="color:#006600; font-weight:bold;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># Change the value in the cookie so the modal window is only shown once</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006600; font-weight:bold;">%</span> cookies<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:facebook_email_modal_shown</span><span style="color:#006600; font-weight:bold;">&#93;</span> = 1 <span style="color:#006600; font-weight:bold;">%&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006600; font-weight:bold;">%</span> <span style="color:#5A0A0A; font-weight:bold;">form_for</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0066ff; font-weight:bold;">@user</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">%&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006600; font-weight:bold;">%</span>= f.<span style="color:#9900CC;">error_messages</span> <span style="color:#006600; font-weight:bold;">%&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;</span>h3<span style="color:#006600; font-weight:bold;">&gt;</span>Facebook Email Address<span style="color:#006600; font-weight:bold;">&lt;/</span>h3<span style="color:#006600; font-weight:bold;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;</span>p<span style="color:#006600; font-weight:bold;">&gt;</span>If you want to login into the website <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#9966CC; font-weight:bold;">not</span> logged into Facebook, please provide your email address <span style="color:#9966CC; font-weight:bold;">and</span> a password.<span style="color:#006600; font-weight:bold;">&lt;/</span>p<span style="color:#006600; font-weight:bold;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;</span>br <span style="color:#006600; font-weight:bold;">/&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;</span>p<span style="color:#006600; font-weight:bold;">&gt;&lt;</span>strong<span style="color:#006600; font-weight:bold;">&gt;</span>Email Address<span style="color:#006600; font-weight:bold;">&lt;/</span>strong<span style="color:#006600; font-weight:bold;">&gt;&lt;</span>br <span style="color:#006600; font-weight:bold;">/&gt;&lt;</span> <span style="color:#006600; font-weight:bold;">%</span>= f.<span style="color:#9900CC;">text_field</span> <span style="color:#ff3333; font-weight:bold;">:email</span> <span style="color:#006600; font-weight:bold;">%&gt;&lt;/</span>p<span style="color:#006600; font-weight:bold;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;</span>p<span style="color:#006600; font-weight:bold;">&gt;&lt;</span>strong<span style="color:#006600; font-weight:bold;">&gt;</span>Password<span style="color:#006600; font-weight:bold;">&lt;/</span>strong<span style="color:#006600; font-weight:bold;">&gt;&lt;</span>br <span style="color:#006600; font-weight:bold;">/&gt;&lt;</span> <span style="color:#006600; font-weight:bold;">%</span>= f.<span style="color:#5A0A0A; font-weight:bold;">password_field</span> <span style="color:#ff3333; font-weight:bold;">:password</span> <span style="color:#006600; font-weight:bold;">%&gt;&lt;/</span>p<span style="color:#006600; font-weight:bold;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;</span>p<span style="color:#006600; font-weight:bold;">&gt;&lt;</span>strong<span style="color:#006600; font-weight:bold;">&gt;</span>Password Confirmation<span style="color:#006600; font-weight:bold;">&lt;/</span>strong<span style="color:#006600; font-weight:bold;">&gt;&lt;</span>br <span style="color:#006600; font-weight:bold;">/&gt;&lt;</span> <span style="color:#006600; font-weight:bold;">%</span>= f.<span style="color:#5A0A0A; font-weight:bold;">password_field</span> <span style="color:#ff3333; font-weight:bold;">:password_confirmation</span> <span style="color:#006600; font-weight:bold;">%&gt;&lt;/</span>p<span style="color:#006600; font-weight:bold;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;</span>p<span style="color:#006600; font-weight:bold;">&gt;&amp;</span>nbsp;<span style="color:#006600; font-weight:bold;">&lt;/</span>p<span style="color:#006600; font-weight:bold;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># Note the method for closing the modal window</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;</span>p<span style="color:#006600; font-weight:bold;">&gt;&lt;</span> <span style="color:#006600; font-weight:bold;">%</span>= f.<span style="color:#9900CC;">submit</span> <span style="color:#996600;">'Update'</span> <span style="color:#006600; font-weight:bold;">%&gt;</span> <span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">&lt;</span>a onClick=<span style="color:#996600;">&quot;jQuery('a.modalGroup').fancybox.close()&quot;</span> href=<span style="color:#996600;">&quot;#&quot;</span><span style="color:#006600; font-weight:bold;">&gt;</span>Cancel<span style="color:#006600; font-weight:bold;">&lt;/</span>a<span style="color:#006600; font-weight:bold;">&gt;&lt;/</span>p<span style="color:#006600; font-weight:bold;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006600; font-weight:bold;">%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;/</span>div<span style="color:#006600; font-weight:bold;">&gt;</span><br />
<span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006600; font-weight:bold;">%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span></div></div>
<p>Now you have a modal window that is only shown once.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/7_JpOAtmN-jNzzcVcgSyWWEwGK0/0/da"><img src="http://feedads.g.doubleclick.net/~a/7_JpOAtmN-jNzzcVcgSyWWEwGK0/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/7_JpOAtmN-jNzzcVcgSyWWEwGK0/1/da"><img src="http://feedads.g.doubleclick.net/~a/7_JpOAtmN-jNzzcVcgSyWWEwGK0/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/lubow/PAyY/~4/s4RRFAiwa-M" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2009/ruby/rails/one-time-modal-windows-with-rails-and-fancybox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://eric.lubow.org/2009/ruby/rails/one-time-modal-windows-with-rails-and-fancybox/</feedburner:origLink></item>
		<item>
		<title>Price of Commercials</title>
		<link>http://feedproxy.google.com/~r/lubow/PAyY/~3/4Et7UlzM8qs/</link>
		<comments>http://eric.lubow.org/2009/misc/price-of-commercials/#comments</comments>
		<pubDate>Wed, 28 Oct 2009 12:00:45 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[productivity]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=329</guid>
		<description><![CDATA[The price of commercials is especially high for engineers.  And by commercials, I don&#8217;t mean an intermission between pieces of a sitcom or drama, I mean the brief 15 seconds of an interruption when someone asks an engineer in the zone a question that takes 3 seconds to answer.  For the sake of [...]]]></description>
			<content:encoded><![CDATA[<p>The price of commercials is especially high for engineers.  And by commercials, I don&#8217;t mean an intermission between pieces of a sitcom or drama, I mean the brief 15 seconds of an interruption when someone asks an engineer in the zone a question that takes 3 seconds to answer.  For the sake of argument, let&#8217;s say an engineer gets interrupted a mere 5 times per day including lunch and a daily meeting (let&#8217;s call it a scrum for fun).</p>
<p>If it takes that engineer, admin, developer or whatever 10 minutes to get focused after each interruption and the initial getting into the office and getting into the swing of things; that means that out of an 8 hour day, 1 hour is wasted just refocusing.  Refocusing just puts you back on the issue, it doesn&#8217;t put you back in the zone.  Some engineers only get in the zone once per day.  At that rate, you can massively waste someone&#8217;s productivity with a 10 second interruption.</p>
<p>What&#8217;s my point?  Good question.  That commercial/question/interruption that someone is pushing onto that engineer could be the straw that broke the camel&#8217;s back on a deadline.  So be aware of the situation that your people are in, who is talking to them, who has access to them, and who takes advantage of that access.  Those precious periods of concentration can afford you a huge win or bring about a big loss.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/lSVkW71xT6wT-eVPtqoiySPbNc0/0/da"><img src="http://feedads.g.doubleclick.net/~a/lSVkW71xT6wT-eVPtqoiySPbNc0/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/lSVkW71xT6wT-eVPtqoiySPbNc0/1/da"><img src="http://feedads.g.doubleclick.net/~a/lSVkW71xT6wT-eVPtqoiySPbNc0/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/lubow/PAyY/~4/4Et7UlzM8qs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2009/misc/price-of-commercials/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://eric.lubow.org/2009/misc/price-of-commercials/</feedburner:origLink></item>
		<item>
		<title>Printing New Lines in Bash</title>
		<link>http://feedproxy.google.com/~r/lubow/PAyY/~3/EAEW6qeTM6M/</link>
		<comments>http://eric.lubow.org/2009/misc/printing-new-lines-in-bash/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 15:00:55 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[bash]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=211</guid>
		<description><![CDATA[Ran across this the other day and decided it required sharing.  If you want to print a new line &#8216;\n&#8216; in an echo statement in bash, one would think its just as simple as:
beacon:~ elubow$ echo &#34;This is a test\n&#34;
This is a test\n
The problem is that this doesn&#8217;t interpolate the newline character.  (For [...]]]></description>
			<content:encoded><![CDATA[<p>Ran across this the other day and decided it required sharing.  If you want to print a new line &#8216;<strong>\n</strong>&#8216; in an <strong>echo</strong> statement in bash, one would think its just as simple as:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">beacon:~ elubow$ echo &quot;This is a test\n&quot;<br />
This is a test\n</div></div>
<p>The problem is that this doesn&#8217;t interpolate the newline character.  (For more information on interpolation, see Wikipedia <a href="http://en.wikipedia.org/wiki/Variable_interpolation#Interpolation">here</a>.)  In order to have the newline interpolated, you need to add the command line switch &#8216;<strong>-e</strong>&#8216;.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">beacon:~ elubow$ echo -e &quot;This is a test\n&quot;<br />
This is a test</div></div>
<p>This will force Bash to interpolate any non-literal characters in the quotes.  <strong>Note:</strong> Unlike Perl, single or double quotes don&#8217;t matter here when Bash is deciding whether or not to interpolate the new line characters.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/eu0jJSOQoZox4IQnXboZlPQCycU/0/da"><img src="http://feedads.g.doubleclick.net/~a/eu0jJSOQoZox4IQnXboZlPQCycU/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/eu0jJSOQoZox4IQnXboZlPQCycU/1/da"><img src="http://feedads.g.doubleclick.net/~a/eu0jJSOQoZox4IQnXboZlPQCycU/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/lubow/PAyY/~4/EAEW6qeTM6M" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2009/misc/printing-new-lines-in-bash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://eric.lubow.org/2009/misc/printing-new-lines-in-bash/</feedburner:origLink></item>
		<item>
		<title>Apple Steps Up With Multitouch Mouse</title>
		<link>http://feedproxy.google.com/~r/lubow/PAyY/~3/LSvKDdJVl7Q/</link>
		<comments>http://eric.lubow.org/2009/mac/apple-steps-up-with-multitouch-mouse/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 22:44:40 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[apple]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=324</guid>
		<description><![CDATA[A while ago I wrote about how Apple needed an external multi-touch solution and that you can use your iPhone until then.  Apple did it and now released the Magic Mouse.
To quote Apple, &#8220;It&#8217;s the world&#8217;s first multi-touch mouse.&#8221;  It&#8217;s a wireless mouse that attaches to any computer that has a keyboard, mouse [...]]]></description>
			<content:encoded><![CDATA[<p>A while ago I <a href="http://eric.lubow.org/2009/mac/external-multi-touch-trackpad-for-a-mac/">wrote about</a> how Apple needed an external multi-touch solution and that you can <a href="http://eric.lubow.org/2009/mac/iphone-as-trackpad/">use your iPhone until then</a>.  Apple did it and now released the <a href="http://www.apple.com/magicmouse/">Magic Mouse</a>.</p>
<p>To quote Apple, &#8220;It&#8217;s the world&#8217;s first multi-touch mouse.&#8221;  It&#8217;s a wireless mouse that attaches to any computer that has a keyboard, mouse and Bluetooth via Bluetooth.  It&#8217;s sleek just like everything else Apple makes.  But the best part is that (as of now), its only $69.  Good work Apple.</p>
<p>I could go on and on about why I think its cool and what it can do, but why waste time on my website reading a summary, just check it out on Apple&#8217;s web site: <a href="http://www.apple.com/magicmouse/">http://www.apple.com/magicmouse/</a></p>

<p><a href="http://feedads.g.doubleclick.net/~a/J6OYuAwPPFL9di3ie0eTIp1m650/0/da"><img src="http://feedads.g.doubleclick.net/~a/J6OYuAwPPFL9di3ie0eTIp1m650/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/J6OYuAwPPFL9di3ie0eTIp1m650/1/da"><img src="http://feedads.g.doubleclick.net/~a/J6OYuAwPPFL9di3ie0eTIp1m650/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/lubow/PAyY/~4/LSvKDdJVl7Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2009/mac/apple-steps-up-with-multitouch-mouse/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://eric.lubow.org/2009/mac/apple-steps-up-with-multitouch-mouse/</feedburner:origLink></item>
		<item>
		<title>First Experience With Cassandra</title>
		<link>http://feedproxy.google.com/~r/lubow/PAyY/~3/JfC5qXBt094/</link>
		<comments>http://eric.lubow.org/2009/databases/first-experience-with-cassandra/#comments</comments>
		<pubDate>Mon, 19 Oct 2009 13:00:16 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[cassandra]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=294</guid>
		<description><![CDATA[I recently posted about my initial experience with Tokyo Cabinet.  Now it&#8217;s time to get to work on Cassandra.
Cassandra is the production database that&#8217;s in use on Facebook for handling their email system and Digg.  
One thing that I would like to note is that when I tested TC, I used the Perl [...]]]></description>
			<content:encoded><![CDATA[<p>I recently posted about my <a href="http://eric.lubow.org/2009/databases/tokyo-tyrant-and-tokyo-cabinet/">initial experience with</a> <a href="http://1978th.net/">Tokyo Cabinet</a>.  Now it&#8217;s time to get to work on <a href="http://incubator.apache.org/cassandra/">Cassandra</a>.</p>
<p><a href="http://incubator.apache.org/cassandra/">Cassandra</a> is the production database that&#8217;s in use on <a href="http://www.facebook.com/">Facebook</a> for handling their email system and <a href="http://digg.com/">Digg</a>.  </p>
<p>One thing that I would like to note is that when I tested TC, I used the Perl API for both TC and TT.  I tried both the Perl API and the Ruby API.  I couldn&#8217;t get the Ruby API (written by <a href="http://blog.evanweaver.com">Evan Weaver</a> of <a href="http://twitter.com/">Twitter</a>) it to work at all with the Cassandra server (although I am sure the server included with the gem works well).  I initially struggled quite a bit with the UUID aspects of the Perl API until I finally gave up and changed the <em>ColumnFamily CompareWith</em> type from</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;columnfamily</span> <span style="color: #000066;">CompareWith</span>=<span style="color: #ff0000;">&quot;TimeUUIDType&quot;</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;Users&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span></div></div>
<p>to</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;columnfamily</span> <span style="color: #000066;">CompareWith</span>=<span style="color: #ff0000;">&quot;BytesType&quot;</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;Users&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span></div></div>
<p>Then everything was working well and I began to write my tests.  The layout that I ended up using is going to be one that works in a schemaless fashion.  I created 2 consistent columns per user: <strong>email</strong> and <strong>person_id</strong>. Here is where it gets interesting and different for those of us used to RDBMS&#8217;s and having less columns.  For this particular project, every time a user is sent an email, there is a &#8220;row&#8221; (I call it a row for those unfamiliar with Cassandra terminology, it is actually a column) added in the format of: send_dates_&lt;date&gt; (note the structure below).  The value of this column is the mailing campaign id sent to the user on this date.  This means that if the user receives 365 emails per year at one a day, then there will be 365 rows (or Cassandra columns) that start with <strong>send_dates_</strong> and end with <strong>YYYY-MM-DD</strong>.  Note the data structure below in a JSON ish format.</p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Users <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <br />
&nbsp; &nbsp; <span style="color: #3366CC;">'foo@example.com'</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; email<span style="color: #339933;">:</span> <span style="color: #3366CC;">'foo@example.com'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; person_id<span style="color: #339933;">:</span> <span style="color: #3366CC;">'123456'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; send_dates_2009<span style="color: #339933;">-</span>09<span style="color: #339933;">-</span><span style="color: #CC0000;">30</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'2245'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; send_dates_2009<span style="color: #339933;">-</span><span style="color: #CC0000;">10</span><span style="color: #339933;">-</span>01<span style="color: #339933;">:</span> <span style="color: #3366CC;">'2247'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; <span style="color: #3366CC;">'bar@baz.com'</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; email<span style="color: #339933;">:</span> <span style="color: #3366CC;">'bar@baz.com'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; person_id<span style="color: #339933;">:</span> <span style="color: #3366CC;">'789'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; send_dates_2009<span style="color: #339933;">-</span>09<span style="color: #339933;">-</span><span style="color: #CC0000;">30</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'2245'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; send_dates_2009<span style="color: #339933;">-</span><span style="color: #CC0000;">10</span><span style="color: #339933;">-</span>01<span style="color: #339933;">:</span> <span style="color: #3366CC;">'2246'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>To understand all the data structures in Cassandra better, I strongly recommend reading <a href="http://arin.me/code/wtf-is-a-supercolumn-cassandra-data-model">WTF Is A SuperColumn Cassandra Data Model</a> and <a href="http://blog.evanweaver.com/articles/2009/07/06/up-and-running-with-cassandra/">Up And Running With Cassandra</a>.  They are written by folks at <a href="http://digg.com">Digg</a> and <a href="http://twitter.com/">Twitter</a> respectively and are well worth the reads.</p>
<p>So for my first iteration, I simply loaded up the data in the format mentioned above.  Every insert does an insert of an email and person_id just in case they aren&#8217;t there to begin with.  The initial data set has approximately 3.6 million records.  This caused all sorts of problems with the default configurations (ie kept crashing on me).  The changes I made to the default configuration are as follows:</p>
<ul>
<li>Change the maximum file descriptors from 1024 (system default) to 65535 (or unlimited)</li>
<li>Change the default minimum and maximum Java -Xms256M -Xmx2G (could not get the data to load past 2.5 million records without upping max memory values)</li>
</ul>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">&#91;</span>elubow<span style="color: #000000; font-weight: bold;">@</span>db5 db<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ <span style="color: #000000; font-weight: bold;">time</span> .<span style="color: #000000; font-weight: bold;">/</span>cas_load.pl <span style="color: #660033;">-D</span> 2009-09-30 <span style="color: #660033;">-c</span> queue-mail.ini <span style="color: #660033;">-b</span> lists<span style="color: #000000; font-weight: bold;">/</span><br />
usa: <span style="color: #000000;">99</span>,<span style="color: #000000;">272</span><br />
top: <span style="color: #000000;">3</span>,<span style="color: #000000;">661</span>,<span style="color: #000000;">491</span><br />
Total: <span style="color: #000000;">3</span>,<span style="color: #000000;">760</span>,<span style="color: #000000;">763</span><br />
<br />
real &nbsp; &nbsp;72m50.826s<br />
user &nbsp; &nbsp;29m57.954s<br />
sys &nbsp; &nbsp; 2m18.816s<br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span>elubow<span style="color: #000000; font-weight: bold;">@</span>db5 cassandra<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;"># du -sh data/Mailings/ # Prior to data compaction</span><br />
13G &nbsp; &nbsp; data<span style="color: #000000; font-weight: bold;">/</span>Mailings<span style="color: #000000; font-weight: bold;">/</span><br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span>elubow<span style="color: #000000; font-weight: bold;">@</span>db5 cassandra<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;"># du -sh data/Mailings/ # Post data compaction</span><br />
1.4G &nbsp; &nbsp;data<span style="color: #000000; font-weight: bold;">/</span>Mailings<span style="color: #000000; font-weight: bold;">/</span></div></div>
<p>It was interesting to note that the write latency of about 3.6 million records was 0.004 ms.  Also the data compaction brought the size of the records on disk down from 13G to 1.4G.  Those figures are being achieved with the reads and writes happening on the same machines.</p>
<p>The load of the second data set took a mere 30m when compared to loading that same data set into Tokyo Cabinet which took closer to 180m.</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">luxe: <span style="color: #000000;">936</span>,<span style="color: #000000;">911</span><br />
amex: <span style="color: #000000;">599</span>,<span style="color: #000000;">981</span><br />
mex: <span style="color: #000000;">39</span>,<span style="color: #000000;">700</span><br />
Total: <span style="color: #000000;">1</span>,<span style="color: #000000;">576</span>,<span style="color: #000000;">592</span><br />
<br />
real &nbsp; &nbsp;30m53.109s<br />
user &nbsp; &nbsp;12m53.507s<br />
sys &nbsp; &nbsp; 0m59.363s<br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span>elubow<span style="color: #000000; font-weight: bold;">@</span>db5 cassandra<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;"># du -sh data/Mailings/</span><br />
2.4G &nbsp; &nbsp;data<span style="color: #000000; font-weight: bold;">/</span>Mailings<span style="color: #000000; font-weight: bold;">/</span></div></div>
<p>Now that there is a dataset worth working with, it&#8217;s time to start the read tests.</p>
<p>For the first test, I am doing a simple <em>get</em> of the <strong>email</strong> column.  This is just to iterate over the column and find out the approximate speed of the read operations.</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Run 1: 134m59.923s<br />
Run <span style="color: #000000;">2</span>; 125m55.673s<br />
Run <span style="color: #000000;">3</span>: 127m21.342s<br />
Run <span style="color: #000000;">4</span>: 119m2.414s</div></div>
<p>For the second test, I made use of a Cassandra feature called <em>get_slice</em>.  Since I have columns that are in the format <strong>send_dates_YYYY-MM-DD</strong>, I used <em>get_slice</em> to grab all column names on a per-row (each email address) basis that were between <strong>send_dates_2009-09-29</strong> and <strong>send_dates_2009-10-29</strong>.  The maximum amount that could be matched were 2 (since I only loaded 2 days worth of data into the data base).  I used data from a 3rd day so I can get 0, 1, or 2 as results.</p>
<p>This first run is using the Perl version of the script.</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Email Count: <span style="color: #000000;">3557584</span><br />
Match <span style="color: #000000;">0</span>: <span style="color: #000000;">4</span>,<span style="color: #000000;">247</span><br />
Match <span style="color: #000000;">1</span>: <span style="color: #000000;">1</span>,<span style="color: #000000;">993</span>,<span style="color: #000000;">273</span><br />
Match <span style="color: #000000;">2</span>: <span style="color: #000000;">1</span>,<span style="color: #000000;">560</span>,064<br />
<br />
real &nbsp; &nbsp;177m23.000s<br />
user &nbsp; &nbsp;45m21.859s<br />
sys &nbsp; &nbsp; 9m17.516s<br />
<br />
Run <span style="color: #000000;">2</span>: 151m27.042s</div></div>
<p>Subsequent runs I began to run into API issues and rewrote the same script in Python to see if the more well tested <a href="http://wiki.apache.org/cassandra/API">Thrift</a> Python API was faster than the <a href="http://wiki.apache.org/cassandra/API">Thrift</a> Perl API (and wouldn&#8217;t give me timeout issues).  The Perl timeout issues ended up being fixable, but I continued with the tests in Python.</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">&#91;</span>elubow<span style="color: #000000; font-weight: bold;">@</span>db5 db<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ <span style="color: #000000; font-weight: bold;">time</span> python cas_get_slice.py<br />
<span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #000000;">0</span>: <span style="color: #000000;">4170</span>, <span style="color: #000000;">1</span>: <span style="color: #000000;">1935783</span>, <span style="color: #000000;">2</span>: <span style="color: #000000;">1560042</span><span style="color: #7a0874; font-weight: bold;">&#125;</span><br />
Total: <span style="color: #000000;">3557584</span><br />
<br />
real &nbsp; &nbsp;213m57.854s<br />
user &nbsp; &nbsp;14m57.768s<br />
sys &nbsp; &nbsp; 0m51.634s<br />
<br />
Run <span style="color: #000000;">2</span>: 132m27.930s<br />
Run <span style="color: #000000;">3</span>: 156m19.906s<br />
Run <span style="color: #000000;">4</span>: 127m34.715s</div></div>
<p>Ultimately with Cassandra, there was quite a bit of a learning curve.  But in my opinion is well worth it.  Cassandra is an extremely powerful database system that I plan on continuing to explore in greater detail with a few more in depth tests.  If you have the chance, take a look at Cassandra.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/sturxxIeUoGRe1swynxGv8lV92M/0/da"><img src="http://feedads.g.doubleclick.net/~a/sturxxIeUoGRe1swynxGv8lV92M/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/sturxxIeUoGRe1swynxGv8lV92M/1/da"><img src="http://feedads.g.doubleclick.net/~a/sturxxIeUoGRe1swynxGv8lV92M/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/lubow/PAyY/~4/JfC5qXBt094" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2009/databases/first-experience-with-cassandra/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://eric.lubow.org/2009/databases/first-experience-with-cassandra/</feedburner:origLink></item>
		<item>
		<title>Migrations Without belongs_to Or references</title>
		<link>http://feedproxy.google.com/~r/lubow/PAyY/~3/2McyteZt0kc/</link>
		<comments>http://eric.lubow.org/2009/ruby/rails/migrations-without-belongs_to-or-references/#comments</comments>
		<pubDate>Wed, 14 Oct 2009 14:00:00 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[database]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=308</guid>
		<description><![CDATA[Normally when do a database migration in Rails, when adding ownership from a model to another model, you use the concept of belongs_to or references:
&#160; create_table :comments do &#124;t&#124;
&#160; &#160; t.belongs_to :user
&#160; &#160; t.references :post
&#160; end
Interestingly enough, these methods are only available during the initial table creation.  If you want to add a reference [...]]]></description>
			<content:encoded><![CDATA[<p>Normally when do a database migration in Rails, when adding ownership from a model to another model, you use the concept of belongs_to or references:</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; create_table <span style="color:#ff3333; font-weight:bold;">:comments</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; t.<span style="color:#9900CC;">belongs_to</span> <span style="color:#ff3333; font-weight:bold;">:user</span><br />
&nbsp; &nbsp; t.<span style="color:#9900CC;">references</span> <span style="color:#ff3333; font-weight:bold;">:post</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>Interestingly enough, these methods are only available during the initial table creation.  If you want to add a reference to a model that is created later, you have to do it the old fashioned way, by just adding a column:</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;add_column <span style="color:#ff3333; font-weight:bold;">:comments</span>, <span style="color:#ff3333; font-weight:bold;">:group_id</span>, :<span style="color:#CC0066; font-weight:bold;">integer</span></div></div>
<p>Doing it this way is clean, easy, and definitely meets the KISS principle.  But I do find it interesting that one can&#8217;t add an association later in the game.  Sometimes the Rails way is just KISS and adding the column by hand.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/QnuM_SsyN7gtRr5lnppfUZjkOfU/0/da"><img src="http://feedads.g.doubleclick.net/~a/QnuM_SsyN7gtRr5lnppfUZjkOfU/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/QnuM_SsyN7gtRr5lnppfUZjkOfU/1/da"><img src="http://feedads.g.doubleclick.net/~a/QnuM_SsyN7gtRr5lnppfUZjkOfU/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/lubow/PAyY/~4/2McyteZt0kc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2009/ruby/rails/migrations-without-belongs_to-or-references/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://eric.lubow.org/2009/ruby/rails/migrations-without-belongs_to-or-references/</feedburner:origLink></item>
		<item>
		<title>Parsing Ini Files With Ruby</title>
		<link>http://feedproxy.google.com/~r/lubow/PAyY/~3/ICl3RevwX2c/</link>
		<comments>http://eric.lubow.org/2009/ruby/parsing-ini-files-with-ruby/#comments</comments>
		<pubDate>Sun, 11 Oct 2009 18:00:55 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[gem]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=296</guid>
		<description><![CDATA[There doesn&#8217;t seem a lot of documentation or examples about parsing ini files in Ruby.  There are definitely shortcut ways to do it and I could always write my own methods, but why reinvent the wheel when there are gems?  So start out by simply installing the inifile gem.
beacon:~ elubow$ sudo gem install [...]]]></description>
			<content:encoded><![CDATA[<p>There doesn&#8217;t seem a lot of documentation or examples about parsing ini files in Ruby.  There are definitely shortcut ways to do it and I could always write my own methods, but why reinvent the wheel when there are gems?  So start out by simply installing the <strong>inifile</strong> gem.</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">beacon:~ elubow$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> gem <span style="color: #c20cb9; font-weight: bold;">install</span> inifile<br />
Successfully installed inifile-0.1.0<br />
1 gem installed<br />
Installing ri documentation <span style="color: #000000; font-weight: bold;">for</span> inifile-0.1.0...<br />
Installing RDoc documentation <span style="color: #000000; font-weight: bold;">for</span> inifile-0.1.0...</div></div>
<p>The code for the gem is available from <a href="http://www.github.com/">github</a> <a href="http://github.com/TwP/inifile">here</a>. Other inifile documentation is available <a href="http://codeforpeople.rubyforge.org/inifile/">here</a>.  The rest of the inifile documentation is a good reference but doesn&#8217;t contain any examples.</p>
<p>For some reason (which I don&#8217;t understand so please feel free to explain it in the comments if you know), you have to do more than just the standard <strong>require</strong> statement for this gem.  At the top of your Ruby code, add the lines below.  Make sure that you replace the directory location with your directory location.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span> <br />
$:.<span style="color:#9900CC;">unshift</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#996600;">'/usr/lib64/ruby/gems/1.8/gems/inifile-0.1.0/lib/'</span> <span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'inifile'</span></div></div>
<p>A short example of the ini file that we will be working with:</p>
<div class="codecolorer-container ini default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="ini codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>foo<span style="">&#93;</span></span><br />
<span style="color: #000099;">bar</span> <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;baz&quot;</span><br />
<span style="color: #000099;">dir</span> <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #933;">&quot;2009-10-05/&quot;</span><br />
<span style="color: #000099;">id</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 75</span></div></div>
<p>To get the <strong>id</strong> parameter of the ini file assuming you know its in the <strong>[foo]</strong>section, you can use the code below.  Notice the parameter section of the <em>new</em> object instantiator.  The reason for this is that ini files are pretty abstract can have a few variations on format.  Therefore you can specify the comment style and parameter definition style during object instantiation.  My ini files use the &#8216;=&#8217; to assign parameters</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; ini = IniFile.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span> options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:conf</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#ff3333; font-weight:bold;">:parameter</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'='</span> <span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; section = ini<span style="color:#006600; font-weight:bold;">&#91;</span>foo<span style="color:#006600; font-weight:bold;">&#93;</span><br />
&nbsp; id = section<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'id'</span><span style="color:#006600; font-weight:bold;">&#93;</span></div></div>
<p>Using the above code the <strong>id</strong> variable now contains the contents of the <strong>id</strong> parameter from the ini file.   </p>

<p><a href="http://feedads.g.doubleclick.net/~a/5oB4E8nFKLlVPG-bUir80W9wB5c/0/da"><img src="http://feedads.g.doubleclick.net/~a/5oB4E8nFKLlVPG-bUir80W9wB5c/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/5oB4E8nFKLlVPG-bUir80W9wB5c/1/da"><img src="http://feedads.g.doubleclick.net/~a/5oB4E8nFKLlVPG-bUir80W9wB5c/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/lubow/PAyY/~4/ICl3RevwX2c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2009/ruby/parsing-ini-files-with-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://eric.lubow.org/2009/ruby/parsing-ini-files-with-ruby/</feedburner:origLink></item>
		<item>
		<title>Tokyo Tyrant and Tokyo Cabinet</title>
		<link>http://feedproxy.google.com/~r/lubow/PAyY/~3/Z4kqyrAT6rQ/</link>
		<comments>http://eric.lubow.org/2009/databases/tokyo-tyrant-and-tokyo-cabinet/#comments</comments>
		<pubDate>Fri, 09 Oct 2009 14:00:38 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Tokyo Cabinet]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=278</guid>
		<description><![CDATA[Tokyo Tyrant and Tokyo Cabinet are the components for a database used by Mixi (basically a Japanese Facebook).  And for work, I got to play with these tools for some research.  Installing all this stuff along with the Perl APIs is incredibly easy.
Ultimately I am working on a comparison of Cassandra and Tokyo [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://1978th.net/tokyotyrant/">Tokyo Tyrant</a> and <a href="http://1978th.net/tokyocabinet/">Tokyo Cabinet</a> are the components for a database used by Mixi (basically a Japanese Facebook).  And for work, I got to play with these tools for some research.  Installing all this stuff along with the Perl APIs is incredibly easy.</p>
<p>Ultimately I am working on a comparison of <a href="http://incubator.apache.org/cassandra/">Cassandra</a> and <a href="http://1978th.net/">Tokyo Cabinet</a>, but I will get to more on <a href="http://incubator.apache.org/cassandra/">Cassandra</a> later.</p>
<p>Ideally the tests I am going to be doing are fairly simple. I am going to be loading a few million rows into a TCT database (which is a table database in TC terms) and then loading key, value pairs into the database.  The layout in a hash format is basically going to be as follows:</p>
<div class="codecolorer-container perl default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #ff0000;">&quot;user@example.com&quot;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span> &nbsp; <span style="color: #ff0000;">&quot;sendDates&quot;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span><span style="color: #ff0000;">&quot;2009-09-30&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #ff0000;">&quot;123456789&quot;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span> &nbsp;<span style="color: #ff0000;">&quot;2009-09-30&quot;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span><span style="color: #ff0000;">&quot;2287&quot;</span><span style="color: #009900;">&#125;</span> &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>I ran these tests in the following formats for INSERTing the data into the a table database and as serialized data in a hash database.  It is necessary to point out that the load on this machine is the normal load.  Therefore it cannot be a true benchmark.  Since the conditions are not optimal (but really, when are they ever), take the results with a grain of salt.  Also, there is some data munging going on during every iteration to grab the email addresses and other data.  All this is being done through the Perl API and Tokyo Tyrant.  The machine that this is running on is a Dual Dual Core 2.5GHz Intel Xeon processor with 16G of memory.</p>
<p>For the first round, a few things should be noted:</p>
<ul>
<li>The totals referenced below are email address counts add/modified in the db</li>
<li>I am only using 1 connection to the Tokyo Tyrant DB and it is currently setup to handle 8 threads</li>
<li>I didn&#8217;t do any memory adjustment on startup, so the default (which is marginal) is in use</li>
<li>I am only using the standard put operations, not <em>putcat</em>, <em>putkeep</em>, or <em>putnr</em> (which I will be using later)</li>
</ul>
<p>The results of the table database are as follows.  It is also worth noting the size of the table is around 410M on disk.</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">&#91;</span>elubow<span style="color: #000000; font-weight: bold;">@</span>db5 db<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ <span style="color: #000000; font-weight: bold;">time</span> .<span style="color: #000000; font-weight: bold;">/</span>tct_test.pl <span style="color: #660033;">-b</span> lists<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #660033;">-D</span> 2009-09-30 <span style="color: #660033;">-c</span> queue-mail.ini <br />
usa: <span style="color: #000000;">99</span>,<span style="color: #000000;">272</span><br />
top: <span style="color: #000000;">3</span>,<span style="color: #000000;">661</span>,<span style="color: #000000;">491</span><br />
Total: <span style="color: #000000;">3</span>,<span style="color: #000000;">760</span>,<span style="color: #000000;">763</span><br />
<br />
real &nbsp; &nbsp;291m53.204s<br />
user &nbsp; &nbsp;4m53.557s<br />
sys &nbsp; &nbsp; 2m35.604s<br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span>root<span style="color: #000000; font-weight: bold;">@</span>db5 tmp<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;"># ls -l</span><br />
<span style="color: #660033;">-rw-r--r--</span> <span style="color: #000000;">1</span> root root <span style="color: #000000;">410798800</span> Oct &nbsp;<span style="color: #000000;">6</span> <span style="color: #000000;">23</span>:<span style="color: #000000;">15</span> mailings.tct</div></div>
<p>The structure for the hash database (seeing as its only key value) is as follows:</p>
<div class="codecolorer-container perl default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; &nbsp; <span style="color: #ff0000;">&quot;user@example.com&quot;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">&quot;2009-09-30&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #ff0000;">&quot;123456789&quot;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">&quot;2009-09-30|2287&quot;</span><span style="color: #339933;">,</span></div></div>
<p>The results of loading the same data into a hash database are as follows. It is also worth noting the size of the table is around 360M on disk.  This is significantly smaller than the 410M of the table database containing the same style data.</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">&#91;</span>elubow<span style="color: #000000; font-weight: bold;">@</span>db5 db<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ <span style="color: #000000; font-weight: bold;">time</span> .<span style="color: #000000; font-weight: bold;">/</span>tch_test.pl <span style="color: #660033;">-b</span> lists<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #660033;">-D</span> 2009-09-30 <span style="color: #660033;">-c</span> queue-mail.ini <br />
usa: <span style="color: #000000;">99</span>,<span style="color: #000000;">272</span><br />
top: <span style="color: #000000;">3</span>,<span style="color: #000000;">661</span>,<span style="color: #000000;">491</span><br />
Total: <span style="color: #000000;">3</span>,<span style="color: #000000;">760</span>,<span style="color: #000000;">763</span><br />
<br />
real &nbsp; &nbsp;345m29.444s<br />
user &nbsp; &nbsp;2m23.338s<br />
sys &nbsp; &nbsp; 2m15.768s<br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span>root<span style="color: #000000; font-weight: bold;">@</span>db5 tmp<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;"># ls -l</span><br />
<span style="color: #660033;">-rw-r--r--</span> <span style="color: #000000;">1</span> root root <span style="color: #000000;">359468816</span> Oct &nbsp;<span style="color: #000000;">7</span> <span style="color: #000000;">17</span>:<span style="color: #000000;">50</span> mailings.tch</div></div>
<p></p>
<p>For the second round, I loaded a second days worth of data in to the database.  I used the same layouts as above with the following noteworthy items:</p>
<ul>
<li>I did a <em>get</em> first prior to the <em>put</em> to decide whether to use <em>put</em> or <em>putcat</em></li>
<li>The new data structure is now either &#8220;2009-09-30,2009-10-01&#8243; or &#8220;2009-09-30|1995,2009-10-01|1996&#8243;</li>
</ul>
<p>Results of the hash database test round 2:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">&#91;</span>elubow<span style="color: #000000; font-weight: bold;">@</span>db5 db<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ <span style="color: #000000; font-weight: bold;">time</span> .<span style="color: #000000; font-weight: bold;">/</span>tch_test.pl <span style="color: #660033;">-b</span> lists<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #660033;">-D</span> 2009-10-01 <span style="color: #660033;">-c</span> queue-mail.ini <br />
luxe: 936,911<br />
amex: 599,981<br />
mex: 39,700<br />
Total: 1,576,592<br />
<br />
real &nbsp; &nbsp;177m55.280s<br />
user &nbsp; &nbsp;1m53.289s<br />
sys &nbsp; &nbsp; 2m8.606s<br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span>elubow<span style="color: #000000; font-weight: bold;">@</span>db5 db<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ <span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #660033;">-l</span><br />
<span style="color: #660033;">-rw-r--r--</span> <span style="color: #000000;">1</span> root root <span style="color: #000000;">461176784</span> Oct &nbsp;<span style="color: #000000;">7</span> <span style="color: #000000;">23</span>:<span style="color: #000000;">44</span> mailings.tch</div></div>
<p>Results of the table database test round 2:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">&#91;</span>elubow<span style="color: #000000; font-weight: bold;">@</span>db5 db<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ <span style="color: #000000; font-weight: bold;">time</span> .<span style="color: #000000; font-weight: bold;">/</span>tct_test.pl <span style="color: #660033;">-b</span> lists<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #660033;">-D</span> 2009-10-01 <span style="color: #660033;">-c</span> queue-mail.ini<br />
luxe: 936,911<br />
amex: 599,981<br />
mex: 39,700<br />
Total: 1,576,592<br />
<br />
real &nbsp; &nbsp;412m19.007s<br />
user &nbsp; &nbsp;4m39.064s<br />
sys &nbsp; &nbsp; 2m22.343s<br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span>elubow<span style="color: #000000; font-weight: bold;">@</span>db5 db<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ <span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #660033;">-l</span><br />
<span style="color: #660033;">-rw-r--r--</span> <span style="color: #000000;">1</span> root root <span style="color: #000000;">512258816</span> Oct &nbsp;<span style="color: #000000;">8</span> <span style="color: #000000;">12</span>:<span style="color: #000000;">41</span> mailings.tct</div></div>
<p>When it comes down to the final implementation, I will likely be parallelizing the <em>put</em> in some form.  I would like to think that a database designed for this sort of thing works best in a concurrent environment (especially considering the default startup value is 8 threads).</p>
<p>It is obvious that when it comes to load times, that the hash database is much faster.  Now its time to run some queries and see how this stuff goes down.</p>
<p>So I ran some queries first against the table database.  I grabbed a new list of 3.6 million email addresses and iterated over the list, grabbed the record from the table database and counted how many dates (via array value counts) were entered for that email address.  I ran the script 4 times and results were as follows.  I typically throw out the first run since caching kicks in for the other runs.</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Run <span style="color: #000000;">1</span>: 10m35.689s<br />
Run <span style="color: #000000;">2</span>: 5m41.896s<br />
Run <span style="color: #000000;">3</span>: 5m44.505s<br />
Run <span style="color: #000000;">4</span>: 5m44.329s</div></div>
<p>Doing the same thing for the hash database, I got the following result set:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Run <span style="color: #000000;">1</span>: 7m54.292s<br />
Run <span style="color: #000000;">2</span>: 4m13.467s<br />
Run <span style="color: #000000;">3</span>: 3m59.302s<br />
Run <span style="color: #000000;">4</span>: 4m13.277s</div></div>
<p>I think the results speak for themselves.  A hash database is obviously faster (which is something most of us assumed from the beginning).  The rest of time comes form programmatic comparisons like date comparisons in specific slices of the array.  Load times can be sped up using concurrency, but given the requirements of the project, the <em>get</em>s have to be done in this sequential fashion.</p>
<p>Now its on to testing <a href="http://incubator.apache.org/cassandra/">Cassandra</a> in a similar fashion for comparison.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/fsYeS5q_8VpEYbHjbUujbprH48o/0/da"><img src="http://feedads.g.doubleclick.net/~a/fsYeS5q_8VpEYbHjbUujbprH48o/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/fsYeS5q_8VpEYbHjbUujbprH48o/1/da"><img src="http://feedads.g.doubleclick.net/~a/fsYeS5q_8VpEYbHjbUujbprH48o/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/lubow/PAyY/~4/Z4kqyrAT6rQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2009/databases/tokyo-tyrant-and-tokyo-cabinet/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://eric.lubow.org/2009/databases/tokyo-tyrant-and-tokyo-cabinet/</feedburner:origLink></item>
		<item>
		<title>Causing More Problems Than You Solve</title>
		<link>http://feedproxy.google.com/~r/lubow/PAyY/~3/T8Y2srBHdBg/</link>
		<comments>http://eric.lubow.org/2009/misc/causing-more-problems-than-you-solve/#comments</comments>
		<pubDate>Wed, 07 Oct 2009 18:00:58 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[planning]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=284</guid>
		<description><![CDATA[To start off, if you know me personally, then you know I recently (July 30, 2009) broke my leg skydiving.  If you&#8217;re interested, you can see this video on Youtube here. To make a long story short, I had surgery that night, they put a titanium rod in my thigh and I have been [...]]]></description>
			<content:encoded><![CDATA[<p>To start off, if you know me personally, then you know I recently (July 30, 2009) broke my leg skydiving.  If you&#8217;re interested, you can see this video on Youtube <a href="http://www.youtube.com/watch?v=E9KnVqVXiiI">here</a>. To make a long story short, I had surgery that night, they put a titanium rod in my thigh and I have been on crutches since.  I have only recently started learning to walk again (which I have no yet reached that point). This week my insurance decided that it was no longer necessary to send me to Physical Therapy (thanks Oxford).</p>
<p>Like any corporation, Oxford is in the business of making money and in this case, they are doing so by deciding not to pay for my PT.  In the long run, the lack of rehabilitation will likely leave me in a weakened state and generally more prone to injury once I go back to my skydiving, motorcycle riding, MMA, and BASE jumping ways.  If Oxford had said, let&#8217;s make sure he can walk and then we&#8217;ll cut him off, at least he&#8217;ll have a foundation and be less prone to injury; then they might be saving a bit of money on me in the long run.</p>
<p>So what does this sob story have to do with IT? A decision made now in order to save money can end up costing you more of time and money in the long run. And since time is money, sometimes a little bit of planning can go a long way.  Should you add the feature now because your biggest client wants it by Friday.  Well if you do that, then you might lose a few smaller clients along the way and the word of mouth may be more damaging than temporarily upsetting that large client.</p>
<p>Perhaps you set up Nagios and immediately turned on alerting without learning the thresholds that your machines typically sit at.  Then you get a whole set of alerts and you spend more time trying to sort through the real problem ones versus the ones that just have a slightly abnormal operating level then you would if you just looked at your machines thresholds to begin with.</p>
<p>There are a million examples that could be listed here.  The point is, before jumping into a decision, try to make sure that you&#8217;re not going to be paying for it in the long run.  A little planning can go a long way.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/HnNc0u38kUHbcy0RcP3Ga0AEad0/0/da"><img src="http://feedads.g.doubleclick.net/~a/HnNc0u38kUHbcy0RcP3Ga0AEad0/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/HnNc0u38kUHbcy0RcP3Ga0AEad0/1/da"><img src="http://feedads.g.doubleclick.net/~a/HnNc0u38kUHbcy0RcP3Ga0AEad0/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/lubow/PAyY/~4/T8Y2srBHdBg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2009/misc/causing-more-problems-than-you-solve/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://eric.lubow.org/2009/misc/causing-more-problems-than-you-solve/</feedburner:origLink></item>
	</channel>
</rss>
