<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Floorplanner Tech Blog</title>
	<atom:link href="http://techblog.floorplanner.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://techblog.floorplanner.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Thu, 19 Nov 2009 04:00:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Request-log-analyzer 1.5.0</title>
		<link>http://techblog.floorplanner.com/2009/11/18/request-log-analyzer-1-5-0/</link>
		<comments>http://techblog.floorplanner.com/2009/11/18/request-log-analyzer-1-5-0/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 17:51:42 +0000</pubDate>
		<dc:creator>Willem van Bergen</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[request-log-analyzer]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[slow query log]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=801</guid>
		<description><![CDATA[Bart and I just released request-log-analyzer version 1.5.0. New features include:

MySQL slow query log format support to analyze what queries are slowing down your database.
Format autodetection: with all those supported file formats, remembering the right --format parameter gets tricky. With format autodetection, this usually is not needed anymore!

As always, run the following command to install [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F11%2F18%2Frequest-log-analyzer-1-5-0%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F11%2F18%2Frequest-log-analyzer-1-5-0%2F" height="61" width="51" /></a></div><p>Bart and I just released <a href="http://github.com/wvanbergen/request-log-analyzer">request-log-analyzer</a> version 1.5.0. New features include:</p>
<ul>
<li><a href="http://wiki.github.com/wvanbergen/request-log-analyzer/mysql-slow-query-log">MySQL slow query log</a> format support to analyze what queries are slowing down your database.</li>
<li><strong>Format autodetection:</strong> with all those supported file formats, remembering the right <code style="white-space: nowrap">--format</code> parameter gets tricky. With format autodetection, this usually is not needed anymore!</li>
</ul>
<p>As always, run the following command to install or upgrade to the latest version:</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family: Monaco,monospace;">$ gem install request-log-analyzer</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/11/18/request-log-analyzer-1-5-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Case-insensitive validates_uniqueness_of slowness</title>
		<link>http://techblog.floorplanner.com/2009/11/17/case-insensitive-validates_uniqueness_of-slowness/</link>
		<comments>http://techblog.floorplanner.com/2009/11/17/case-insensitive-validates_uniqueness_of-slowness/#comments</comments>
		<pubDate>Tue, 17 Nov 2009 14:01:02 +0000</pubDate>
		<dc:creator>Willem van Bergen</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[case insensitive]]></category>
		<category><![CDATA[index]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[validates_uniqueness_of]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=787</guid>
		<description><![CDATA[Watch out when using validates_uniqueness_of :field, :case_sensitive => false. Rails transforms this in a query that cannot be supported by an index, which will really slow validation down if the underlying table grows larger.
For example, we use validates_uniqueness_of to check for duplicate e-mail addresses. Because email addresses are case-insensitive, adding :case_sensitive => false seems like [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F11%2F17%2Fcase-insensitive-validates_uniqueness_of-slowness%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F11%2F17%2Fcase-insensitive-validates_uniqueness_of-slowness%2F" height="61" width="51" /></a></div><p>Watch out when using <code>validates_uniqueness_of :field, :case_sensitive => false</code>. Rails transforms this in a query that cannot be supported by an index, which will really slow validation down if the underlying table grows larger.</p>
<p>For example, we use <code>validates_uniqueness_of</code> to check for duplicate e-mail addresses. Because email addresses are case-insensitive, adding <code>:case_sensitive => false</code> seems like a natural choice. However, this results in the following queries:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family: Monaco,monospace;"><span style="color: #808080; font-style: italic;"># For a new User instance:</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> users 
 <span style="color: #993333; font-weight: bold;">WHERE</span> LOWER<span style="color: #66cc66;">&#40;</span>users<span style="color: #66cc66;">.</span>email<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">BINARY</span> <span style="color: #ff0000;">'user@example.com'</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># For an existing User instance:</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> users 
 <span style="color: #993333; font-weight: bold;">WHERE</span> LOWER<span style="color: #66cc66;">&#40;</span>users<span style="color: #66cc66;">.</span>email<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">BINARY</span> <span style="color: #ff0000;">'user@example.com'</span> 
   <span style="color: #993333; font-weight: bold;">AND</span> users<span style="color: #66cc66;">.</span>id <span style="color: #66cc66;">&lt;&gt;</span> <span style="color: #cc66cc;">42</span></pre></div></div>

<p>This query cannot be optimized by a (unique) index on the email field and thus has to scan the full table. As our users table grew larger, these queries started to show up in our slow query log. </p>
<p>However, MySQL uses case-insensitive comparison by default. (To be exact, case-sensitiveness depends on the current collation, which can vary. Rails generates the weird query to make sure the check works, regardless of the current collation.) The conversion to lowercase therefore is not necessary for a uniqueness check (as long as the field has a case-insensitive collation like <code>utf8_general_ci</code>). I decided to write my own validation method that issues a query that can be optimized by a query.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;">  <span style="color:#008000; font-style:italic;"># Alternative for validates_uniqueness_of :email, :case_sensitive =&gt; false</span>
  validate <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>user<span style="color:#006600; font-weight:bold;">|</span>
    conditions = <span style="color:#996600;">&quot;users.email = :email&quot;</span>
    conditions <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot; AND users.id != :id&quot;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> user.<span style="color:#9900CC;">new_record</span>?
    conditions = <span style="color:#006600; font-weight:bold;">&#91;</span>conditions, <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:email</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> user.<span style="color:#9900CC;">email</span>, <span style="color:#ff3333; font-weight:bold;">:id</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> user.<span style="color:#9900CC;">id</span> <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> User.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:first</span>, <span style="color:#ff3333; font-weight:bold;">:select</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:id</span>, <span style="color:#ff3333; font-weight:bold;">:conditions</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> conditions<span style="color:#006600; font-weight:bold;">&#41;</span>
      user.<span style="color:#9900CC;">errors</span>.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:email</span>, <span style="color:#996600;">'Already in use'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>There is <a href="https://rails.lighthouseapp.com/projects/8994/tickets/2503-validates_uniqueness_of-is-horribly-inefficient-in-mysql">a ticket for this issue in Rails&#8217;s Lighthouse</a>, but as of yet this issue is unresolved. For now, this solution works to keep our slow query log nice and quiet!</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/11/17/case-insensitive-validates_uniqueness_of-slowness/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Database replication in 5 easy steps</title>
		<link>http://techblog.floorplanner.com/2009/11/09/database-replication-in-5-easy-steps/</link>
		<comments>http://techblog.floorplanner.com/2009/11/09/database-replication-in-5-easy-steps/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 13:34:00 +0000</pubDate>
		<dc:creator>Gert-Jan</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[database replication mysql]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=753</guid>
		<description><![CDATA[Running an online service like Floorplanner is not without risks. There are a lot of things that can go wrong. One of them is downtime of your service due to a crashing system. It doesn&#8217;t have to happen of course, but when it does, it can have some nasty consequences. A good way to reduce [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F11%2F09%2Fdatabase-replication-in-5-easy-steps%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F11%2F09%2Fdatabase-replication-in-5-easy-steps%2F" height="61" width="51" /></a></div><p>Running an online service like <a href="http://floorplanner.com">Floorplanner</a> is not without risks. There are a lot of things that can go wrong. One of them is downtime of your service due to a crashing system. It doesn&#8217;t have to happen of course, but when it does, it can have some nasty consequences. A good way to reduce the risk of a crashing system is to set up a redundant system.</p>
<p>In short, a redundant system is an exact copy of your main system. When your main system goes down (for whatever reason), the redundant system can take over. One of the most important parts of any online service is the database. A way to maintain an exact copy of your database is setting up database replication. This post gives you the basics on how to set up database replication using a MySQL database.</p>
<p>Database replication isn&#8217;t probably something you&#8217;d setup right from the start. This means that you have to work with a running system when you decide to do so. From past experience we know that it&#8217;s not a good idea to replicate your database to the same machine, let alone to the same disk. To make this work, you need a separate machine with MySQL installed. This is your slave machine and database.</p>
<p>Let&#8217;s get down to business. These are the steps for setting up database replication:</p>
<ol>
<li>Enable binary logging on master database</li>
<li>Create a backup of master database</li>
<li>Transfer backup to slave machine</li>
<li>Import backup to slave database</li>
<li>Start slave database</li>
</ol>
<h3>1. Enable binary logging on master database</h3>
<blockquote><p><em>The binary log contains all statements that update data [..]. Statements are stored in the form of “events” that describe the modifications. The binary log also contains information about how long each statement took that updated data.</em></p></blockquote>
<p>Every write action that&#8217;s performed on your database, like an insert or an update, is stored in these binary logs (bin logs). The master dumps all actions in these logs and the slave database can read them  and perform the same actions. This way your master and slave databases will always have the same data.</p>
<p>To enable binary logging you have to create a config file, for example master.cnf. An important thing here is the server-id, which is needed for replication to work. Then there is log-bin which specifies base name of binary logs, and finally binlog-do-db, which specifies which databases should be bin logged.</p>

<div class="wp_syntax"><div class="code"><pre class="cnf" style="font-family: Monaco,monospace;">[mysqld]
datadir=/home/yourname/mysql/myisam/data
basedir=/usr/local/mysql
port=3306
server-id=1
log-bin=mysql-bin
binlog-do-db=my_fat_db1
binlog-do-db=ma_other_fat_db</pre></div></div>

<p>Then start (or restart) the master database using the config file:</p>

<div class="wp_syntax"><div class="code"><pre class="cnf" style="font-family: Monaco,monospace;">~ $ mysqld --defaults-file=master.cnf&amp;amp;</pre></div></div>

<p>The slave database needs a userid/password in order to access the master machine. It&#8217;s best practice create a dedicated user with just the required privileges. This can be done with the following SQL statement.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family: Monaco,monospace;"><span style="color: #993333; font-weight: bold;">GRANT</span> replication slave <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #66cc66;">*.*</span> <span style="color: #993333; font-weight: bold;">TO</span> <span style="color: #ff0000;">'repl'</span>@<span style="color: #ff0000;">'slave-ip-here'</span></pre></div></div>

<h3>2. Create a backup of master database</h3>
<p>The next step it to create a backup of your master database. The type of your database is very important for this action. If you use MyISAM, you need to schedule some downtime to dump your database. Otherwise the dumped data isn&#8217;t consistent and therefor useless. <span style="background-color:#FFE789">With InnoDB it&#8217;s possible to dump a consistent backup of your database while keeping it up and running</span>. We stumbled on this feature by accident, but we haven&#8217;t been able to in the official documentation.</p>
<p>MyISAM</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family: Monaco,monospace;">~ $ mysqldump --lock-all-tables</pre></div></div>

<p>InnoDB</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family: Monaco,monospace;">~ $ mysqldump --single-transaction</pre></div></div>

<h3>3. Transfer backup to slave machine</h3>
<p>Now that the backup is created on the master machine, it needs to be transferred to the slave machine.</p>
<h3>4. Import backup to slave database</h3>
<p>Once the backup is present on the slave machine, it can be imported into the slave database:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family: Monaco,monospace;">~ $ mysql &amp;lt; filename</pre></div></div>

<h3>5. Start slave database</h3>
<p>The last step is to tell the database that it&#8217;s a slave database. First we have to give it an server id. We use a config file for this, slave.cnf:</p>

<div class="wp_syntax"><div class="code"><pre class="cnf" style="font-family: Monaco,monospace;">[mysqld]
datadir=/home/yourname/mysql/myisam/data
basedir=/usr/local/mysql
port=3306
server-id=2
replicate-do-db=my_fat_db1
replicate-do-db=my_other_fat_db</pre></div></div>

<p>Then we start the database with this config file:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family: Monaco,monospace;">~ $ mysqld --defaults-file=slave.cnf&amp;amp;</pre></div></div>

<p>and we issue the following SQL statement:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family: Monaco,monospace;"><span style="color: #993333; font-weight: bold;">CHANGE</span> MASTER <span style="color: #993333; font-weight: bold;">TO</span>
<span style="color: #66cc66;">-</span>&amp;gt; MASTER_HOST<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'master-ip-here'</span><span style="color: #66cc66;">,</span>
<span style="color: #66cc66;">-</span>&amp;gt; MASTER_PORT<span style="color: #66cc66;">=</span><span style="color: #cc66cc;">3306</span><span style="color: #66cc66;">,</span>
<span style="color: #66cc66;">-</span>&amp;gt; MASTER_USER<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'repl'</span><span style="color: #66cc66;">,</span>
<span style="color: #66cc66;">-</span>&amp;gt; MASTER_PASSWORD<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'repl'</span><span style="color: #66cc66;">,</span>
<span style="color: #66cc66;">-</span>&amp;gt; MASTER_LOG_FILE<span style="color: #66cc66;">=</span><span style="color: #ff0000;">'bin-log-filename-here'</span><span style="color: #66cc66;">,</span>
<span style="color: #66cc66;">-</span>&amp;gt; MASTER_LOG_POS<span style="color: #66cc66;">=</span><span style="color: #cc66cc;">4</span>;</pre></div></div>

<p>It&#8217;s hard to predict the MASTER_LOG_POS. You can find this number by issuing the following SQL statement on the <strong>master</strong> database:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family: Monaco,monospace;"><span style="color: #993333; font-weight: bold;">SHOW</span> MASTER <span style="color: #993333; font-weight: bold;">STATUS</span>\G;</pre></div></div>

<p>Once the slave is configured correctly it will get the bin logs from the master machine, parse them and execute each action. It takes some time to have an exact copy of the master database, depending on the size and number of bin logs. To get an idea about the delay, issue the following query:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family: Monaco,monospace;"><span style="color: #993333; font-weight: bold;">SHOW</span> SLAVE <span style="color: #993333; font-weight: bold;">STATUS</span>\G;</pre></div></div>

<p>With this post we hope to contribute to a less riskier world and more peaceful state of mind for the sys admins out there <img src='http://techblog.floorplanner.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' />  </p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/11/09/database-replication-in-5-easy-steps/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Evaluating static ParseTree subtrees</title>
		<link>http://techblog.floorplanner.com/2009/10/03/evaluating-static-parsetree-subtrees/</link>
		<comments>http://techblog.floorplanner.com/2009/10/03/evaluating-static-parsetree-subtrees/#comments</comments>
		<pubDate>Sat, 03 Oct 2009 12:34:21 +0000</pubDate>
		<dc:creator>Willem van Bergen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[evaluate]]></category>
		<category><![CDATA[ParseTree]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[syntax tree]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=734</guid>
		<description><![CDATA[ParseTree is a very useful to gem that can translate Ruby code into a syntax tree. I recently needed to evaluate a static part of this tree to return the original hash it represented. I wrote a simple method called ParseTree.eval_static_tree for this purpose. 
The method can only evaluate trees that have a static value [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F10%2F03%2Fevaluating-static-parsetree-subtrees%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F10%2F03%2Fevaluating-static-parsetree-subtrees%2F" height="61" width="51" /></a></div><p><a href="http://parsetree.rubyforge.org/">ParseTree</a> is a very useful to gem that can translate Ruby code into a syntax tree. I recently needed to evaluate a static part of this tree to return the original hash it represented. I wrote a simple method called <code>ParseTree.eval_static_tree</code> for this purpose. </p>
<p>The method can only evaluate trees that have a static value composed of hashes, arrays, strings, symbols and numerics. You can however pass a block to the function that will be called for every dynamic part the method encounters (function calls, etc.) </p>
<p><script src="http://gist.github.com/200607.js"></script></p>
<p>A quick sample on how to use it:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;">code = <span style="color:#996600;">'{ :static_array =&gt; [&quot;str&quot;, 123, 4.5], :dynamic =&gt; method_call }'</span>
tree = ParseTree.<span style="color:#9900CC;">translate</span><span style="color:#006600; font-weight:bold;">&#40;</span>code<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#008000; font-style:italic;"># =&gt; [:hash, [:lit, :static_array], [:array, [:str, &quot;str&quot;], </span>
<span style="color:#008000; font-style:italic;">#       [:lit, 123], [:lit, 4.5]], [:lit, :dynamic], [:vcall, :method_call]]</span>
&nbsp;
ParseTree.<span style="color:#9900CC;">eval_static_tree</span><span style="color:#006600; font-weight:bold;">&#40;</span>tree<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#008000; font-style:italic;"># =&gt; RuntimeError: tree is not static: :vcall ...</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># Pass a block to simply return nil for every dynamic item in the tree.</span>
ParseTree.<span style="color:#9900CC;">eval_static_tree</span><span style="color:#006600; font-weight:bold;">&#40;</span>tree<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>dynamic_subtree<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#0000FF; font-weight:bold;">nil</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#008000; font-style:italic;"># =&gt; {:dynamic=&gt;nil, :static_array=&gt;[&quot;str&quot;, 123, 4.5]}</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/10/03/evaluating-static-parsetree-subtrees/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Request-log-analyzer 1.4.0</title>
		<link>http://techblog.floorplanner.com/2009/09/30/request-log-analyzer-1-4-0/</link>
		<comments>http://techblog.floorplanner.com/2009/09/30/request-log-analyzer-1-4-0/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 09:40:04 +0000</pubDate>
		<dc:creator>Willem van Bergen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Amazon S3]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[log analysis]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[profiling]]></category>
		<category><![CDATA[Rack CommonLogger]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[request-log-analyzer]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=729</guid>
		<description><![CDATA[Bart and I have been working a lot on request-log-analyzer lately, our tool to produce performance reports for web applications based on their log files. Today, we released version 1.4.0, which boasts many new features since I last blogged about a release. The changelog contains all changes we have implemented recently with some additional information, [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F09%2F30%2Frequest-log-analyzer-1-4-0%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F09%2F30%2Frequest-log-analyzer-1-4-0%2F" height="61" width="51" /></a></div><p>Bart and I have been working a lot on <a href="http://github.com/wvanbergen/request-log-analyzer">request-log-analyzer</a> lately, our tool to produce performance reports for web applications based on their log files. Today, we released version 1.4.0, which boasts many new features since I last blogged about a release. The <a href="http://wiki.github.com/wvanbergen/request-log-analyzer/changelog">changelog</a> contains all changes we have implemented recently with some additional information, but these are the highlights:</p>
<ul>
<li><strong>New and improved log formats:</strong> r-l-a can now handle <a href="http://wiki.github.com/wvanbergen/request-log-analyzer/apache-access-log">Apache access logs</a>, <a href="http://wiki.github.com/wvanbergen/request-log-analyzer/apache-access-log#rack">Rack CommonLogger logs</a> and <a href="http://wiki.github.com/wvanbergen/request-log-analyzer/amazon-s3-access-log">Amazon S3 access logs</a>. Moreover, the Rails format has been restructured to offer <a href="http://wiki.github.com/wvanbergen/request-log-analyzer/rails-request-log">more flexibility</a>.</li>
<li><strong>Improved database support: </strong>the database supports other databases than SQLite3 as well, and r-l-a can append information to an existing database instead of overwriting it. Moreover, a console tool similar to Rails&#8217;s script/console is bundled to inspect the database and run queries on it easily.</li>
<li><strong>Added standard deviation to reports: </strong>the standard deviation measure has been added to duration and traffic reports to get some feel of the variation in values besides the mean.</li>
<li><strong>E-mailing reports:</strong> r-l-a can email the performance report to a given e-mail address. This can be useful when running r-l-a in a cron job.</li>
<li><strong>Compressed log support:</strong> r-l-a will decompress compressed logs automatically.</li>
<li><strong>Speed improvements:</strong> we have profiled <a href="http://techblog.floorplanner.com/2009/09/27/performance-tweaking-of-ruby-algorithms/">request-log-analyzer itself</a> and significantly improved its performance.</li>
<li><strong>API:</strong> we created a basic API so it is possible to use the r-l-a engine as a library as well.</li>
<li><strong>Monitoring integration:</strong> integrate performance information into your <a href="http://github.com/barttenbrinke/munin-plugins-rails/">Munin dashboard</a> or your <a href="http://wiki.github.com/wvanbergen/request-log-analyzer/scout">Scout account</a>.</li>
</ul>
<p>As always, use <code>sudo gem install request-log-analyzer</code> to install or upgrade.</p>
<h3>Ruby en Rails 2009 conference</h3>
<p>Bart and I will be presenting request-log-analyzer and performance tuning of Rails applications in general at the <a href="http://2009.rubyenrails.nl">Ruby en Rails</a> conference in Amsterdam, October 30-31 2009. We hope to see you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/09/30/request-log-analyzer-1-4-0/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Adyen payment services for Rails</title>
		<link>http://techblog.floorplanner.com/2009/09/27/adyen-payment-services-for-rails/</link>
		<comments>http://techblog.floorplanner.com/2009/09/27/adyen-payment-services-for-rails/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 18:27:23 +0000</pubDate>
		<dc:creator>Willem van Bergen</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[adyen]]></category>
		<category><![CDATA[forms]]></category>
		<category><![CDATA[payments]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[signature calculation]]></category>
		<category><![CDATA[soap]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=726</guid>
		<description><![CDATA[Michel and I have been playing around with integrating Adyen payment services in Rails applications. We have assembled some of the pieces of code we have written, combined them, written specs for them and released the result as a gem. The package is also included on the Adyen support site.
Currently, the gem provides the following:

Simple [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F09%2F27%2Fadyen-payment-services-for-rails%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F09%2F27%2Fadyen-payment-services-for-rails%2F" height="61" width="51" /></a></div><p>Michel and I have been playing around with integrating <a href="http://www.adyen.com/">Adyen payment services</a> in Rails applications. We have assembled some of the pieces of code we have written, combined them, written specs for them and <a href="http://github.com/wvanbergen/adyen">released the result as a gem</a>. The package is also included on the <a href="https://support.adyen.com/index.php?_m=downloads&amp;_a=viewdownload&amp;downloaditemid=43">Adyen support site</a>.</p>
<p>Currently, the gem provides the following:</p>
<ul>
<li>Simple configuration and setup.</li>
<li>Uses Adyen&#8217;s test or production environment based on your Rails environment.</li>
<li>Generating hidden form fields for redirecting to Adyen for a payment.</li>
<li>Calculating the signature to sign these redirects.</li>
<li>Checking Adyen&#8217;s signature when the user gets redirected back.</li>
<li>Matchers to easily test your payment forms using RSpec.</li>
<li>Receiving and storing notifications from Adyen.</li>
<li>Calling the Adyen SOAP services (requires the <a href="http://github.com/troelskn/handsoap">Handsoap gem</a>).</li>
</ul>
<p>Currently, not all SOAP services are implemented (because we didn&#8217;t need them all). It should be quite easy to implement them as well based on the other services that are implemented already. Don&#8217;t hesitate to submit patches!</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/09/27/adyen-payment-services-for-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Performance tweaking of Ruby algorithms</title>
		<link>http://techblog.floorplanner.com/2009/09/27/performance-tweaking-of-ruby-algorithms/</link>
		<comments>http://techblog.floorplanner.com/2009/09/27/performance-tweaking-of-ruby-algorithms/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 06:02:42 +0000</pubDate>
		<dc:creator>Willem van Bergen</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[analysis]]></category>
		<category><![CDATA[blocks]]></category>
		<category><![CDATA[parallelization]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[profiling]]></category>
		<category><![CDATA[regular expressions]]></category>
		<category><![CDATA[request-log-analyzer]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby-prof]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=716</guid>
		<description><![CDATA[I have been working on request-log-analyzer quite a lot recently. One of the things I focused on was improving the parsing performance: because it parses log files that often are very big, processing times tend to be long. So all savings are very welcome.
Improving the performance of a command line application that does a lot [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F09%2F27%2Fperformance-tweaking-of-ruby-algorithms%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F09%2F27%2Fperformance-tweaking-of-ruby-algorithms%2F" height="61" width="51" /></a></div><p>I have been working on <a href="http://github.com/wvanbergen/request-log-analyzer">request-log-analyzer</a> quite a lot recently. One of the things I focused on was improving the parsing performance: because it parses log files that often are very big, processing times tend to be long. So all savings are very welcome.</p>
<p>Improving the performance of a command line application that does a lot of processing is very different from optimizing the performance of a web application. Request-log-analyzer basically reads a file line by line and processes it, so small performance improvements in the line processing algorithm can really add up when the file has a lot of lines. I used <a href="http://ruby-prof.rubyforge.org/">ruby-prof</a> to get information about the performance of our algorithms split out by method to focus my tweaking efforts. I have written down some of my findings below; hopefully they can be helpful.</p>
<h3>Parallelization</h3>
<p>My first thought for improving performance was parallelization: parse multiple lines at the same time. Unfortunately, this did not yield the results I was hoping for: it instead become slower. Probably, this is because Ruby implements its own in-process threading and thus only uses one core of my processor.</p>
<h3>Block overhead</h3>
<p>The overhead of using a block should not be underestimated. Consider the following simple change, which improved the performance of request-log-analyzer by 1.5-2% on large log files:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#008000; font-style:italic;"># with block</span>
io.<span style="color:#9900CC;">each_line</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>line<span style="color:#006600; font-weight:bold;">|</span> process_line<span style="color:#006600; font-weight:bold;">&#40;</span>line<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># without block</span>
process_line<span style="color:#006600; font-weight:bold;">&#40;</span>line<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">while</span> line = io.<span style="color:#CC0066; font-weight:bold;">gets</span></pre></div></div>

<h3>Regular expressions</h3>
<p>If you&#8217;re using complex regular expressions, and you do not expect that every string will match it successfully, it can be beneficial to test the string with a simpler regexp first. For example, request-log-analyzer uses a complex regexp to see if a line in a log file is a &#8220;Completed in&#8230;&#8221; line with the request duration in it:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#008000; font-style:italic;"># Check every line to see if it is a &quot;completed&quot; line and capture the values</span>
<span style="color:#9966CC; font-weight:bold;">if</span> line =~ <span style="color:#006600; font-weight:bold;">/</span>Completed <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#40;</span>\d<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span>ms \<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>?:View: <span style="color:#006600; font-weight:bold;">&#40;</span>\d<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#006600; font-weight:bold;">&#41;</span>?DB: <span style="color:#006600; font-weight:bold;">&#40;</span>\d<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span>\<span style="color:#006600; font-weight:bold;">&#41;</span> \<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">&#40;</span>\d\d\d<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#006600; font-weight:bold;">+</span>\<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#40;</span>http.<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span>\<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">/</span>
  <span style="color:#008000; font-style:italic;"># do something with the captured values</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>I improved this by first checking for a superficial regexp that tells me with 99% certainty that the complex regexp will match the line successfully as well:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#9966CC; font-weight:bold;">if</span> line =~ <span style="color:#006600; font-weight:bold;">/</span>Completed <span style="color:#9966CC; font-weight:bold;">in</span><span style="color:#006600; font-weight:bold;">/</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> line =~ <span style="color:#006600; font-weight:bold;">/</span>Completed <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#40;</span>\d<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span>ms \<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>?:View: <span style="color:#006600; font-weight:bold;">&#40;</span>\d<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#006600; font-weight:bold;">&#41;</span>?DB: <span style="color:#006600; font-weight:bold;">&#40;</span>\d<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span>\<span style="color:#006600; font-weight:bold;">&#41;</span> \<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">&#40;</span>\d\d\d<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#006600; font-weight:bold;">+</span>\<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#40;</span>http.<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span>\<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">/</span>
    <span style="color:#008000; font-style:italic;"># do something with the captured values</span>
  <span style="color:#9966CC; font-weight:bold;">else</span>
    <span style="color:#ff6633; font-weight:bold;">$stderr</span>.<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{line.inspect} expected to match 'Completed' regexp!&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Depending on the log file, this can increase performance by ~3%. Another benefit of this approach is that it will give feedback on lines that matched the simple regexp, but not the complex one. This information can be used to correct the regular expressions.</p>
<h3>Calculate things that do not change only once</h3>
<p>Calculate things that do not change only once is easier said than done. For instance, request-log analyzer can aggregate durations in a category. A category can be based on a request field that is parsed from the log, or a <code>Proc</code> that calculates it:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#008000; font-style:italic;"># during parsing:</span>
<span style="color:#9966CC; font-weight:bold;">if</span> categorizer.<span style="color:#9900CC;">respond_to</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:call</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  category = categorizer.<span style="color:#9900CC;">call</span><span style="color:#006600; font-weight:bold;">&#40;</span>request<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">else</span>
  category = request<span style="color:#006600; font-weight:bold;">&#91;</span>categorizer<span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
categories<span style="color:#006600; font-weight:bold;">&#91;</span>category<span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">aggregate_request</span><span style="color:#006600; font-weight:bold;">&#40;</span>request<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>With this implementation, <code>categorizer</code> will be checked to be a <code>Proc</code> for every request, but as the value of <code>categorizer</code> will not change, the result of the check will be constant as well. I solved this my making sure that it is always a <code>Proc</code> beforehand, so the check is no longer necessary during parsing:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#008000; font-style:italic;"># before parsing:</span>
<span style="color:#9966CC; font-weight:bold;">if</span> categorizer.<span style="color:#9900CC;">respond_to</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:call</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  categorizer_proc = categorizer
<span style="color:#9966CC; font-weight:bold;">else</span>
  categorizer_proc = <span style="color:#CC0066; font-weight:bold;">lambda</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>request<span style="color:#006600; font-weight:bold;">|</span> request<span style="color:#006600; font-weight:bold;">&#91;</span>categorizer<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># during parsing:</span>
category = categorizer_proc.<span style="color:#9900CC;">call</span><span style="color:#006600; font-weight:bold;">&#40;</span>request<span style="color:#006600; font-weight:bold;">&#41;</span>
categories<span style="color:#006600; font-weight:bold;">&#91;</span>category<span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">aggregate_request</span><span style="color:#006600; font-weight:bold;">&#40;</span>request<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Performance gain: ~1%! And because on several instances a similar technique could be applied, the performance got improved by about 4% in total.</p>
<h3>Check the most common case first</h3>
<p>Consider the following example, which converts a number in any traffic unit (kilobytes, MB, etc) to bytes:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> convert_traffic<span style="color:#006600; font-weight:bold;">&#40;</span>value, unit<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">case</span> unit
  <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#ff3333; font-weight:bold;">:GB</span>, <span style="color:#ff3333; font-weight:bold;">:G</span>, <span style="color:#ff3333; font-weight:bold;">:gigabyte</span>      <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#006600; font-weight:bold;">&#40;</span>value.<span style="color:#9900CC;">to_f</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006666;">1000</span>_000_000<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">round</span>
  <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#ff3333; font-weight:bold;">:MB</span>, <span style="color:#ff3333; font-weight:bold;">:M</span>, <span style="color:#ff3333; font-weight:bold;">:megabyte</span>      <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#006600; font-weight:bold;">&#40;</span>value.<span style="color:#9900CC;">to_f</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006666;">1000</span>_000<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">round</span>
  <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#ff3333; font-weight:bold;">:KB</span>, <span style="color:#ff3333; font-weight:bold;">:K</span>, <span style="color:#ff3333; font-weight:bold;">:kilobyte</span>, <span style="color:#ff3333; font-weight:bold;">:kB</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#006600; font-weight:bold;">&#40;</span>value.<span style="color:#9900CC;">to_f</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006666;">1000</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">round</span>
  <span style="color:#008000; font-style:italic;"># ... even more units here</span>
  <span style="color:#9966CC; font-weight:bold;">else</span> value.<span style="color:#9900CC;">to_i</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>In most cases, the value will simply given in bytes, which will be returned by the final <code>else</code> after all possibilities have been checked. This can be improved by checking for this possibility first:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#008000; font-style:italic;"># Converts traffic in any unit to bytes.</span>
<span style="color:#9966CC; font-weight:bold;">def</span> convert_traffic<span style="color:#006600; font-weight:bold;">&#40;</span>value, unit<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">case</span> unit
  <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#0000FF; font-weight:bold;">nil</span>, <span style="color:#ff3333; font-weight:bold;">:B</span>, <span style="color:#ff3333; font-weight:bold;">:byte</span>          <span style="color:#9966CC; font-weight:bold;">then</span> value.<span style="color:#9900CC;">to_i</span>
  <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#ff3333; font-weight:bold;">:GB</span>, <span style="color:#ff3333; font-weight:bold;">:G</span>, <span style="color:#ff3333; font-weight:bold;">:gigabyte</span>      <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#006600; font-weight:bold;">&#40;</span>value.<span style="color:#9900CC;">to_f</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006666;">1000</span>_000_000<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">round</span>
  <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#ff3333; font-weight:bold;">:MB</span>, <span style="color:#ff3333; font-weight:bold;">:M</span>, <span style="color:#ff3333; font-weight:bold;">:megabyte</span>      <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#006600; font-weight:bold;">&#40;</span>value.<span style="color:#9900CC;">to_f</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006666;">1000</span>_000<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">round</span>
  <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#ff3333; font-weight:bold;">:KB</span>, <span style="color:#ff3333; font-weight:bold;">:K</span>, <span style="color:#ff3333; font-weight:bold;">:kilobyte</span>, <span style="color:#ff3333; font-weight:bold;">:kB</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#006600; font-weight:bold;">&#40;</span>value.<span style="color:#9900CC;">to_f</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006666;">1000</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">round</span>
  <span style="color:#008000; font-style:italic;"># ... even more units here</span>
  <span style="color:#9966CC; font-weight:bold;">else</span> <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#996600;">&quot;Unknown unit: #{unit.inspect}!&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Again this change adds up to a ~1% performance increase if this method is called very often.</p>
<p>These kinds of changes really improved the performance of request-log-analyzer by quite a bit, so upgrade to the latest version to get some of your valuable time back! <img src='http://techblog.floorplanner.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/09/27/performance-tweaking-of-ruby-algorithms/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Build ActionScript3 projects with TextMate in 5 easy steps</title>
		<link>http://techblog.floorplanner.com/2009/09/05/build-actionscript3-projects-with-textmate-in-5-easy-steps/</link>
		<comments>http://techblog.floorplanner.com/2009/09/05/build-actionscript3-projects-with-textmate-in-5-easy-steps/#comments</comments>
		<pubDate>Sat, 05 Sep 2009 11:51:34 +0000</pubDate>
		<dc:creator>Gert-Jan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Flash+ActionScript]]></category>
		<category><![CDATA[textmate actionscript flex sdk]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=704</guid>
		<description><![CDATA[The text editor of choice of our Rails team is TextMate. Our Flash team is a bit divided between Eclipse+FDT and FlexBuilder. I wanted to see if TextMate is a good alternative for building Flash/ActionScript projects.
There are a couple of good sources on using TexMate for ActionScript projects, but it&#8217;s a little fragmented and sometimes [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F09%2F05%2Fbuild-actionscript3-projects-with-textmate-in-5-easy-steps%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F09%2F05%2Fbuild-actionscript3-projects-with-textmate-in-5-easy-steps%2F" height="61" width="51" /></a></div><p>The text editor of choice of our Rails team is TextMate. Our Flash team is a bit divided between Eclipse+FDT and FlexBuilder. I wanted to see if TextMate is a good alternative for building Flash/ActionScript projects.</p>
<p>There are a couple of good sources on using TexMate for ActionScript projects, but it&#8217;s a little fragmented and sometimes outdated. I found <a href="http://www.pixelate.de/blog/setting-up-a-as3-project-in-textmate">pixelate&#8217;s blog post</a> and <a href="http://blog.simongregory.com/">Simon&#8217;s blog</a> very useful.</p>
<h3>1. TextMate</h3>
<p>First of all, you need have MacroMates&#8217; <a href="http://macromates.com/">TexMate</a> of course. If you don&#8217;t already own a copy, you can download a <a href="http://download-b.macromates.com/TextMate_1.5.9.dmg">30-day-trial</a>.</p>
<h3>2. ActionScript3 bundle</h3>
<p><a href="http://blog.simongregory.com/">Simon Gregory</a> did some fine work by creating a TextMate bundle for ActionScript3. The most important things that the bundle handles are <a href="http://blog.simongregory.com/09/as3-autocompletion-in-textmate/">auto-completion</a> and <a href="http://blog.simongregory.com/02/improved-auto-import-for-actionscript-3-in-textmate/">auto-import</a>.  You can <a href="http://blog.simongregory.com/wp-content/assets/bundles/ActionScript%203.tmbundle.zip">download it</a> directly from his blog, or fetch it with Git or SVN.</p>
<p>To install via Subversion:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family: Monaco,monospace;">export LC_CTYPE=en_US.UTF-8
cd ~/&quot;Library/Application Support/TextMate/Bundles/&quot;
svn co http://svn.textmate.org/trunk/Review/Bundles/ActionScript\ 3.tmbundle
osascript -e 'tell app &quot;TextMate&quot; to reload bundles'</pre></div></div>

<p>To install via Git:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family: Monaco,monospace;">cd ~/&quot;Library/Application Support/TextMate/Bundles/&quot;
git clone git://github.com/simongregory/actionscript3-tmbundle.git &quot;ActionScript 3.tmbundle&quot;
osascript -e 'tell app &quot;TextMate&quot; to reload bundles'</pre></div></div>

<h3>3. Flex SDK</h3>
<p>The actual building of your project is done by the free <a href="http://www.adobe.com/cfusion/entitlement/index.cfm?e=flexbuilder3&#038;promoid=DJGYF">Flex 3 SDK</a>. Download it and move the extracted folder into your /Developer/SDKs/ folder. The SDK has to be accessible throughout your whole system. You can do this by adding it to the PATH variable in the /etc/profile file. Open terminal and type:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family: Monaco,monospace;">sudo mate /etc/profile</pre></div></div>

<p>Then add the folder &#8220;/Developers/SDKs/flex_sdk_3/bin&#8221; to the file and save it. It should look something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family: Monaco,monospace;">PATH=&quot;/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/mysql/bin:/Developer/SDKs/flex_sdk_3/bin&quot;</pre></div></div>

<h3>4. TextMate settings</h3>
<p>Before we can start the ActionScript fun we have to setup a few things in TextMate. Open TextMate and select File→New Project. Click on the info button located in the bottom of the Project Drawer. Add two shell variables so that the ActionScript Bundle knows where to look for your files:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family: Monaco,monospace;">TM_FLEX_FILE_SPECS    src/Main.as
TM_FLEX_OUTPUT        bin/Main.swf</pre></div></div>

<p>We also need to let TextMate know where the Flex SDK is located. Go to TextMate→Preferences→Advanced→Shell Variables and add a new global variable:</p>

<div class="wp_syntax"><div class="code"><pre class="console" style="font-family: Monaco,monospace;">TM_FLEX_PATH    Developer/SDKs/flex_sdk_3</pre></div></div>

<h3>5. Hello World</h3>
<p>With all that out of the way, we can finally start working on a ActionScript project: Hello World. Create a folder on your system that will hold this project. Drag this folder to TextMate&#8217;s Project Drawer. Create two new folders named bin and src in your project folder. Then create a new file in the src folder and name it Main.as. It should look something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family: Monaco,monospace;">package <span style="color: #66cc66;">&#123;</span>        
    <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">Sprite</span>;
    <span style="color: #0066CC;">import</span> flash.<span style="color: #0066CC;">text</span>.<span style="color: #0066CC;">TextField</span>;
&nbsp;
    <span style="color: #66cc66;">&#91;</span>SWF<span style="color: #66cc66;">&#40;</span> <span style="color: #0066CC;">backgroundColor</span>=<span style="color: #ff0000;">'0xFFFFFF'</span>, frameRate=<span style="color: #ff0000;">'30'</span>, <span style="color: #0066CC;">width</span>=<span style="color: #ff0000;">'200'</span>, <span style="color: #0066CC;">height</span>=<span style="color: #ff0000;">'200'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
&nbsp;
    <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Main <span style="color: #0066CC;">extends</span> Sprite <span style="color: #66cc66;">&#123;</span>
        <span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #0066CC;">textField</span>: <span style="color: #0066CC;">TextField</span>;
&nbsp;
        <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> Main<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #0066CC;">textField</span> = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #0066CC;">TextField</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
            <span style="color: #0066CC;">textField</span>.<span style="color: #0066CC;">text</span> = <span style="color: #ff0000;">&quot;Hello World.&quot;</span>;
&nbsp;
            addChild<span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">textField</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span>        
    <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>Choose Bundles→ActionScript 3→Build to build your project. A terminal window pops up which runs the Flex SDK to build your project. You can find the resulting Main.swf file in your bin folder. Yay!</p>
<h3>Notes</h3>
<p>If you want to build Flash Player 10 specific stuff (like me) you have to let the Flex SDK know. Open /Developer/SDKs/flex_sdk_3/frameworks/flex-config.xml and set the target-player tag to 10.0.0</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family: Monaco,monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target-player<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>10.0.0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target-player<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>The easiest way to work with libraries, the so called SWC files, in this setup is to drop them directly into /Developer/SDKs/flex_sdk_3/frameworks/libs folder. That way the Flex SDK has no problem finding them.</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/09/05/build-actionscript3-projects-with-textmate-in-5-easy-steps/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>New version of Scoped search</title>
		<link>http://techblog.floorplanner.com/2009/08/31/new-version-of-scoped-search/</link>
		<comments>http://techblog.floorplanner.com/2009/08/31/new-version-of-scoped-search/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 09:37:22 +0000</pubDate>
		<dc:creator>Willem van Bergen</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[LIKE]]></category>
		<category><![CDATA[query language]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[scoped_search]]></category>
		<category><![CDATA[search]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=698</guid>
		<description><![CDATA[After an almost complete rewrite, I am proud to present version 2.0 of scoped_search, the ActiveRecord plugin that makes it easy to find records using a simple query language. This new version support a new query language that supports more complex constructs, and can therefore be used to conduct more fine-grained queries on your models.
New [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F08%2F31%2Fnew-version-of-scoped-search%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F08%2F31%2Fnew-version-of-scoped-search%2F" height="61" width="51" /></a></div><p>After an almost complete rewrite, I am proud to present version 2.0 of <a href="http://github.com/wvanbergen/scoped_search">scoped_search</a>, the ActiveRecord plugin that <a href="http://techblog.floorplanner.com/2008/07/26/easy-search-with-activerecord/">makes it easy to find records using a simple query language</a>. This new version support a new query language that supports more complex constructs, and can therefore be used to conduct more fine-grained queries on your models.</p>
<h3>New query language</h3>
<ul>
<li>Logical operators: AND (&amp;, &amp;&amp;), OR (|, ||) and NOT (!, -) operators, and parentheses to structure the boolean logic: <code>police AND (car || uniform), -"village people"</code>. By default, the AND operator is used to combine different segments of your query.</li>
<li>Comparison operators: the most common comparison operators are supported, and to what you expect on integer and date field.</li>
<li>Explicit field support: only search in the specified field instead of all fields: <code>age &gt;= 21</code>, <code>created &lt; 2009-01-01</code>, <code>username != "root"</code>.</li>
<li>Check for NULL fields: <code>null? parent</code>, <code>set? error_message</code></li>
<li>Commas are supported to separate the different parts of the query.</li>
</ul>
<p>More information about <a href="http://wiki.github.com/wvanbergen/scoped_search/query-language">the query language</a> can be found in the project wiki on GitHub.</p>
<h3>New definition syntax</h3>
<p>The new version supports a new syntax to define what fields of your model can be searched and in what cases. An example:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> User <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>   
  belongs_to <span style="color:#ff3333; font-weight:bold;">:account_type</span>
&nbsp;
  scoped_search <span style="color:#ff3333; font-weight:bold;">:on</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:first_name</span>, <span style="color:#ff3333; font-weight:bold;">:last_name</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  scoped_search <span style="color:#ff3333; font-weight:bold;">:on</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:created_at</span>, <span style="color:#ff3333; font-weight:bold;">:alias</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:created</span>, <span style="color:#ff3333; font-weight:bold;">:only_explicit</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
  scoped_search <span style="color:#ff3333; font-weight:bold;">:in</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:account_type</span>, <span style="color:#ff3333; font-weight:bold;">:on</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:name</span>, <span style="color:#ff3333; font-weight:bold;">:description</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>After the fields have been defined, the <code>search_for</code> method can be used to search your models using a named scope, just like it was before. The <a href="http://wiki.github.com/wvanbergen/scoped_search/search-definition">project wiki</a> has more information about this new syntax. The search syntax itself hasn&#8217;t changed:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#0066ff; font-weight:bold;">@users</span> = User.<span style="color:#9900CC;">search_for</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:q</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">paginate</span><span style="color:#006600; font-weight:bold;">&#40;</span>page <span style="color:#006600; font-weight:bold;">=&gt;</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:page</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<h3>Installation or upgrade</h3>
<p>Include the gem in your <code>environment.rb</code> configuration and run <code>rake gems:install</code> to install it:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;">config.<span style="color:#9900CC;">gem</span> <span style="color:#996600;">'scoped_search'</span>, <span style="color:#ff3333; font-weight:bold;">:source</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'http://gemcutter.org'</span></pre></div></div>

<h3>Backwards compatibility</h3>
<p>The new version has a new syntax to define the fields that can be searched with a query. This new syntax gives you more fine-grained control over the queries that will be generated, so I urge you to adopt this new syntax. However, the old <code>searchable_on</code> syntax is still available for backwards compatibility.</p>
<p>Please contact me if you have any issues with the new version.</p>
<p><small>(Updated with new gemcutter installation instructions.)</small></p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/08/31/new-version-of-scoped-search/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Papervision3D 2.1 &#8211; alpha</title>
		<link>http://techblog.floorplanner.com/2009/05/26/papervision3d-21-alpha/</link>
		<comments>http://techblog.floorplanner.com/2009/05/26/papervision3d-21-alpha/#comments</comments>
		<pubDate>Tue, 26 May 2009 20:57:53 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Flash+ActionScript]]></category>
		<category><![CDATA[Papervision3D]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=659</guid>
		<description><![CDATA[Just committed rev. 911 to the Papervision3D SVN trunk. Rev. 911 and upwards will become Papervision3D 2.1 because the changes made are quite big.
Major changes where made to the DAE, MD2 and animation classes.
NOTE:
This revision is considerably different then previous revisions. Use with care!
At this point its not advised to use rev. 911 for production.
This [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F05%2F26%2Fpapervision3d-21-alpha%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F05%2F26%2Fpapervision3d-21-alpha%2F" height="61" width="51" /></a></div><p>Just committed rev. 911 to the <a href="http://code.google.com/p/papervision3d/">Papervision3D SVN trunk</a>. Rev. 911 and upwards will become Papervision3D 2.1 because the changes made are quite big.<br />
Major changes where made to the DAE, MD2 and animation classes.</p>
<p>NOTE:<br />
This revision is considerably different then previous revisions. Use with care!<br />
At this point its not advised to use rev. 911 for production.</p>
<p>This revision fixes several issues regarding the <a href="http://code.google.com/p/papervision3d/source/browse/trunk/as3/trunk/src/org/papervision3d/objects/parsers/DAE.as?r=911">DAE class</a>:</p>
<ol>
<li>vertex-animation</li>
<li>nested animations</li>
<li>Cinema4D support</li>
<li>morph-weight animation</li>
<li>splines</li>
<li>cloning</li>
<li>play(), play(&#8221;clipName&#8221;), stop(), pause(), resume()</li>
<li>more&#8230;</li>
</ol>
<p>The whole <a href="http://code.google.com/p/papervision3d/source/browse/trunk/as3/trunk/src/org/papervision3d/?r=911#papervision3d/core/animation">org.papervision3d.core.animation.*</a> package has been revamped <strong>completely</strong> to allow for the changes in the <a href="http://code.google.com/p/papervision3d/source/browse/trunk/as3/trunk/src/org/papervision3d/objects/parsers/DAE.as?r=911">DAE class</a>.</p>
<p><strong>DAE Example</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family: Monaco,monospace;"><span style="color: #000000; font-weight: bold;">var</span> autoPlay : <span style="color: #0066CC;">Boolean</span> = <span style="color: #000000; font-weight: bold;">false</span>; <span style="color: #808080; font-style: italic;">// don't play animations automatically</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">var</span> dae : DAE = <span style="color: #000000; font-weight: bold;">new</span> DAE<span style="color: #66cc66;">&#40;</span> autoPlay, <span style="color: #ff0000;">&quot;myCollada&quot;</span> <span style="color: #66cc66;">&#41;</span>;
&nbsp;
dae.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>FileLoadEvent.<span style="color: #006600;">LOAD_COMPLETE</span>, onDaeComplete<span style="color: #66cc66;">&#41;</span>;
dae.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>FileLoadEvent.<span style="color: #006600;">LOAD_PROGRESS</span>, onDaeLoadProgress<span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #808080; font-style: italic;">// optionally pass materials to DAE</span>
<span style="color: #808080; font-style: italic;">// NOTE: here's a change with previous revs :</span>
<span style="color: #808080; font-style: italic;">// 1. lookup the &lt;material&gt; elements in the COLLADA file (inside &lt;library_materials&gt;).</span>
<span style="color: #808080; font-style: italic;">// 2. write down / remember the @id attribute of the &lt;material&gt; element.</span>
<span style="color: #808080; font-style: italic;">// 3. materials.addMaterial( myMaterial, materialElementID ).</span>
<span style="color: #808080; font-style: italic;">// ==&gt; this will probably change in future revs</span>
<span style="color: #000000; font-weight: bold;">var</span> materials : MaterialsList = <span style="color: #000000; font-weight: bold;">new</span> MaterialsList<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #808080; font-style: italic;">// If textures fail to load optionally add some search-paths </span>
<span style="color: #808080; font-style: italic;">// (relative to the swf):</span>
dae.<span style="color: #006600;">addFileSearchPath</span><span style="color: #66cc66;">&#40;</span> <span style="color: #ff0000;">&quot;images&quot;</span> <span style="color: #66cc66;">&#41;</span>;
dae.<span style="color: #006600;">addFileSearchPath</span><span style="color: #66cc66;">&#40;</span> <span style="color: #ff0000;">&quot;textures&quot;</span> <span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #808080; font-style: italic;">// set to true if you get a script-timeout error</span>
<span style="color: #000000; font-weight: bold;">var</span> asyncParsing : <span style="color: #0066CC;">Boolean</span> = <span style="color: #000000; font-weight: bold;">false</span>;
&nbsp;
<span style="color: #808080; font-style: italic;">// load it!</span>
dae.<span style="color: #0066CC;">load</span><span style="color: #66cc66;">&#40;</span> <span style="color: #ff0000;">&quot;/path/to/dae&quot;</span>, materials, asyncParsing <span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #808080; font-style: italic;">/**
 * The DAE has loaded completely
 */</span>
<span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> onDaeComplete<span style="color: #66cc66;">&#40;</span>event : FileLoadEvent<span style="color: #66cc66;">&#41;</span> : <span style="color: #0066CC;">void</span>
<span style="color: #66cc66;">&#123;</span>
     <span style="color: #000000; font-weight: bold;">var</span> dae : DAE = event.<span style="color: #0066CC;">target</span> as DAE;
&nbsp;
     <span style="color: #808080; font-style: italic;">// add to scene</span>
     scene.<span style="color: #006600;">addChild</span><span style="color: #66cc66;">&#40;</span> dae <span style="color: #66cc66;">&#41;</span>;
&nbsp;
     <span style="color: #808080; font-style: italic;">// start playing animation (if any available)</span>
     <span style="color: #808080; font-style: italic;">// other animation controls include :</span>
     <span style="color: #808080; font-style: italic;">// 1. play( &quot;clipName &quot;)</span>
     <span style="color: #808080; font-style: italic;">// 2. stop()</span>
     <span style="color: #808080; font-style: italic;">// 3. pause()</span>
     <span style="color: #808080; font-style: italic;">// 4. resume()</span>
     <span style="color: #808080; font-style: italic;">// 5. playing (getter: bool indicating if playing)</span>
     dae.<span style="color: #0066CC;">play</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
     <span style="color: #808080; font-style: italic;">// lets create a clone</span>
     <span style="color: #808080; font-style: italic;">// NOTE: DAE#clone() is somewhat bugged still, </span>
     <span style="color: #808080; font-style: italic;">// but seems to work in most cases</span>
     <span style="color: #000000; font-weight: bold;">var</span> clone : DAE = dae.<span style="color: #006600;">clone</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> as DAE;
&nbsp;
     <span style="color: #808080; font-style: italic;">// add clone to scene</span>
     scene.<span style="color: #006600;">addChild</span><span style="color: #66cc66;">&#40;</span> clone <span style="color: #66cc66;">&#41;</span>;
&nbsp;
     <span style="color: #808080; font-style: italic;">// move it a bit</span>
     clone.<span style="color: #006600;">x</span> = <span style="color: #cc66cc;">200</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> onDaeLoadProgress<span style="color: #66cc66;">&#40;</span>event : FileLoadEvent<span style="color: #66cc66;">&#41;</span> : <span style="color: #0066CC;">void</span>
<span style="color: #66cc66;">&#123;</span>
&nbsp;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p><strong>MD2 Example</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family: Monaco,monospace;"><span style="color: #000000; font-weight: bold;">var</span> md2 : MD2 = <span style="color: #000000; font-weight: bold;">new</span> MD2<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">var</span> material : MaterialObject3D = <span style="color: #000000; font-weight: bold;">new</span> WireframeMaterial<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
md2.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>FileLoadEvent.<span style="color: #006600;">LOAD_COMPLETE</span>, onMD2Complete<span style="color: #66cc66;">&#41;</span>;
&nbsp;
md2.<span style="color: #0066CC;">load</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;/path/to/md2&quot;</span>, material<span style="color: #66cc66;">&#41;</span>;
&nbsp;
scene.<span style="color: #006600;">addChild</span><span style="color: #66cc66;">&#40;</span>md2<span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> onMD2Complete<span style="color: #66cc66;">&#40;</span>event : FileLoadEvent<span style="color: #66cc66;">&#41;</span> : <span style="color: #0066CC;">void</span>
<span style="color: #66cc66;">&#123;</span>
       <span style="color: #000000; font-weight: bold;">var</span> md2 : MD2 = event.<span style="color: #0066CC;">target</span> as MD2;
&nbsp;
       md2.<span style="color: #0066CC;">play</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
       <span style="color: #808080; font-style: italic;">// or play some clip :</span>
       <span style="color: #808080; font-style: italic;">// md2.play( &quot;run&quot; )</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p><strong>Animation</strong>:</p>
<p>Click the image below to show an example of the new animation controls.<br />
<a href="http://lab.floorplanner.com/pv3d/21/animation/"><img src="http://techblog.floorplanner.com/wp-content/uploads/2009/05/picture-3.png" alt="Animation Test" title="Animation Test" width="511" height="371" class="alignnone size-full wp-image-686" /></a><br />
Download the source of this example <a href="http://lab.floorplanner.com/pv3d/21/animation/AnimationTest.as">here</a>.</p>
<p>The DAE and MD2 class implement <a href="http://code.google.com/p/papervision3d/source/browse/trunk/as3/trunk/src/org/papervision3d/core/animation/IAnimatable.as">IAnimatable</a>, <a href="http://code.google.com/p/papervision3d/source/browse/trunk/as3/trunk/src/org/papervision3d/core/animation/IAnimationProvider.as">IAnimationProvider</a> and <a href="http://code.google.com/p/papervision3d/source/browse/trunk/as3/trunk/src/org/papervision3d/core/controller/IControllerProvider.as">IControllerProvider</a>, which can be found in the org.papervision3d.core.animation.* package.</p>
<ul>
<li>IAnimatable provides the play(), stop(), pause() and resume() methods.</li>
<li>IAnimationProvider provides a getter / setter #animation for low level access to <a href="http://code.google.com/p/papervision3d/source/browse/trunk/as3/trunk/src/org/papervision3d/core/controller/AnimationController.as">org.papervision3d.core.controllers.AnimationController</a></li>
<li>IControllerProvider provides a getter / setter #controllers for low level access to the different controllers:
<ul>
<li><a href="http://code.google.com/p/papervision3d/source/browse/trunk/as3/trunk/src/org/papervision3d/core/controller/MorphController.as">org.papervision3d.core.controllers.MorphController</a></li>
<li><a href="http://code.google.com/p/papervision3d/source/browse/trunk/as3/trunk/src/org/papervision3d/core/controller/SkinController.as">org.papervision3d.core.controllers.SkinController</a></li>
<li><a href="http://code.google.com/p/papervision3d/source/browse/trunk/as3/trunk/src/org/papervision3d/core/controller/AnimationController.as">org.papervision3d.core.controllers.AnimationController</a></li>
</ul>
</li>
</ul>
<p>As so much has changed I&#8217;m sure some bugs are introduced. Please let me know!</p>
<p>PS: I&#8217;ll be on vacation until june 8th, so its unlikely I&#8217;ll be able to fix any bugs before that time.<br />
PS2: Many people have helped by submitting code-snips, reporting bugs etc. I&#8217;ll credit you all when I&#8217;m back <img src='http://techblog.floorplanner.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/05/26/papervision3d-21-alpha/feed/</wfw:commentRss>
		<slash:comments>37</slash:comments>
		</item>
	</channel>
</rss>
