Reputation: 4278
Is there a Cache implementation available in Java, Guava, or another library that can do the following:
cache.put(key, value);
I have seen the Guava LoadingCache
but that implementation requires you to implement the load(key)
method. The load(key)
method is intended to compute a value based on the key by using a database or other resource. Once that value is computed by the load(key)
method I believe the LoadingCache
sticks the resulting (key, value) pair in the cache.
My implementation requirements differ from the LoadingCache
because my keys will remain fixed, but the corresponding values will be slowly updated as I scrape my database. In other words, I don't want to load the entire value at once like the LoadingCache does in it's load(key)
method - I want to leave the key the same and incrementally update the value Object depending on what I get from the database. So it would appear that this precludes using the LoadingCache
since the load(key)
method forces you to load the key's corresponding value all at once.
The reason I want to incrementally load the value (for each key) is because it's going to take a long time and I am using AJAX polling to keep the user updated. Therefore loading it all at once is useless. I want to cache these values so I can easily retrieve them with AJAX. I want them to expire because once the user is done visiting the webpage, they are useless.
Upvotes: 0
Views: 2230
Reputation: 4278
Following @Louis Wasserman's advice I implemented the following code:
LoadingCache<String, WorkerItem> cache = CacheBuilder.newBuilder()
.concurrencyLevel(level)
.maximumSize(size)
.expireAfterWrite(seconds, TimeUnit.SECONDS)
.removalListener(this)
.build(
new CacheLoader<String, WorkerItem>() {
public WorkerItem load(String key) throws Exception {
WorkerItem workerItem = new MoreSpecificWorkerItem();
workerItem.setTask(key);
Controller.beginWorking(workerItem); //Runs in thread pool
return workerItem;
}
}
);
When the user calls get() on the Cache it will immediately return the WorkerItem
and will be populating it in the background. As long as you implement WorkerItem
with an isFinished()
method or similar, it will be possible to know when it's ready for use.
And I implemented a cleanup service since the cache does not periodically remove expired items. Expired items are simply marked dirty and are removed the next time you access them or the next time cleanup is called.
final Runnable doCleanup = new Runnable() {
public void run() {
LoadingCache<K, V> cache = getCache();
cache.cleanUp();
}
}
ScheduledFuture<?> cleanupHandle = scheduler.scheduleAtFixedRate(doCleanup, 1, 1, TimeUnit.MINUTES);
return cleanupHandle;
Upvotes: 2
Reputation: 18148
JCS supports idle time expiration and manual adds
Upvotes: 1