Building a Client-Side Ajax Cache / Page 3 | WebReference

Building a Client-Side Ajax Cache / Page 3


Building a Client-Side Ajax Cache [con't]

Setting the Maximum Cache Size

There are a couple of reasons that you would want to set a maximum size for your cache: one is to prevent the cache from using all of your available memory. The browser, like all applications, is allocated a chunk of memory. It's really not that difficult to use it all up if you're not careful. I've done it myself by using intensive iterative processes. Hoarding lots of huge data sets could cause similar problems. Another valid reason to set limits on the cache size is that the more items that are in your cache, the longer it will take to search through them. While an Ajax call would take more time in the beginning, there would come a time that performance would become negatively impacted by your cache size.

It's simple enough to accept a second constructor argument to set the size, carrying out the element deletions is another matter. If we think of the cache as a treadmill, we can easily envision new items being loaded at the front, and the old ones being dropped off the back. The problem is that Hashes just don't work that way! That's because one of the fundamental design attributes of a Hash is that element ordering is not guaranteed. You can load new items in alright, but there's no simple way to be sure that the ones that you are removing are the oldest ones. Therefore, rather than keeping track of the ordering, it would be feasible to switch container objects to an Array. There are already functions in JavaScript to work with Arrays, including push(), pop(), shift() and unshift(). Sticking with the treadmill idea, we can push() new items into the front of the Array and shift() them off of the back, where the oldest items would be located.

Another change that we'll have to make is how we store the items. We need to keep track of the search string because that's what we're comparing the current form contents with in the cache. We can store both the search values and corresponding results by using an object literal, consisting of two properties called input and output. Here is the code to add the new item after an Ajax call and remove the oldest from the array:

To retrieve an item from the cache, we'll use the find() function of the Prototype Enumerable class. Enumerations are objects that act as collections of values. Enumerable is a module that provides a large set of useful methods for collections. Both the Hash and Array classes already include the Enumerable module. The find() function accepts an iteration function and returns the first element for which the iterator returns true, or undefined if no element matches. Here is the updated code for fetching a cached object. The Function.bind() method is employed to make the this reference point to the input string:

Here is the code for our AjaxCache using an Array instead of a Hash:

Behind the scenes, the find() function is just iterating through each Array element using a for loop. To some degree, we have sacrificed retrieval speed for improved control over management of the items in the cache. This is a reasonable trade off, unless the size of the cache becomes prohibitive. To minimize the effect of retrieval time being adversely affected by a large cache size, you can go with a Hash + Array combination. The Hash will give you the fast access while the Array will provide the cache management functionality. Here's how it works: instead of replacing the Hash, we add an Array to hold keys. The keys will serve the same purpose as primary and foreign keys in a database: Image of a Hash with a key Array

All that's required to add the new functionality to our original AjaxCache class is to:

  1. add the Array to the variable declarations:
  1. Update the onSuccess() function to push() the new input string on the keyArray and update the objects when the cache has grown too large. We can easily reference the item in the cache by using the Array.first() method. Calling Array.shift() will delete the first item in the keyIndex array:

Here are some files that you can use to try out the different cache designs:

The First In, First Out (FIFO) queuing method that we used above is but one of many such methods of dealing with ordering processes. In part two, we'll explore some other popular caching algorithms that will help our cache manage data in different ways.

Original: Jan 26, 2009