/* * Copyright (2005-2012) Schibsted ASA * This file is part of Possom. * * Possom is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Possom is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Possom. If not, see <http://www.gnu.org/licenses/>. */ package no.sesat.search.query.parser; import java.lang.ref.Reference; import java.util.concurrent.ConcurrentHashMap; import java.util.Map; import java.util.Set; import no.sesat.commons.ref.ReferenceMap; import no.sesat.search.query.PhraseClause; import no.sesat.search.query.token.TokenEvaluationEngine; import no.sesat.search.query.token.TokenPredicate; import no.sesat.search.site.Site; /** * * * * @version $Id$ */ public final class PhraseClauseImpl extends AbstractLeafClause implements PhraseClause { private static final int WEAK_CACHE_INITIAL_CAPACITY = 2000; private static final float WEAK_CACHE_LOAD_FACTOR = 0.5f; private static final int WEAK_CACHE_CONCURRENCY_LEVEL = 16; /** Values are WeakReference object to AbstractClause. * Unsynchronized are there are no 'changing values', just existance or not of the AbstractClause in the system. */ private static final Map<Site,ReferenceMap<String,PhraseClauseImpl>> WEAK_CACHE = new ConcurrentHashMap<Site,ReferenceMap<String,PhraseClauseImpl>>(); /** * Creator method for PhraseClauseImpl objects. By avoiding the constructors, * and assuming all PhraseClauseImpl objects are immutable, we can keep track * (via a weak reference map) of instances already in use in this JVM and reuse * them. * The methods also allow a chunk of creation logic for the PhraseClauseImpl to be moved * out of the QueryParserImpl.jj file to here. * * * @param term the term this clause represents. * @param field any field this clause was specified against. * @param engine the factory handing out evaluators against TokenPredicates. * Also holds state information about the current term/clause we are finding predicates against. * @return returns a PhraseClauseImpl instance matching the term, left and right child clauses. * May be either newly created or reused. */ public static PhraseClauseImpl createPhraseClause( final String term, final String field, final TokenEvaluationEngine engine) { // the weakCache to use. ReferenceMap<String,PhraseClauseImpl> weakCache = WEAK_CACHE.get(engine.getSite()); if( weakCache == null ){ weakCache = new ReferenceMap<String,PhraseClauseImpl>( DFAULT_REFERENCE_MAP_TYPE, new ConcurrentHashMap<String,Reference<PhraseClauseImpl>>( WEAK_CACHE_INITIAL_CAPACITY, WEAK_CACHE_LOAD_FACTOR, WEAK_CACHE_CONCURRENCY_LEVEL)); WEAK_CACHE.put(engine.getSite(),weakCache); } // use helper method from AbstractLeafClause return createClause( PhraseClauseImpl.class, term, field, engine, weakCache); } /** * Create clause with the given term, known and possible predicates. * @param term the term (query string) for this clause. * @param field the field for this clause. <b>May be <code>null</code></b>. * @param knownPredicates the set of known predicates for this clause. * @param possiblePredicates the set of possible predicates for this clause. */ protected PhraseClauseImpl( final String term, final String field, final Set<TokenPredicate> knownPredicates, final Set<TokenPredicate> possiblePredicates) { super(term, field, knownPredicates, possiblePredicates); } }