<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Yaychris Blog</title>
    <description>One bad mutha-shut-yo-mouth</description>
    <link>http://yaychris.com/blog.html</link>
          <item>
        <title>Redis, Part 2: Lists</title>
        <description><![CDATA[<p>Welcome to Part 2 in my series of posts about <a href="http://code.google.com/p/redis/">Redis</a>, a key-value database and open source project created by <a href="http://antirez.com">Salvatore Sanfilippo</a>. In <a href="http://yaychris.com/blog/2009/11/redis-part-1.html">Part 1</a>, we discussed some basic Redis commands: getting and setting values, testing for key existence, and incrementing and decrementing values. Standard stuff in the world of key-value databases. This time, we&#8217;ll explore something more interesting: lists.</p>

<p>(If you haven&#8217;t read <a href="http://yaychris.com/blog/2009/11/redis-part-1.html">Part 1</a> yet, please do so before continuing.)</p>

<hr />

<p>A list is an ordered collection of values. Think of it like an array in your favorite programming language. You can insert values at the beginning (left) and end (right) of the list, retrieve single and ranges of elements, and delete elements.</p>

<p>To follow along with these examples, start the Redis server and then connect with telnet, just like we did in part 1.</p>

<h2>Inserting Elements</h2>

<p>Let&#8217;s create a new list:</p>

<pre><code>    % LPUSH vowels 1
    % a
    +OK
</code></pre>

<p>Inserting an element is called pushing. Because the key <code>vowels</code> doesn&#8217;t exist yet, a new list is created with a single value, <code>a</code>. Let&#8217;s add two more values to the list, this time at the end:</p>

<pre><code>    % RPUSH vowels 1
    % e
    +OK

    % RPUSH vowels 1
    % i
    +OK
</code></pre>

<p>We&#8217;ve pushed three values into our list; let&#8217;s make sure Redis agrees.</p>

<pre><code>    % LLEN vowels
    :3
</code></pre>

<p>Now that we have some values in the list, how do we get them back out?</p>

<h2>Retrieving Elements</h2>

<p>Redis has a few commands for retrieving list elements; which command to use depends on how many elements we wish to retrieve.</p>

<p>We can get a single value back with the <code>LINDEX</code> command. Lists in Redis are zero-based, so the first element of a list has index 0, the second has index 1, and so on. So far our list has values <code>a</code>, <code>e</code>, and <code>i</code>. Let&#8217;s get each by its index.</p>

<pre><code>    % LINDEX vowels 0
    $1
    a

    % LINDEX vowels 1
    $1
    e

    % LINDEX vowels 2
    $1
    i
</code></pre>

<p>If we try to get the value at an index that doesn&#8217;t exists, Redis returns a null value.</p>

<pre><code>    % LINDEX vowels 3
    $-1
</code></pre>

<p>Suppose we want the last (right-most) value in the list, but we don&#8217;t know how long it is. Using a negative index, we can get elements starting at the end of the list:</p>

<pre><code>    % LINDEX vowels -1
    $1
    i

    % LINDEX vowels -2
    $1
    e
</code></pre>

<p>We can retrieve more than one value using the <code>LRANGE</code> command, which takes three arguments: the key, the start index, and the end index. To get the first two elements in the list:</p>

<pre><code>    % LRANGE vowels 0 1
    *2
    $1
    a
    $1
    e
</code></pre>

<p>(The first line reads <code>*2</code>, which means two elements are being returned.)</p>

<p><code>LRANGE</code> accepts negative indices, just like <code>LINDEX</code>. Let&#8217;s get all the elements in the list:</p>

<pre><code>    % LRANGE vowels 0 -1
    *3
    $1
    a
    $1
    e
    $1
    i
</code></pre>

<p>By making both indices negative, we can get the last two values out of the list:</p>

<pre><code>    % LRANGE vowels -2 -1
    *2
    $1
    e
    $1
    i
</code></pre>

<h2>Deleting Elements</h2>

<p>Suppose we executed a few more commands and now <code>vowels</code> looks like this: <code>y, j, u, x, o, j, a, e, i, x, j, j</code>. Let&#8217;s clean it up by removing the extra elements.</p>

<p>First, let&#8217;s delete the <code>y</code> at index 0. One way is to use the <code>LPOP</code> command. <code>LPOP</code> removes and returns the first element of the list:</p>

<pre><code>    % LPOP vowels
    $1
    y
</code></pre>

<p>We can also <code>RPOP</code>, which does the same thing to the last element of the list.</p>

<p>Another option is to trim the list to a smaller version of itself. We can do this with the <code>LTRIM</code> command. <code>LTRIM</code> works exactly like <code>LRANGE</code> except instead of returning the range Redis overwrites the key with it:</p>

<pre><code>    % LTRIM vowels 1 -1
    +OK
</code></pre>

<p>This command sets <code>vowels</code> to be the range starting at index 1 and ending at the last element. <code>vowels</code> now contains these elements: <code>u, x, o, j, a, e, i, x, j, j</code>.</p>

<p>Let&#8217;s get rid of those <code>j</code>s using the <code>LREM</code> command. <code>LREM</code> takes three arguments: a key to operate on, the number of matching elements to remove, and the value to remove<sup id="fnr1"><a href="#fn1">1</a></sup>.</p>

<p>Let&#8217;s remove the first <code>j</code>:</p>

<pre><code>    % LREM vowels 1 1
    % j
    :1
</code></pre>

<p>The first <code>1</code> tells Redis to start searching at the first element and to remove one instance of <code>j</code>. (The second <code>1</code> is the size in bytes of the value for which to search.) Redis responds with <code>:1</code>, the number of elements removed.</p>

<p>Let&#8217;s remove two more <code>j</code>s, this time from the end of the list:</p>

<pre><code>    % LREM vowels -2 1
    % j
    :2
</code></pre>

<p>The <code>-2</code> tells Redis to remove two elements and, because of the negative sign, to search starting at the end of the list. Two elements have been removed, so Redis says <code>:2</code>.</p>

<p>Now our list is <code>u, x, o, a, e, i, x</code>. Let&#8217;s remove all of the <code>x</code>s in one go:</p>

<pre><code>    % LREM vowels 0 1
    % x
    :2
</code></pre>

<p>By sending <code>0</code> as the second argument we&#8217;re telling Redis to remove all <code>x</code> elements.</p>

<h2>Sorting</h2>

<p>We have a complete list of vowels&#8211;<code>u, o, a, e, i</code>&#8211;but they&#8217;re in the wrong order. Let&#8217;s get a sorted list of vowels:</p>

<pre><code>    % SORT vowels ALPHA
    *5
    $1
    a
    $1
    e
    $1
    i
    $1
    o
    $1
    u
</code></pre>

<p><code>SORT</code> is a powerful command with many options and we&#8217;ll cover it later in greater detail. For now, here are a couple more things you can do with <code>SORT</code>.</p>

<p>Sort in the opposite direction:</p>

<pre><code>    % SORT vowels ALPHA DESC
    *5
    $1
    u
    $1
    o
    $1
    i
    $1
    e
    $1
    a
</code></pre>

<p>Limit the returned list to 3 elements, starting at index 1:</p>

<pre><code>    % SORT vowels LIMIT 1 3 ALPHA
    *3
    $1
    e
    $1
    i
    $1
    o
</code></pre>

<hr />

<p>So far, we&#8217;ve only had a taste of why Redis is so exciting. Next time we&#8217;ll look at sets and things will really pick up.</p>

<ol class="footnotes">
    <li id="fn1">
        <p>Redis can&#8217;t remove an element by index. There will always be a delay between when a command is sent and executed&#8211;during that delay, the list could be modified by another client and the index would then reference the wrong element.</p>
    </li>
</ol>



]]></description>
        <pubDate>Thu, 03 Dec 2009 12:36:00 -0500</pubDate>
        <link>http://yaychris.com/blog/2009/12/redis-part-2.html</link>
      </item>
          <item>
        <title>Redis, Part 1: Intro, Setup, and Basic Commands</title>
        <description><![CDATA[<p>This is the first in a series of posts about <a href="http://code.google.com/p/redis/">Redis</a>, a key-value database and open source project created by <a href="http://antirez.com">Salvatore Sanfilippo</a>. Most web applications are built on a relational database, and the key-value database (if used at all) is a volatile cache. My goal is to show that Redis is a suitable replacement for a relational database and an exciting and powerful new technology on which to build web applications.</p>

<p>I&#8217;ll start with setup and basic commands; continue with lists, sets, and some fancier stuff like key expiration; and finish with a simple Ruby application that will demonstrate the covered topics.</p>

<p>Redis is the coolest bit of software I&#8217;ve seen in ages and I hope this series helps to spread the word and get more people to try it.</p>

<h2>What Is Redis?</h2>

<p>Redis is a key-value database. Unlike a relational database, which is comprised of tables containing columns of data definitions and rows of data, a key-value database stores values, each of which is referenced by a unique key. To get a value out of the database, we send the corresponding key. It&#8217;s a little like the hash, associative array, or dictionary data type in your favorite programming language.</p>

<p>Redis has several features that make it unique among key-value database projects:</p>

<ul>
<li>It stores strings, yes, but also lists and sets, so it&#8217;s flexible.</li>
<li>It loads the entire dataset into RAM, so it&#8217;s fast.</li>
<li>It writes the database to disk, so it&#8217;s persistent.</li>
<li>It supports master-slave replication, so it&#8217;s scalable.</li>
<li>It&#8217;s easy to run, so you aren&#8217;t endlessly futzing with mammoth config files</li>
<li>Maybe most important, it&#8217;s easy to use, so you spend less time working with the database and more time writing your application.</li>
</ul>


<p>I&#8217;ll cover each of these topics in greater depth as we go. Right now, let&#8217;s install it and start playing.</p>

<h2>Setup</h2>

<p>Redis is cake to build<sup id="fnr1"><a href="#fn1">1</a></sup>. Observe:</p>

<pre><code>    % curl -O http://redis.googlecode.com/files/redis-1.02.tar.gz
    % tar xzf redis-1.02.tar.gz
    % cd redis-1.02
    % make
</code></pre>

<p>The <code>redis-server</code> binary is in the current working directory; we can run it directly, copy to <code>/usr/local/bin</code>, or whatever.</p>

<p>To start Redis:</p>

<pre><code>    % redis-server
</code></pre>

<p>Redis is now available on localhost at port 6379. In a real application, we would interact with Redis via a client library for our language of choice. For now, we&#8217;ll just use telnet.</p>

<p>Open a new shell and run:</p>

<pre><code>    % telnet 127.0.0.1 6379
</code></pre>

<p>We&#8217;re now connected to Redis; let&#8217;s send it some commands.</p>

<h2>Basic Commands</h2>

<p>Here&#8217;s our first command (I will prefix commands with <code>%</code> but you won&#8217;t see an actual prompt):</p>

<pre><code>    % DBSIZE
    :0
</code></pre>

<p><code>DBSIZE</code> returns the number of keys in the database. This is a new database with no keys, so Redis says <code>:0</code>.</p>

<p>The database is empty, but let&#8217;s try to <code>GET</code> a value:</p>

<pre><code>    % GET hello
    $-1
</code></pre>

<p><code>GET</code> fetches the value at the provided key. The key <code>hello</code> doesn&#8217;t exist, so Redis says <code>$-1</code>, which is like <code>nil</code> or <code>null</code>. Let&#8217;s set a value for that key:</p>

<pre><code>    % SET hello 5
    % world
    +OK
</code></pre>

<p><code>SET</code> takes three parameters: the name of the key, the size of the value in bytes, and, after a newline, the value itself. Here, we <code>SET</code> the key <code>hello</code> to the <code>5</code>-byte value <code>world</code>, and Redis says <code>+OK</code>. Now if we <code>GET</code> again:</p>

<pre><code>    % GET hello
    $5
    world
</code></pre>

<p>We receive the value we just set, but with an extra line that reads <code>$5</code>. Just like with <code>SET</code>, the size of the value in bytes is returned first, then a newline, then the value.</p>

<p>We can ask Redis if a key exists:</p>

<pre><code>    % EXISTS bigkahuna
    :0

    % EXISTS hello
    :1
</code></pre>

<p>Here, <code>:0</code> and <code>:1</code> mean false and true, respectively.</p>

<p>Let&#8217;s delete the <code>hello</code> key:</p>

<pre><code>    % DEL hello
    :1
</code></pre>

<p><code>DEL</code> deletes the value stored at the key <code>hello</code>. The command succeeds and Redis says <code>:1</code>, the number of records deleted. We can delete multiple keys by separating them with a space.</p>

<p>Say we want to set the value of a key only if that key doesn&#8217;t exist. Enter <code>SETNX</code>:</p>

<pre><code>    % SETNX bigkahuna 22
    % that is a tasty burger
    :1

    % GET bigkahuna
    $22
    that's a tasty burger

    % SETNX bigkahuna 4
    % d'oh
    :0

    % GET bigkahuna
    $22
    that's a tasty burger
</code></pre>

<p>The second <code>SETNX</code> fails because the key <code>bigkahuna</code>, having been created by the first <code>SETNX</code>, now exists.</p>

<p>Let&#8217;s create a few more keys: <code>english</code>, <code>englash</code>, and <code>englosh</code>. Set the value to whatever you want, remembering to enter the number of bytes and a newline first, then the value.</p>

<p>Redis returns data only if we feed it a valid key&#8211;it&#8217;s impossible to search for some value and get back its key. Suppose we don&#8217;t know what keys are in the database. How do we figure it out?</p>

<p>The <code>KEYS</code> command searches all the keys for the provided pattern. Let&#8217;s get a list of every key in the database:</p>

<pre><code>    % KEYS *
    $33
    englosh englash english bigkahuna
</code></pre>

<p>The pattern can include globs:</p>

<pre><code>    % KEYS *a*
    $17
    englash bigkahuna

    % KEYS engl?sh
    $23
    englosh englash english

    % KEYS engl[ia]sh
    $15
    englash english
</code></pre>

<p>Finally, we can purge all of the keys from the database:</p>

<pre><code>    % FLUSHDB
    +OK

    % DBSIZE
    :0
</code></pre>

<h2>Increment &amp; Decrement</h2>

<p>Redis lets us increment and decrement our values. First, let&#8217;s create a counter and set it to 1:</p>

<pre><code>    % SET counter 1
    % 1
    +OK
</code></pre>

<p>To increment:</p>

<pre><code>    % INCR counter
    :2
</code></pre>

<p>To decrement:</p>

<pre><code>    % DECR counter
    :1
</code></pre>

<p>Nothing to it, right? We can also increment and decrement by values other than one:</p>

<pre><code>    % INCRBY counter 5
    :6

    % DECRBY counter 6
    :0
</code></pre>

<p>Why do the increment and decrement commands exist? Say we&#8217;re using Redis to track the pageviews for a web site. Every URL maps to a key whose value is a counter. When a user visits a URL, we increment the counter. Imagine two visitors, <code>v1</code> and <code>v2</code>, visit the same URL, <code>/about</code>, at the same time. Here&#8217;s how it might play out in pseudocode, using only the <code>GET</code> and <code>SET</code> commands:</p>

<pre><code>    redis.get("/about") == 5      # 5 visits so far
    v1 = redis.get("/about")      # visitor 1 grabs the count
    v2 = redis.get("/about")      # visitor 2 grabs the count
    redis.set("/about", v1 + 1)   # visitor 1 sets the count + 1
    redis.set("/about", v2 + 1)   # visitor 2 sets the count + 1
    redis.get("/about") == 6      # wha?? should be 7
</code></pre>

<p>The problem is clear: <code>v2</code> changed the counter after <code>v1</code> retrieved the value but before setting the new one. The increment and decrement commands prevent this problem because they&#8217;re atomic: reading the value and changing it occur in one motion and can&#8217;t be interrupted.</p>

<hr />

<p>We can close both Redis and our telnet session by sending the <code>SHUTDOWN</code> command:</p>

<pre><code>    % SHUTDOWN
    Connection closed by foreign host.
</code></pre>

<p>And that&#8217;s it for part 1. Already, we know enough commands to build a real application, but Redis has much more to offer&#8211;next time, we&#8217;ll explore lists.</p>

<ol class="footnotes">
    <li id="fn1">
        Mac OS X users must install the <a href="http://developer.apple.com">Developer Tools</a>. Windows users should get along just fine using <a href="http://www.cygwin.com">Cygwin</a>. Linux/UNIX users shouldn&#8217;t need my help. <a href="#fnr1" title="Jump back to footnote 1 in the text.">&#8617;</a>
    </li>
</ol>



]]></description>
        <pubDate>Tue, 10 Nov 2009 12:30:00 -0500</pubDate>
        <link>http://yaychris.com/blog/2009/11/redis-part-1.html</link>
      </item>
          <item>
        <title>Switching From Task Management to Time Management</title>
        <description><![CDATA[<p>
  Here&rsquo;s how I used to work:
</p>

<ol>
  <li>Create tasks in a task manager.</li>
  <li>Meticulously sort them by project and priority.</li>
  <li>Select some of them as today&rsquo;s tasks.</li>
</ol>

<p>
  There&rsquo;s a massive industry built around this method, and for good reason: it sounds nice and makes sense. Define your tasks, then do them. Write a blog article, fix the toilet, buy groceries, code the products page.
</p>

<p>
  But I never get anything done this way. Tasks seem easy when I read them, so I schedule too many at a time. After work, only a handful are checked off, sometimes none. I feel unproductive and lousy :(
</p>

<p>
  The thing about tasks is they&rsquo;re reminders, abstractions that communicate what to do, not how or how long. I write down &ldquo;code the product pages&rdquo; so I don&rsquo;t forget to do it. I may need to do twelve other things to code the page, but I don&rsquo;t write those down because they tell me how to do it, and I already know that. If I don&rsquo;t know how to do something, I probably shouldn&rsquo;t be doing it in the first place. I just need a little reminder. 
</p>

<p>
  Task-based schedules fail precisely because they&rsquo;re abstractions&mdash;they represent a large jobs that requires significant and uncertain effort. With this kind of schedule, the task is the basic unit of work. Productivity is determined by the number of completed tasks. I might estimate three hours to code the products page, but after starting I discover an issue that balloons the time to seven hours. My schedule is blown, I check off one task instead of however-many-scheduled, and I feel bad, despite working those extra for hours on something productive and necessary.
</p>

<p>
  The reader who loves his task manager is shouting that I&rsquo;m doing it wrong: my tasks are too big and I should break them down into sub-tasks. Kay. To code the products page, I must generate the model and controller, write tests, code the views, test in several browsers. Aren&rsquo;t those instructions? I don&rsquo;t need instructions because I know how to do the damn thing. Tasks are reminders, remember? Breaking down the original task only creates extra work and more to manage. Plus it does nothing to address the unexpected work which caused the extra time.
</p>

<p>
  The real solution is to stop scheduling tasks and start scheduling time. Make time the basic unit of work. Seconds, minutes, hours, whatever. Instead of saying &ldquo;what tasks can I complete today,&rdquo; say &ldquo;what can I get done in 60 minutes?&rdquo;
</p>

<p>
  Here&rsquo;s how I work now:
</p>

<ol>
  <li>Commit to working a fixed block of time, usually two or three hours.</li>
  <li>Set a timer and keep it visible on the screen.</li>
  <li>Work until the timer runs out, then stop.</li>
</ol>

<p>
  The only goal is to work for a set amount of time. I usually do two or three of these sessions per day, and as long as I spend the entire time working, I&rsquo;ve succeeded. Tasks are no longer metrics for success and productivity, they&rsquo;re back to being reminders. If I finish a task before the timer is done, then I say &ldquo;yay!&rdquo; and start the next one. More important, if I don&rsquo;t finish a task when the timer ends, no biggie, I feel good anyway because I met my goal. Bonus: no matter how frustrating my work is, I can look at the timer tick-tocking to zero and know that soon I can do something else, and the harder I work the faster the time will go.
</p>

<p>
  The result is I get far more done than I ever did by managing tasks. Because I don&rsquo;t define my tasks upfront, I can reflect on all the little things I finished instead of feeling bad about the big things still incomplete. That&rsquo;s a big morale boost and it energizes me to dive in to the next session, something I rarely experienced with my task-based workflow.
</p>
]]></description>
        <pubDate>Mon, 12 Oct 2009 15:30:00 -0400</pubDate>
        <link>http://yaychris.com/blog/2009/10/time-management.html</link>
      </item>
      </channel>
</rss>