Thursday, October 6, 2011

Goodbye, MapMaker. Hello, CacheBuilder.

Google has released a new version of Guava, and it's bad news for one of my favorite classes, MapMaker. The exciting feature of MapMaker is its ability to produce an insta-cache, a key-value mapping that calculates values on the fly, expires them, and limits the quantity stored -- all while maintaining thread safety.

In release ten, Guava added CacheBuilder. CacheBuilder produces a Cache: a key-value mapping that calculates values on the fly, expires them, and limits the quantity stored -- all while maintaining thread safety.

Wait, that sounds exactly like MapMaker. Poor MapMaker -- its methods are now deprecated. The king is dead, long live the king!

Here's a quick look at what CacheBuilder does:

final Cache cache =
CacheBuilder.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.maximumSize(50)
.build(CacheLoader.fromFunction(retrieveInterestingInfoByKey);

Here, retrieveInterestingInfoByKey is a Function that goes to the database, calls a service, or performs some calculation to get the value for a key.

What does this cache do?

The first time cache.get(key) is called, the cacheLoader loads the value, stores the entry in its map, then returns the value. If two threads make this call at the same time, one of them loads the value, and the other one blocks until the value is available. Values are never loaded more times than necessary.

If cache.get(key) is called more than ten minutes after that entry was created, the value will be loaded again. When the size of the cache gets close to the maximum, then the older, less-used entries are evicted.

What is this cache good for? Reference data, certainly. Any time you have data that's loaded over and over again, but doesn't change nearly as often as it's loaded. The whole process can share a single cache. It's a good candidate for a singleton Spring bean.

What is this cache not good for? Anything you want to cache across processes or machines. Anything you want to update. (You can evict entries from the cache, but not put them in.) Anything you want persisted.

I could write whole posts about exception handling in the load, testing and tuning hooks, and memory use optimization of the Cache. But those are decorations on the cake. The real point of CacheBuilder is how quickly and easily you can get a map that gets you the information you want, when you want it, without hitting the database every single time.

MapMaker, your name was fun to say, but we won't miss you now that we have CacheBuilder.

1 comment:

  1. Good post, thanks Jess.
    The Guava API docs show several methods in MapMaker as deprecated, but it wasn't immediately obvious to me that the whole class should be dropped in favor of CacheBuilder. Thanks for clarifying.

    ReplyDelete