method caching using AOP

108 views
Skip to first unread message

Andreas

unread,
Feb 17, 2009, 3:25:18 AM2/17/09
to google-guice
hi!

i will need to use a simplistic caching on some methods in my code.
for example, i do geocoding, route planning, REST request, etc.. and i
want to avoid doing the exact same requests more than once every few
seconds.

this happens in multiple threads both in batch processes and in
response to http requests, so its a classic cross-cutting concern.

of course i could implement a simplistic implementation of cached
methods, but i thought maybe other people have the same problem. im
thinking of doing a @Cached(maxObjects=5000, lifetime=MILLIS_PER_DAY)
annotation, with two hashMaps to store the data. maybe also
weakHashMap in addition?

in spring this is done via cache provider, which is quite flexible and
also allows for cluster-aware caching. in my case a simple cache for
maximum ~5000 objects with a maximum lifetime of 1 day would be
sufficient.

has anyone implemented something similar? i want to avoid reinventing
the wheel - though i like to learn more about wheels.

best regards
Andreas

Alen Vrečko

unread,
Feb 17, 2009, 12:10:48 PM2/17/09
to google-guice
Hi,

I had similar problem. In the end I just went with LinkedHashMap (LRU)
with synchronization and keyed on username. MapMaker is nice but not
my choice for LRU.

What do you key on? If this is a pure method it could be the
arguments, if not some different criteria applies?

Cheers,
Alen

Taylor Gautier

unread,
Feb 17, 2009, 5:35:15 PM2/17/09
to google...@googlegroups.com
this pattern is referred to as a memoizer.  i blogged about it here:

Andreas Petersson

unread,
Feb 17, 2009, 8:44:50 PM2/17/09
to google...@googlegroups.com

> this pattern is referred to as a memoizer. i blogged about it here:
>
> http://javathink.blogspot.com/2008/09/what-is-memoizer-and-why-should-you.html
>
> there's also a nice implementation on google code:
>
> http://code.google.com/p/concurrentlinkedhashmap/wiki/SelfPopulatingCache
there are some nice ideas in there..there are two issues that came to my
mind:
1) hibernate doesn't like acting in multiple threads in a single
transaction. - so calling my particular code in futures is not really an
option.
2) i want to evict the cache at some point in the future.the method keys
are based on user input - city, name, etc.. so its most likely that the
cache will grow ad infinitum, given time.

i have taken a look at
http://opensource.atlassian.com/confluence/spring/display/DISC/Caching+the+result+of+methods+using+Spring+and+EHCache
there is a quite simple MethodCacheInterceptor class, which uses EHCache
+ spring AOP. i think i will adapt this example to guice AOP with injection.

i think using such a method cache should really be domain specific where
i can control the input and context/semantics of the method to cache
precisely.

some reasons for that:
the cacheKey in the spring example is put together like

targetName.methodName.argument0.argument1...

i don't think that is a great idea for a general-purpose implementation
as an argument with a stupid/expensive toString method might mess
everything up.
it would make sense to aim for some kind of equals() check on the
original parameters but this will most likely kill the GC as we need to
retain the original references to the arguments.
furthermore, a general-purpose implementation would need to take into
account all current members of the class, and all static members it
accesses.
so i think i will need to roll my own specific method cache, and be
careful on what methods i apply it.

best regards
Andreas

Reply all
Reply to author
Forward
0 new messages