public QueryExecutor<S> executor(Filter<S> filter, OrderingList<S> ordering, QueryHints hints)
        throws RepositoryException
    {
        final Key<S> key = new Key<S>(filter, ordering, hints);

        synchronized (mPrimaryCache) {
            QueryExecutor<S> executor = mPrimaryCache.get(key);
            if (executor != null) {
                return executor;
            }
        }

        // Fallback to second level cache, which may still have the executor because
        // garbage collection has not reclaimed it yet. It also allows some concurrent
        // executor creation, by using filter-specific locks.

        SoftValuedCache<Object, QueryExecutor<S>> cache;
        synchronized (mFilterToExecutor) {
            cache = mFilterToExecutor.get(filter);
            if (cache == null) {
                cache = SoftValuedCache.newCache(7);
                mFilterToExecutor.put(filter, cache);
            }
        }

        Object subKey;
        if (hints == null || hints.isEmpty()) {
            subKey = ordering;
        } else {
            // Don't construct key with filter. It is not needed here and it would prevent
            // garbage collection of filters.
            subKey = new Key(null, ordering, hints);
        }

        QueryExecutor<S> executor;
        synchronized (cache) {
            executor = cache.get(subKey);
            if (executor == null) {
                executor = mFactory.executor(filter, ordering, hints);
                cache.put(subKey, executor);
            }
        }

        synchronized (mPrimaryCache) {
            mPrimaryCache.put(key, executor);
        }

        return executor;
    }
public QueryExecutor < S > executor ( Filter < S > filter , OrderingList < S > ordering , QueryHints hints ) throws RepositoryException { final Key < S > key = new Key < S > ( filter , ordering , hints ) ; synchronized ( mPrimaryCache ) { QueryExecutor < S > executor = mPrimaryCache . get ( key ) ; if ( executor != null ) { return executor ; } } SoftValuedCache < Object , QueryExecutor < S > > cache ; synchronized ( mFilterToExecutor ) { cache = mFilterToExecutor . get ( filter ) ; if ( cache == null ) { cache = SoftValuedCache . newCache ( 7 ) ; mFilterToExecutor . put ( filter , cache ) ; } } Object subKey ; if ( hints == null || hints . isEmpty ( ) ) { subKey = ordering ; } else { subKey = new Key ( null , ordering , hints ) ; } QueryExecutor < S > executor ; synchronized ( cache ) { executor = cache . get ( subKey ) ; if ( executor == null ) { executor = mFactory . executor ( filter , ordering , hints ) ; cache . put ( subKey , executor ) ; } } synchronized ( mPrimaryCache ) { mPrimaryCache . put ( key , executor ) ; } return executor ; }
Returns an executor from the cache.

@param filter optional filter
@param ordering optional order-by properties
@param hints optional query hints