Wednesday, July 01, 2009

Javascript Deque

Doubly ended queue code is just a whole lot cleaner if you go with dummy head and tail nodes to avoid special cases. I put together this Javascript example: A Javascript array has the methods available (push(), pop(), shift(), unshift()) to be used as a deque but of course being an array you shouldn't be adding and removing from anywhere but the tail end if you need top performance. The following provides for a comparison between my deque and a regular Javascript array for adding and removing items from the head or tail of the data structure.
Items:
array dequeue
head tail

Tuesday, June 23, 2009

JavaScript InfoVis Toolkit

The JavaScript InfoVis Toolkit is another example of a library exploiting Canvas technology. I put together a small demo Rails application that uses the toolkit to provide a dynamic tree view of the Rails application directory structure.

Monday, June 22, 2009

Don't Miss Aloha on Rails!



You don't want to miss the Hawaii Ruby On Rails Conference - Waikiki, Oahu, Hawaii - October 5-6 2009. The speaker list is impressive and still growing. The venue is awesome and is only a short (really short!!!) walk from Waikiki beach. The economic downturn is making flights to Hawaii very reasonable right now.

This conference is being primarily organized by Seth Ladd, a Honolulu based RoR developer and great co-worker of mine. There is an Aloha On Rail Blog featuring the latest information. The latest post features another great co-worker of mine, Honolulu Hacker Kevin English in a clip on why you should come to Aloha on Rails.

Why Aloha on Rails???

  • mingle with a group of very talented developers
  • gain insights on the latest technologies and techniques
  • re-charge your batteries
  • reward yourself!

This is a no brainer - register now!

Friday, June 19, 2009

Rails Bug in *_changed?

UPDATE: The latest rails has fixed this problem but this problem was still present in Rails 2.2.2.

The new dirty methods in Rails show this interesting result:



The above code has position as a nullable integer column. When parameters come in a post via the parameters hash position comes across as a string. For 14 you get the Rails goodness and assigning "14" is not seen as a change - but why not the same thing for 0?

The problem is in the following offending code in vendor/rails/activerecord/lib/active_record/dirty.rb file. I have commented out the problem line (look for the no!!!!...) and added what I believe to be the correct code below it:

Wednesday, May 27, 2009

Creating a Remote Shared Git Repository

When creating a remote shared Git repository you likely want to do it like this:



The "--shared=group" is important as it will ensure that permissions will be set correctly when working with the repository with multiple users. When issued in this way the config file will end up looking like this:

Tuesday, May 26, 2009

Rails ActsAsList - Initializing position Values

Recently I worked on a project that had a model acting as a tree with the children acting as a list within the scope of the child's parent. The old school ActsAsTree and ActsAsList plugins used in combination, handle this scenario nicely. There was one problem however - we had a large "tree" to load in where only some of the children were ordered under their parent. The rest of the children had a NULL value sitting in the position column. Because ActsAsList works by setting "position = position + 1 WHERE position >= x" when insert_at(x) is called this wasn't going to work with the data as is. "NULL = NULL + 1" just doesn't seem to work out too well. I decided to pre-process the data putting the children in their natural position order. In this case the natural position order would be by the provided position with a secondary sort on short_name if the position was not given. Also, when a child list contains both numeric positions and NULLs the NULL children should go to the bottom. Given the number of rows I was processing I knew this was going to take some time so I decided to see how this would perform when implemented as a MySQL stored procedure. Here is the code I came up with shown in the migration that creates the stored proc:



And here is the rake task to call it:



The stored procedure took just over a minute to do the renumbering. After implementing I decided to compare this to a straight SQL version that would be portable to different databases - but not as fast. I tried to avoid an ActiveRecord tax here and did the SQL in raw execute statements. Here is the rake task:



The final results showed the stored procedure technique to be about 5 times faster than the SQL technique.

Monday, May 25, 2009

Quicker Rails Seed Data Loading

The word is that Rails 3.0 will feature a way to load seed data. This is sure to be a handy and needed feature, however, when loading large amounts of seed data you are probably going to have to abandon ActiveRecord and / or fixture style loading in your db/seeds.rb file in order to get the kind of performance you want. Recently I set up a way to load seed data for a Rails 2.2.2 project which exploits the "LOAD DATA INFILE..." command that MySQL provides. This cut the data loading time for my particular data set from over 15 minutes (I gave up waiting) to less than 30 seconds. This technique is likely to remain relevant for your future db/seed.rb files. The following rake tasks set up my Rails application to load ".psv" and ".yml" seed data files from the db/seed directory. The ".yml" files are normal YAML fixture files and are loaded via my rake tasks using an ordinary fixture technique. The ".psv" files are pipe separated files which are loaded use the above mentioned "LOAD DATA INFILE..." command. The way I have this set up here the order of the columns in your ".psv" needs to match the column order in your database so you may want to tweak this code a bit and provide parameters to specify a different column order. In other words, YMMV, anyway, code follows:



One thing to look at carefully when using this technique is what your database product does with "empty" values in your data set. MySQL didn't want to seem to let a empty numeric value be NULL which caused me to go with some data massaging before and / or after load.