Looking at the world of media: from music to RIA.

VivMedia Code: the HashTable

May 29th, 2008 Posted in ActionScript, Flash Player, Flex Development, Rich Internet Applications

rune_flash.gifOne of my favorite, and until recently, most used classes in Flex was the ArrayCollection. The ArrayCollection is a powerful data-structure that acts similarly to an Array but provides an extended API that provide shortcuts to data access. A few of the more used accessors are contains(), which tells you if the item is in the ArrayCollection and getItemIndex() which tells you where the item is in the ArrayCollection.

The ArrayCollection is much more then this too. It also has the ability to tie directly into FlexData services and then dynamically page the data into the ArrayCollection instance as data is requested. The ArrayCollection is also the complex data structure that is generated by the HTTPService (when parse to Object is set) if you have more then one child node in an XML structure. If you haven’t used it yet, the ArrayCollection is a very powerful data-structure.

Of course, with this robustness comes limitations. First off, its Flex only. This means that if you are used to Flex development but find yourself on an AS3 only project, you can’t use the ArrayCollection. Another big one is performance. As you begin filling the ArrayCollection up, queries into the data structure start to slow down, and I mean significantly slow down. If you have hundreds of objects in the ArrayCollection, the performance for lookup and access are way slower then just looping over an array and finding it the old fashioned way. A more minor issue is when trying to manipulate data dynamically you start having to write some pretty ugly code such as to prevent null reference errors:

// remove the item if it exists
if(myCollection.contains(objectNeeded))
{
	myCollection.removedItemAt(myCollection.getItemIndex(objectNeeded));
}

Its not that bad, but as you get more and more complex accessing structures you start longing for the simplicity of an Array. This is where the HashTable came into the picture. I wanted something that performs like an Array, yet has the API data accessors that can simplify development. Yet, there was one more thing that I wanted, the ability to map key’s to values like in an object or Dictionary but still maintain Array like access.

From this need came the HashTable. In the past I had built multiple solutions similar to the HashTable but they typically where one-offs that lived in the code the functionality was needed. I never got around to formalizing it into a proper data-structure. I finally got the chance and built it from the ground up for my Photoslider app. So, let’s talk about the HashTable…

Using The HashTable
The HashTable is an ActionScript 3.0 data structure that is not dependent on any of the Flex SDK, this means you can use it freely in both Flash and Flex projects. The HashTable, simply put, is two Arrays which are wrapped in logic to provide a simplified data access API for development. Its not complex, but it can cut out a ton of code that you would typically write over and over.

The main thing to know about the HashTable is that everything revolves around a key/value pair. The key can be anything, from a number to a complex object. When you add an item to the HashTable you define this pairing:

// create a key (person) and item (friends)
var person:Object = {name: "James"};
var friends:Array = [{name: "Eno"}, {name: "Aaron"}, {name: "Doug"}, {name: "Dave"}];
 
// create the table
var hash:HashTable = new HashTable();
hash.addItem(person, friends);
 
...
 
// get my friends
var myFriends:Array = hash.getItem(person) as Array;

As you can see from the example, we can use an Object as a key and then bind another complex object to the key. Later on we can retrieve the item by simply requesting the item by providing the key. Not only can we access via the key, but we can also get all the keys and then retrieve their data. For example, we now have multiple people in our HashTable and we want to get all their friends:

// get all the people and loop on them
var people:Array = hash.getAllKeys();
var len:int = people.length();
for(var i:uint = 0; i < len; i++)
{
	var friends:Array = hash.getItem(people[i]) as Array;
	...
}

Not only can you get all the keys but you can also get all the items by using getAllItems(). There are also other accessors that can help you along the way. Such as:

// how many key/items are in the HashTable
var numberOfItems:int = hash.length;
 
// do we have any items
if(!hash.isEmpty)
{
	// do something
	...
}
 
// is the key or the item in the table?
if(hash.containsKey(person) || hash.containsItem(friends))
{
	// do something
	...
}
 
// we can also remove key pairs
hash.remove(person);
 
// or clear the entire table
hash.removeAll();

Things to Consider When Using the HashTable
If you read my EventBroker post or my Code Behind Pattern post then you know I like to point out any possible gotcha’s when using code. I feel this is very important because if the issues are raised in the beginning it makes the life of the developer a hell of a lot easier. Here are a few nuggets to consider when using the HashTable:

  • The HashTable uses an Array under the hood so this means items are strong referenced. Make sure to remove the items from the HashTable before you decide you no longer need the items in you application and want the Garbage Collection to clean them up.
  • When using the getAllKeys() or getAllItems() you are being handed back a clone of the internal Array. If you want to change the value in the HashTable you will need to overwrite them by updating the HashTable. Note: The current version (0.01) of the Framework has a brute force clone in the HashTable. I was a little for loop happy and this has been fixed locally and will be available in the SVN soon. Version 0.02 of the framework will have this fix. Its nothing to worry about, I just prefer more elegant code and wanted to note this for the few of you that will poor over my code (Aaron, Eno and Dave!)
  • You can have the same object multiple times in the HashTable if it is an item, but only one instance as a key. This means that if you have the object “person” as the key to item “friends”, and then try to addItem(person, friendsTwo) then “friends” will be replaced with “friendsTwo” within the table. This is silent and allowed. Key’s must be unique otherwise you overwrite.

That should be all… if you find anything, want more examples or event want new features let me know!

  1. 1 Trackback(s)

  2. May 29, 2008: Vivisecting Media » Blog Archive » Vivisecting Media Code Depot launched…

You must be logged in to post a comment.