001/* 002 * Copyright 2019 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.core.cache; 017 018import java.util.HashMap; 019import java.util.Map; 020import java.util.function.Function; 021 022import org.slf4j.Logger; 023 024import org.ametys.core.cache.AbstractCacheManager.CacheType; 025import org.ametys.plugins.core.impl.cache.AbstractCacheKey; 026import org.ametys.runtime.i18n.I18nizableText; 027 028/** 029 * A cache represents a store of objects indexed with a key 030 * @param <K> the type of the keys in cache 031 * @param <V> the type of the values in cache 032 */ 033public interface Cache<K, V> 034{ 035 /** 036 * Returns the value associated with {@code key} in this cache if it exist, 037 * obtaining that value from given function if necessary and store it. 038 * @param key the key to get the element 039 * @param function the function to compute the value if key is not present 040 * @return V the value associated with key 041 * @throws CacheException throw CacheException if the key is null or invalid, or if failed to compute the new value 042 */ 043 public V get(K key, Function<K, V> function) throws CacheException; 044 045 /** 046 * Returns the value associated with {@code key} in this cache if it exist 047 * @param key the key to get the element 048 * @return V the value linked to key 049 */ 050 public V get(K key); 051 052 /** 053 * Get the cache as a simple Map, filtered by filled values of the cache key 054 * @param key the key to get the element. 055 * @return the Map<K, V> representing the cache 056 */ 057 public Map<K, V> getAll(AbstractCacheKey key); 058 059 /** 060 * Associates {@code value} with {@code key} in this cache. If the cache 061 * previously contained a value associated with {@code key}, the old value 062 * is replaced by {@code value}. The {@code key} can not be null. 063 * @param key the key to get the element 064 * @param value the value associated with key 065 */ 066 public void put(K key, V value); 067 068 /** 069 * Copies all of the mappings from the specified map to the cache. 070 * @param map map of key/values to be stored in the cache 071 */ 072 public void putAll(Map<K, V> map); 073 074 /** 075 * return true if key is present in cache 076 * @param key the key to be checked 077 * @return true if key is present in cache 078 */ 079 public boolean hasKey(K key); 080 081 /** 082 * Discards any cached value for key {@code key}. 083 * @param key the key to invalidate 084 */ 085 public void invalidate(K key); 086 087 /** 088 * Discards all entries in the cache, without reseting statistics 089 */ 090 public void invalidateAll(); 091 092 /** 093 * Create or reset the whole cache (including statistics).<br> 094 * The CACHE_RESET event is not notified by this method, but should be by callers. 095 */ 096 public void resetCache(); 097 098 /** 099 * Get all statistics about cache 100 * @return statistic about the cache (hit, miss, evictions...) 101 */ 102 public CacheStats getCacheStats(); 103 104 /** 105 * Get the size the cache take in bytes 106 * @return the size of the cache if it's computable, return 0 otherwise 107 * @throws CacheException throw CacheException if memory size can not be computed 108 */ 109 public long getMemorySize() throws CacheException; 110 111 /** 112 * Get the max size allocated to the cache, in bytes. 113 * This value can be set to Long.MAX_VALUE for infinite cache 114 * @return the max size allocated to the cache 115 */ 116 public long getMaxSize(); 117 118 /** 119 * Get the number of values in cache 120 * @return the number of values in cache 121 */ 122 public long getNumberOfElements(); 123 124 /** 125 * Get the label of cache 126 * @return the label of cache 127 */ 128 public I18nizableText getLabel(); 129 130 /** 131 * Get the description of cache 132 * @return the description of cache 133 */ 134 public I18nizableText getDescription(); 135 136 /** 137 * Get the id of cache 138 * @return the id of cache 139 */ 140 public String getId(); 141 142 /** 143 * Is this cache size computable 144 * @return true if the cache size is computable 145 */ 146 public boolean isComputableSize(); 147 148 /** 149 * Get the cache as a simple Map 150 * @return the Map<K, V> representing the cache 151 */ 152 public Map<K, V> asMap(); 153 154 /** 155 * Get the definition in JSON Map 156 * @param logger Logger to log an error when the size cannot be computed 157 * @return the JSON for the cache 158 */ 159 public default Map<String, Object> toJSONMap(Logger logger) 160 { 161 Map<String, Object> properties = new HashMap<>(); 162 properties.put("id", this.getId()); 163 properties.put("label", this.getLabel()); 164 properties.put("description", this.getDescription()); 165 properties.put("computableSize", this.isComputableSize()); 166 properties.put("access", this.getCacheStats().requestCount()); 167 properties.put("hit", this.getCacheStats().hitCount()); 168 properties.put("hitRate", this.getCacheStats().hitRate()); 169 properties.put("miss", this.getCacheStats().missCount()); 170 properties.put("missRate", this.getCacheStats().missRate()); 171 properties.put("nbElement", this.getNumberOfElements()); 172 properties.put("nbEviction", this.getCacheStats().evictionCount()); 173 properties.put("type", CacheType.MEMORY); 174 try 175 { 176 properties.put("currentSize", this.getMemorySize()); 177 } 178 catch (CacheException e) 179 { 180 logger.error("Unable to compute size of cache: {} - {}", this.getId(), this.getLabel(), e); 181 properties.put("currentSize", -1); 182 } 183 properties.put("maxSize", this.getMaxSize()); 184 return properties; 185 } 186 187 /** 188 * Is this cache filled at least once. 189 * @return true if the cache have been filled (put or putAll have been called even without values), 190 * false when the cache is new, reseted or if all values have been cleaned 191 */ 192 public boolean isInitialized(); 193 194 /** 195 * Can the cache be transmitted in sub-requests of DispatchGenerator 196 * @return true if the cache can be transmitted in sub-requests of DispatchGenerator 197 */ 198 public boolean isDispatchable(); 199}