views:

44

answers:

3

I'm writing a web application that constantly retrieves XML "components" from a database and then transforms them into XHTML using XSLT. Some of these transformations happen frequently (e.g. a "sidebar navigation" component goes out for the same XML and performs the same XSL transformation on every page that features that sidebar), so I have started implementing some caching to speed things up.

In my current solution, before each component attempts to perform a transformation, the component checks with a static CacheManager object to see if a cached version of the transformed XML exists. If so, the component outputs this. If not, the component performs the transformation and then stores the transformed XML with the CacheManager object.

The CacheManager object keeps an in-memory store of the cached transformed XML (in a Dictionary, to be exact). In my local, development environment this is working beautifully, but I'm assuming this may not be a very scalable solution.

What are the potential downfalls of storing these data in-memory? Do I need to put a cap on the amount of data I can store in an in-memory data structure like this? Should I be using a different data store for this type of caching altogether?

+3  A: 

The obvious disadvantage will be, as you suspect, potentially high memory usage by your cache. You may want to implement a system where rarely-used items "expire" out of the cache when memory pressure goes up. Microsoft's Caching Application Block implements pretty much everything you need, right out of the box.

Another potential (though unlikely) problem you could run into is the cost of digging through the cache to find what you need. At some point it could be faster to just go ahead and generate what you need instead of looking through the cache. We've run into this in at least one precise scenario related to very large caches and very cheap operations. It's unlikely, but it can happen.

Mark
+1  A: 

You should definitly look for a generic chache implementation. I dont do C#, so I dont know of any solution in your language. In Java, I would have recommended EHCache.

Caching is much harder that it seems at first. That's why it is probably a good idea to rely on work done by others. Some of the problem you will run into at some point are concurrency, cache invalidation, time to live, blocking caches, cache management (statistics, clearing of caches, ...), overflowing to disk, distributed caching, ...

Monitoring a cache is a must. You need to see if the caching strategy you put in place is actually doing anything good (cache hits / cache misses, percentage of cache used, ...) You should probably divide your cache in multiple regions to be able to monitor better the cache usage.

As a side note, as long as you cache your XML after transformation, you should probably store its String representation (and not an object tree). That's one less transformation to do after the cache asyou are probably outputing it as String anyway. And there is a good chance that the String representation will take less space (but as always, measure that, dont take my word for it).

Guillaume
Thanks for the help! I actually am storing the string representation in the Dictionary (I probably should have said that), but it's nice to hear some confirmation that that was a good idea. :)
attack
+1  A: 

You can do the caching but only keep reference values (uri) in the dictionary and store the actual transformed XML on disk. This is probably going to be faster than retrieving values from the database and doing the transformation again, slower than storing this all in memory but gets around the problem of having all of this cached data in memory in the first place. This also could allow the transformed XML documents to survive through a recycle/reset, but you'd have to rebuild your dictionary and you'd also have to think about "expiring" documents that need to be purged from the disk cache.

Just an idea..

Dave White
Thanks for the idea! I'll keep it in mind as a back-up solution in case this caching business goes down in flames.
attack