blob: d23311fcdb96bf4e63337bf2ad05415d1e4b219b [file] [log] [blame]
/*
* 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.openjpa.kernel;
import java.util.List;
import java.util.Map;
import org.apache.openjpa.lib.conf.Configurable;
/**
* A cache to create and maintain {@link PreparedQuery prepared queries}.
*
* To cache a PreparedQuery is two-stage process. In the first stage,
* {@link #register(String, Query, FetchConfiguration)} register}
* an identification key and a compiled Query Q to create a
* hollow PreparedQuery instance P in the cache. In the second stage, after Q
* executes, {@link #initialize(String, Object)} initialize} the hollow
* Prepared Query P from the result of execution such as the target
* database query PQ and its parameters. After initialization, P can
* be used with re-parameterization for subsequent execution of the original
* Query Q.
*
* The target database query PQ associated to a cached prepared query P
* <em>may</em> depend upon query execution context such as fetch plan or
* lock group. This cache, by design, does not monitor the context or
* automatically invalidate an entry P when the original query Q is executed
* with context parameters that affect the target query PQ.
*
* The user must notify this receiver to invalidate a cached entry P when
* execution context changes in a way that will modify the resultant database
* language query PQ.
*
* One of the built-in mechanism (available in JPA facade) is to set query hints
* to either invalidate the query entirely or ignore the cached version for the
* current execution.
*
* @see QueryHints#HINT_IGNORE_PREPARED_QUERY
* @see QueryHints#HINT_INVALIDATE_PREPARED_QUERY
*
* This cache allows customization of whether a query can be cached or not
* via either explicit marking of certain keys as non-cachable (which is
* irreversible or <em>strong</em>) or addition/removal of exclusion patterns
* (which is reversible or <em>weak</em>).
*
* @see #markUncachable(String)
* @see #addExclusionPattern(String)
* @see #setExcludes(String)
* @see #removeExclusionPattern(String)
*
* @author Pinaki Poddar
*
* @since 2.0.0
*/
public interface PreparedQueryCache extends Configurable {
/**
* Register the given query for caching against the given key if it has not
* already been cached. If the query can not be cached, then mark it as such
* to avoid computing for the same key again.
*
* @return TRUE the query is registered in the cache by this call
* null if the query is already registered in the cache
* FALSE if can not be registered in the cache, either because
* it is known not to be cacheable from a previous attempt or
* a hint is given to ignore the cached version.
*/
Boolean register(String key, Query query, FetchConfiguration hints);
/**
* Initialize the cached Prepared Query registered with the given
* key earlier by the given execution result. If it is not possible to
* initialize the Prepared Query from the given execution result, then
* the corresponding key will be marked as invalid for caching.
*
* @param key the key used during registration
* @param executionResult an opaque instance carrying the execution result
* of the original query.
*
* @return the initialized Prepared Query. If it is not possible to
* initialize the cached, possibly hollow Prepared Query from the given
* result, return null.
*/
PreparedQuery initialize(String key, Object executionResult);
/**
* Get a map view of the cached queries indexed by identifier.
*/
Map<String, String> getMapView();
/**
* Cache the given PreparedQuery.
* The key is the identifier of the given PreparedQuery itself.
* The query must not be cached if either the key matches any exclusion
* pattern or the key has been marked non-cachable.
*
* @return true if the given query is cached. false if it can not be cached
* due to exclusion.
*
* @see #markUncachable(String)
* @see #setExcludes(String)
* @see #addExclusionPattern(String)
*/
boolean cache(PreparedQuery q);
/**
* Remove the PreparedQuery with the given identifier from this cache.
*/
boolean invalidate(String id);
/**
* Get the PreparedQuery with the given identifier if it exists. null
* otherwise.
*/
PreparedQuery get(String id);
/**
* Affirms if a PreparedQuery can be cached against the given key.
*
* @return Boolean.FALSE if the given key is explicitly marked before as not
* be cached or matches any of the exclusion patterns.
* Boolean.TRUE if the given key currently exists in the cache.
* Otherwise, return null implying this receiver can not determine whether
* this key can be cached on not.
*
*/
Boolean isCachable(String id);
/**
* Marks the given key as not amenable to caching.
* Explicit marking helps to avoid repeated computational cost of
* determining whether a query can be cached or not.
*
* @param id is the key to be excluded
* @param exclusion directs whether exclusion is irreversible or not.
*
* @return The value for the given key if it had been cached before. null
* otherwise.
*/
PreparedQuery markUncachable(String id, Exclusion exclusion);
/**
* Returns the exclusion status of if the given query key.
*
* @return null implies that the key is not excluded.
*/
Exclusion isExcluded(String id);
/**
* Gets the exclusion patterns.
*/
List<Exclusion> getExcludes();
/**
* Sets one or more exclusion regular expression patterns separated by
* semicolon. Any existing cache entry whose key matches any of the given
* pattern will be marked non-cachable in a reversible manner.
*/
void setExcludes(String excludes);
/**
* Adds the given pattern to the list of excluded patterns. Any existing
* cache entry whose key matches the given pattern will be marked
* non-cachable in a reversible manner.
*/
void addExclusionPattern(String pattern);
/**
* Removes the given pattern from the list of excluded patterns.
* Any excluded key that matches the given pattern can now be cached
* again, unless it has been marked non-cachable explicitly.
*
* @see #markUncachable(String, Exclusion)
*/
void removeExclusionPattern(String pattern);
/**
* Clears all cached queries.
*/
void clear();
/**
* Enable/disable gathering of statistics.
*
*/
void setEnableStatistics(boolean enable);
/**
* Affirm if statistics is gathered.
*
*/
boolean getEnableStatistics();
/**
* Gets the simple statistics for executed queries.
* If the statistics gathering is disabled, an empty statistics is returned.
*/
QueryStatistics<String> getStatistics();
/**
* A structure to describe the strength and reason for excluding a query from the cache.
*
*/
public interface Exclusion {
/**
* Affirms if this exclusion is strong i.e. can never be reversed.
*/
boolean isStrong();
/**
* Gets the human-readable reason for excluding this query from being cached.
*/
String getReason();
/**
* The pattern (either the exact query string or a regular expression) that
* denotes this exclusion.
*/
String getPattern();
/**
* Affirms if this exclusion matches the given identifier.
*/
boolean matches(String id);
}
}