publicclassRedissonShiroCache<K,V>implementsCache<K,V>{privateRMapCache<K,Object> mapCache;privatefinalRMap<K,Object> map;privateCacheConfig config;privatefinalboolean allowNullValues;privatefinalAtomicLong hits =newAtomicLong();privatefinalAtomicLong misses =newAtomicLong();publicRedissonShiroCache(RMapCache<K,Object> mapCache,CacheConfig config,boolean allowNullValues){this.mapCache = mapCache;this.map = mapCache;this.config = config;this.allowNullValues = allowNullValues;}publicRedissonShiroCache(RMap<K,Object> map,boolean allowNullValues){this.map = map;this.allowNullValues = allowNullValues;}@OverridepublicVget(K key)throwsCacheException{Object value =this.map.get(key);if(value ==null){addCacheMiss();}else{addCacheHit();}returnfromStoreValue(value);}@OverridepublicVput(K key,V value)throwsCacheException{Object previous;if(!allowNullValues && value ==null){if(mapCache !=null){previous = mapCache.remove(key);}else{previous = map.remove(key);}returnfromStoreValue(previous);}Object val =toStoreValue(value);if(mapCache !=null){previous = mapCache.put(key, val, config.getTTL(),TimeUnit.MILLISECONDS,config.getMaxIdleTime(),TimeUnit.MILLISECONDS);}else{previous = map.put(key, val);}returnfromStoreValue(previous);}publicvoidfastPut(K key,V value)throwsCacheException{if(!allowNullValues && value ==null){if(mapCache !=null){mapCache.fastRemove(key);}else{map.fastRemove(key);}return;}Object val =toStoreValue(value);if(mapCache !=null){mapCache.fastPut(key, val, config.getTTL(),TimeUnit.MILLISECONDS,config.getMaxIdleTime(),TimeUnit.MILLISECONDS);}else{map.fastPut(key, val);}}publicVputIfAbsent(K key,V value)throwsCacheException{Object previous;if(!allowNullValues && value ==null){if(mapCache !=null){previous = mapCache.get(key);}else{previous = map.get(key);}returnfromStoreValue(previous);}Object val =toStoreValue(value);if(mapCache !=null){previous = mapCache.putIfAbsent(key, val, config.getTTL(),TimeUnit.MILLISECONDS,config.getMaxIdleTime(),TimeUnit.MILLISECONDS);}else{previous = map.putIfAbsent(key, val);}returnfromStoreValue(previous);}publicbooleanfastPutIfAbsent(K key,V value)throwsCacheException{if(!allowNullValues && value ==null){returnfalse;}Object val =toStoreValue(value);if(mapCache !=null){return mapCache.fastPutIfAbsent(key, val, config.getTTL(),TimeUnit.MILLISECONDS,config.getMaxIdleTime(),TimeUnit.MILLISECONDS);}else{return map.fastPutIfAbsent(key, val);}}@OverridepublicVremove(K key)throwsCacheException{Object previous =this.map.remove(key);returnfromStoreValue(previous);}publiclongfastRemove(K... keys){returnthis.map.fastRemove(keys);}@Overridepublicvoidclear()throwsCacheException{this.map.clear();}@Overridepublicintsize(){returnthis.map.size();}@OverridepublicSet<K>keys(){returnthis.map.readAllKeySet();}@OverridepublicCollection<V>values(){Collection<Object> innerValues =this.map.readAllValues();Collection<V> res =newArrayList<>(innerValues.size());for(Object val : innerValues){res.add(fromStoreValue(val));}return res;}protectedVfromStoreValue(Object storeValue){if(storeValue instanceofNullValue){returnnull;}return(V) storeValue;}protectedObjecttoStoreValue(V userValue){if(userValue ==null){returnNullValue.INSTANCE;}return userValue;}/** The number of get requests that were satisfied by the cache.* @return the number of hits*/longgetCacheHits(){returnthis.hits.get();}/** A miss is a get request that is not satisfied.* @return the number of misses*/longgetCacheMisses(){returnthis.misses.get();}privatevoidaddCacheHit(){this.hits.incrementAndGet();}privatevoidaddCacheMiss(){this.misses.incrementAndGet();}}