Reputation: 24550
I'm looking for an in-memory cache with the following behaviour.
I know how to implement such a cache, but does anybody know an existing library, which provides a cache like this.
This is my idea about the interface. There are elements for the cache
Element element = new Element(Object key, Object objectToCache);
A loader provides all elements
Collection<Element> elements = myLoader.getElements();
In the end there is the cache
public Cache {
public Cache(CacheLoader loader, int timeToReload) {
...
}
public Object getValueForKey(Object key {
...
}
...
}
A solution would be to have a cache with a single entry, which is a HashMap of the real entries. With this solution I can use existing caches like Ehcache or Guava Caches.
But nevertheless I'm looking for existing code, before I start writing a own library.
Upvotes: 0
Views: 1106
Reputation: 166
Do you look for some kind of distributed cache and want spread the initial load over many instances, right?
Hazlecast persistent datastore API is always worth a look.
Initialization on startup As of 1.9.3 MapLoader has the new MapLoader.loadAllKeys API. It is used for pre-populating the in-memory map when the map is first touched/used. If MapLoader.loadAllKeys returns NULL then nothing will be loaded. Your MapLoader.loadAllKeys implementation can return all or some of the keys. You may select and return only the hot keys, for instance. Also note that this is the fastest way of pre-populating the map as Hazelcast will optimize the loading process by having each node loading owned portion of the entries.
In combination with the hazelcast.initial.min.cluster.size configuration property you can distribute your initial load.
Upvotes: 2
Reputation: 5469
I cannot see where this is a library, either. Simply because your requirements are very special:
I would drop the lazy-"requirement" and simply use a ExecutorService.newSingleThreadScheduledExecutor(ThreadFactory)
with a scheduled daemon thread that reloads a ConcurrentHashMap every hour, starting on application startup (asynchroneously). That is as simple as it can get.
If you want to have it more complicated make your get method synchronized
and check for an isInitialized
or use double-checked locking or, or, or. You see where this gets? This tiny requirement you created makes you wanna go for a library, but because of the other requirements I would just question that it makes any sense at all and go for a simpler solution.
Upvotes: 0
Reputation: 77495
This functionality is probably to simple to be wrapped in a library efficiently. After all, it boils down to having a thread call the reinitalize function every hour.
Getter:
if (collection == null) reinitialize();
return collection.get(key);
Clearing thread:
while(true) {
Thread.sleep(60*60);
collection = null; // probably as a method.
}
Notice that I would not call this "caching".
The strategy you are calling for is a timer-triggered reinitialization. Caching usually means
Upvotes: 0
Reputation: 75426
Sounds like you need to override HashMap.get() and add an if that has a timer for resetting, and code that loads if necessary.
If you do not need more than that I would not look for a library for it. Most caches do not populate fully at first access anyway.
Upvotes: 0
Reputation: 11257
I'm not sure what kind of collection you need (Map, Set, List or Queue) but take a look at Google Guava Cache implemetantions
Upvotes: 1