I am using Guava LoadingCache to cache some of the results. Using load method I fetch results from other source and put into cache using 'put(key,value)'.
Now the problem I am trying to solve is: I want to get all the available results in that cache with out passing any keys. Because I am interested in taking all the values presented in the cache at that time regardless of any specific keys.
getall(Iterable<?> keys) or getAllPresent(Iterable<?> keys) methods are there but those are expecting the keys to be passed.
You can use (Loading)Cache#asMap view and operate on returned ConcurrentMap. There's nice description on Guava wiki page:
You can view any Cache as a ConcurrentMap using its asMap view, but
how the asMap view interacts with the Cache requires some explanation.
cache.asMap() contains all entries that are currently loaded in the
cache. So, for example, cache.asMap().keySet() contains all the
currently loaded keys.
Related
I'm storing a few properties(KV pairs) in a hierarchical db(JCR). As part of business logic, i have to lookup these key-value pairs very frequently and each time i have to call a method which goes and retrieves the persisted value.
I'm working on a CMS called AEM and all these key-value pairs are authored using a component and stored as JCR properties. Presently i've written an OSGi service which will go to that node and retrieve the value corresponding to the key and this method gets invoked several several times. Instead of making repeated calls to the service method to retrieve these values, can you suggest an efficient way to do this? OSGi auto-wiring?
First of all, I would suggest you to thing twice if you really need to get rid of (or decrease) node properties reading. Do you have performance issues because of this reading or you have another important reason?
If you still wanna to mess with it, I would suggest you next configuration:
You have a Cache Component, which contains this map with all key-value pairs.
You have Listener, which listens to node's change, which contains this data, and invalidates cache on such event (so cache will be rebuilt next time it accessed).
There is a great variety of cache implementations, or you can use simple map for this.
I'm developing a RESTful web service using Jersey and I'm going to be using a simple object cache that is updating it's data by retrieving records from a database based on a timer. I plan on using a HashMap to store my retrieved data in this cache but my question is what is the best practice for updating this HashMap.
Right now my choices are making the HashMap volatile and anytime an update comes in, create a new HashMap and then assign it when it completes. I could also wrap the HashMap in a synchronized block or use a ReentrantReadWriteLock while updating the HashMap variable directly. I have also thought about using ConcurrentHashMap which seems to have some performance benefits. Are there any significant performance differences and/or drawbacks in using one of these approaches over the other?
Also, when a user updates or inserts a record through my web service API, is it best practice to update the local cache directly once I save the record in the DB or force the cache to do another big data retrieval?
Instead of a HashMap, consider using Guava's cache, which is much more configurable and documents your intention to cache data. Read this example.
Use ConcurrentLinkedHasHMap , it uses LIRS algorithm.
ConcurrentLinkedHashMap implementation is a tweaked version of the ConcurrentHashMap implementation originally coded by Doug Lea and found on OpenJDK 1.6.0_0. We present a concurrent hash map and linked list implementation of the ConcurrentMap interface, with predictable iteration order. This implementation differs from ConcurrentHashMap in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order). Note that insertion order is not affected if a key is re-inserted into the map.
I want to implement a cache using Guava's caching mechanism.
I have a DB query which returns a map, I want to cache the entire map but let it expire after a certain amount of time.
I realize Guava caches works as a per-item bases. We provide a key, the Cache will either returns the corresponding value from the cache or get it.
Is there a way to use Guava to get everything, cache it but timeout it after a certain time period of time and get everything again.
Many thanks
You can create an instance of Supplier<Map<K,V>> that fetches the entire map from the database, and then use Suppliers.memoizeWithExpiration to cache it.
Related:
Google Guava Supplier Example
http://google.github.io/guava/releases/snapshot/api/docs/com/google/common/base/Supplier.html
http://google.github.io/guava/releases/snapshot/api/docs/com/google/common/base/Suppliers.html
I am currently using a ConcurrentHashMap in my application but I need to add the ability to expire entries after a timeout period efficiently (expireAfterWrite) and notify a removal listener whenever an entry is removed.
I see that CacheBuilder can provide what I need but I am hesitant to use it because my need is for a map, not a cache. I say this (difference between map and cache) because the guava cache documenatation says this
Generally, the Guava caching utilities are applicable whenever:
You are willing to spend some memory to improve speed.
You expect that keys will sometimes get queried more than once.
Your application would, in principle, work if every value was evicted from the cache immediately -- but you're trying to reduce
duplicated work.
Specifically the thrid bullet point is not okay in my application. I am storing values in the map/cache that I want to retrieve later (until its expiration). Also my keys generally get queried only one or two times, not many times to see caching benefits. So you see my requirement is for a map, not a cache in a sense. Is it still a good idea to use CacheBuilder as a map to store values that will expireAfterWrite and provide removalListener capability? Anybody know enough about the internals of CacheBuilder implementation to offer advice?
EDIT: Of course MapMaker caching features are deprecated in favor of CacheBuilder, my bad. Don't hesitate to use it:
Cache<Key, Graph> graphs = CacheBuilder.newBuilder()
.concurrencyLevel(4) // read docs for more details
.expireAfterWrite(yourExpireTime, TimeUnit.MINUTES)
.build();
and then use Cache#asMap() if you want it's view as ConcurrentMap.
Use another utility from Guava - MapMaker. From docs:
A builder of ConcurrentMap instances having any combination of the
following features:
keys or values automatically wrapped in weak or soft references
least-recently-used eviction when a maximum size is exceeded
time-based expiration of entries, measured since last access or last write
notification of evicted (or otherwise removed) entries
on-demand computation of values for keys not already present
(...)
The returned map is implemented as a hash table with similar
performance characteristics to ConcurrentHashMap. It supports all
optional operations of the ConcurrentMap interface. It does not permit
null keys or values.
How would one return all the values stored within the memcache?
I have tried using entrySet() and values() methods on the cache but both result in an java.lang.UnsupportedOperationException.
Ideally, I need to return all the entities stored within the cache and bulk save them to the datastore - is this possible?
Thanks
Given the MemcacheService low-level documentation, I don't think it's possible to do so.
This is also supported by the JCache Features Not Supported section of the docs:
An app cannot dump the contents of the cache's keys or values.
(Note: I work for Google. but please don't take this as a response from Google. I haven't used AppEngine much myself.)