| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.solr.search; |
| |
| import org.apache.solr.core.SolrInfoBean; |
| import org.apache.solr.metrics.SolrMetricProducer; |
| import org.apache.solr.util.IOFunction; |
| |
| import java.io.IOException; |
| import java.util.Map; |
| import java.util.function.Function; |
| |
| |
| /** |
| * Primary API for dealing with Solr's internal caches. |
| */ |
| public interface SolrCache<K,V> extends SolrInfoBean, SolrMetricProducer { |
| |
| String HIT_RATIO_PARAM = "hitratio"; |
| String HITS_PARAM = "hits"; |
| String INSERTS_PARAM = "inserts"; |
| String EVICTIONS_PARAM = "evictions"; |
| String LOOKUPS_PARAM = "lookups"; |
| String SIZE_PARAM = "size"; |
| String MAX_SIZE_PARAM = "maxSize"; |
| String RAM_BYTES_USED_PARAM = "ramBytesUsed"; |
| String MAX_RAM_MB_PARAM = "maxRamMB"; |
| String MAX_IDLE_TIME_PARAM = "maxIdleTime"; |
| String INITIAL_SIZE_PARAM = "initialSize"; |
| String CLEANUP_THREAD_PARAM = "cleanupThread"; |
| String SHOW_ITEMS_PARAM = "showItems"; |
| String ASYNC_PARAM = "async"; |
| |
| /** |
| * The initialization routine. Instance specific arguments are passed in |
| * the <code>args</code> map. |
| * <p> |
| * The persistence object will exist across different lifetimes of similar caches. |
| * For example, all filter caches will share the same persistence object, sometimes |
| * at the same time (it must be thread-safe). If null is passed, then the cache |
| * implementation should create and return a new persistence object. If not null, |
| * the passed in object should be returned again. |
| * <p> |
| * Since it will exist across the lifetime of many caches, care should be taken to |
| * not reference any particular cache instance and prevent it from being |
| * garbage collected (no using inner classes unless they are static). |
| * <p> |
| * The persistence object is designed to be used as a way for statistics |
| * to accumulate across all instances of the same type of cache, however the |
| * object may be of any type desired by the cache implementation. |
| * <p> |
| * The {@link CacheRegenerator} is what the cache uses during auto-warming to |
| * regenerate an item in the new cache from an entry in the old cache. |
| * |
| */ |
| public Object init(@SuppressWarnings({"rawtypes"})Map args, Object persistence, CacheRegenerator regenerator); |
| // I don't think we need a factory for faster creation given that these |
| // will be associated with slow-to-create SolrIndexSearchers. |
| // change to NamedList when other plugins do? |
| |
| /** |
| * Name the Cache can be referenced with by SolrRequestHandlers. |
| * |
| * This method must return the identifier that the Cache instance |
| * expects SolrRequestHandlers to use when requesting access to it |
| * from the SolrIndexSearcher. It is <strong>strongly</strong> |
| * recommended that this method return the value of the "name" |
| * parameter from the init args. |
| * |
| * :TODO: verify this. |
| */ |
| public String name(); |
| |
| |
| // Should SolrCache just extend the java.util.Map interface? |
| // Following the conventions of the java.util.Map interface in any case. |
| |
| /** :TODO: copy from Map */ |
| public int size(); |
| |
| /** :TODO: copy from Map */ |
| public V put(K key, V value); |
| |
| /** :TODO: copy from Map */ |
| public V get(K key); |
| |
| public V remove(K key); |
| |
| /** |
| * Get an existing element or atomically compute it if missing. |
| * @param key key |
| * @param mappingFunction function to compute the element. If the function returns a null |
| * result the cache mapping will not be created. NOTE: this function |
| * must NOT attempt to modify any mappings in the cache. |
| * @return existing or newly computed value, null if there was no existing value and |
| * it was not possible to compute a new value (in which case the new mapping won't be created). |
| * @throws IOException if and only if mappingFunction threw an IOException. |
| * A cache mapping will not be created in this case |
| */ |
| V computeIfAbsent(K key, IOFunction<? super K, ? extends V> mappingFunction) throws IOException; |
| |
| /** :TODO: copy from Map */ |
| public void clear(); |
| |
| /** |
| * Enumeration of possible States for cache instances. |
| * :TODO: only state that seems to ever be set is LIVE ? |
| */ |
| public enum State { |
| /** :TODO */ |
| CREATED, |
| /** :TODO */ |
| STATICWARMING, |
| /** :TODO */ |
| AUTOWARMING, |
| /** :TODO */ |
| LIVE |
| } |
| |
| /** |
| * Set different cache states. |
| * The state a cache is in can have an effect on how statistics are kept. |
| * The cache user (SolrIndexSearcher) will take care of switching |
| * cache states. |
| */ |
| public void setState(State state); |
| |
| /** |
| * Returns the last State set on this instance |
| * |
| * @see #setState |
| */ |
| public State getState(); |
| |
| /** |
| * Warm this cache associated with <code>searcher</code> using the <code>old</code> |
| * cache object. <code>this</code> and <code>old</code> will have the same concrete type. |
| */ |
| void warm(SolrIndexSearcher searcher, SolrCache<K,V> old); |
| // Q: an alternative to passing the searcher here would be to pass it in |
| // init and have the cache implementation save it. |
| |
| |
| /** Frees any non-memory resources */ |
| default void close() throws IOException { |
| SolrMetricProducer.super.close(); |
| } |
| |
| /** Returns maximum size limit (number of items) if set and supported, -1 otherwise. */ |
| int getMaxSize(); |
| |
| /** Set maximum size limit (number of items), or -1 for unlimited. Note: this has effect |
| * only on implementations that support it, it's a no-op otherwise |
| */ |
| void setMaxSize(int maxSize); |
| |
| /** Returns maximum size limit (in MB) if set and supported, -1 otherwise. */ |
| int getMaxRamMB(); |
| |
| /** Set maximum size limit (in MB), or -1 for unlimited. Note: this has effect |
| * only on implementations that support it, it's a no-op otherwise. |
| */ |
| void setMaxRamMB(int maxRamMB); |
| |
| /** |
| * Check if this SolrCache supports recursive calls to {@link #computeIfAbsent(Object, IOFunction)}. |
| * Caches backed by {@link java.util.concurrent.ConcurrentHashMap#computeIfAbsent(Object, Function)} explicitly do |
| * not support that, but other caches might. |
| * @return whether this cache allows recursive computations |
| */ |
| default boolean isRecursionSupported() { |
| return false; |
| } |
| } |