Maybe this is slightly academic, but if I implement a cache for speeding up an application, how should I best handle cache misses? (In my case, the language would be Java, but maybe the answer can be more general.)
Throw an exception:
ResultType res;
try {
res = Cache.resLookup(someKey);
} catch (NotFoundException e) {
res = Cache.resInsert(someKey, SlowDataSource.resLookup(someKey));
}
Ask before fetch:
ResultType res;
if (Cache.contains(someKey) {
res = Cache.resLookup(someKey);
} else {
res = Cache.resInsert(someKey, SlowDataSource.resLookup(someKey));
}
Return null:
ResultType res;
res = Cache.resLookup(someKey);
if (null == res) {
res = Cache.resInsert(someKey, SlowDataSource.resLookup(someKey));
}
Throwing an Exception seems wrong, after all, this isn't an error. Letting the Cache do a look up for contains() and then again to retrieve the data seems wasteful, especially as this would occur every time. And checking for null
of course requires that null
can never be a valid result...
The first is excessive I think and not a good use for exceptions. Do you have an expectation that there will be a cache hit? A cache miss is a fairly normal occurrence I would think and thus an exception becomes simply flow control. Not good imho.
The second is a race condition. There is a time delay between checking on the existence of the cache entry and querying it. That could lead to all sorts of trouble.
Returning null is probably appropriate in the general sense but that comes with some qualifications.
Firstly, what type of cache is it? Ideally you'd be talking to a read-through cache in which case if it's not in the cache it'll simply get it from the source, which is not the style of code you've written there.
Secondly, the get then insert is another race condition. Look at the interface for ConcurrentHashMap
for a good general way of dealing with this kind of thing. Most notably, the putIfAbsent()
call is an atomic operation that does the equivalent of you're third call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With