Cache key organization problem
My entity has two unique ids (yes this is wrong but it is a requirement). I want to organize a cache of such instances. The search in cache could be made by id1 OR id2 OR id1 and id2. Search by both id1 and id2 is ok - I will make composite key. But how to deal with just search by one of ids. What should be the cache key? I'm using ehcache.
I have a situation where several key may refer the same object.
Like ehcache does not suport this feature, the same object will be stored for each key (n instances of the same object, where n is the number of diferent keys that that object m开发者_如何学Goay be refered from).
At some point i have the knowledge to calculate the other keys, but not before i need them.
Situation :
GEN KEY (1) Check if object is in cache (2) TRUE : Retreve it
FALSE : Process the new object (3) Place it in ehcache return OBJECT
At point (1) just know one of the keys. At the point (3) there is the possibility to know all keys that the object may have associated to it in ehcache. The problem is that the keys are needed at point (2).
Thx
One option would be to use two Maps. One for each id set, but both would point to the same set of values.
If the search is on id1 just lookup the value in the first map, if on id2, just lookup in the second map. If you need to search both, lookup both values and see if the values are identical.
Updated based on updates to your question and comments below: Use both keys in your ecache. Yes this will take up more space and there might be times that the object you are looking for is already in the cache under the other key. However, the cache should store common looked up keys. It should not care that the value might exist under another key. So I would not stress yourself with trying to optimize your cache to lookup based on two keys.
I can't tell for ehcache, but I've been having a similar problem for HashMap
used as cache. I simply put each value twice in the Map, it's not that expensive and it worked well.
Because of my keys being of different types, I used Map<Object, V>
.
To accomplish what you want you can do it by transitivity storing not only the object in the cache, but storing also the index that points to your object using each of the keys.
e.g.:
cache["key1"]=theIndex;
cache["key2"]=theIndex;
cache[theIndex]=object;
So, when you request for cache["key1"] you'd get an index (you have to know it's an index), and then get the actual object using that index.
The code could go something like:
public class CacheUtil {
... any necessary code here
public static void put(String key, Serializable obj) {
if (obj instance of Cacheable) {
//Cacheable interface identifies the cacheable object that has the getKeys method
String[] keys = obj.getKeys();
if (keys != null && keys.length > 0) {
for (String myKey : keys) {
//CacheIndex identifies the index
cache.put(new Element(myKey, new CacheIndex(hashCode)));
}
key = hashCode(keys); //change the key. Can be a hashcode of the keys
}
}
cache.put(new Element(key, obj));
}
public static Serializable get(String key) {
Serializable obj = cache.get(key);
return ((null != serializable) && (serializable instanceof CacheIndex)) ?
get(((CacheIndex)serializable).getIndex(), area) : obj;
}
}
精彩评论