Author: ssmiweve
Date: 2008-09-16 14:47:51 +0200 (Tue, 16 Sep 2008)
New Revision: 6815
Modified:
trunk/core-api/src/main/java/no/sesat/search/http/servlet/FactoryReloads.java
trunk/core-api/src/test/java/no/sesat/search/http/servlet/FactoryReloadsTest.java
trunk/generic.sesam/query-evaluation/src/main/java/no/sesat/search/query/token/JepEvaluatorFactory.java
trunk/generic.sesam/query-evaluation/src/main/java/no/sesat/search/query/token/RegExpEvaluatorFactory.java
trunk/generic.sesam/query-evaluation/src/main/java/no/sesat/search/query/token/SolrEvaluatorFactory.java
trunk/generic.sesam/query-evaluation/src/main/java/no/sesat/search/query/token/VeryFastTokenEvaluator.java
trunk/query-api/src/main/java/no/sesat/search/query/token/AbstractEvaluatorFactory.java
Log:
Issue SKER3540: (Token Evaluator SPI)
Modified:
trunk/core-api/src/main/java/no/sesat/search/http/servlet/FactoryReloads.java
===================================================================
---
trunk/core-api/src/main/java/no/sesat/search/http/servlet/FactoryReloads.java
2008-09-16 12:47:10 UTC (rev 6814)
+++
trunk/core-api/src/main/java/no/sesat/search/http/servlet/FactoryReloads.java
2008-09-16 12:47:51 UTC (rev 6815)
@@ -29,7 +29,6 @@
import no.sesat.search.mode.SearchModeFactory;
import no.sesat.search.site.config.SiteConfiguration;
import no.sesat.search.query.analyser.AnalysisRuleFactory;
-import no.sesat.search.query.token.AbstractEvaluatorFactory;
import no.sesat.search.site.Site;
import no.sesat.search.site.SiteContext;
import no.sesat.search.site.SiteKeyedFactory;
@@ -53,7 +52,6 @@
SEARCH_TAB_FACTORY,
SEARCH_MODE_FACTORY,
ANALYSIS_RULES_FACTORY,
- EVALUATOR_FACTORY,
VELOCITY_ENGINE_FACTORY
}
@@ -104,20 +102,6 @@
performReload(site, AnalysisRuleFactory.instanceOf(
ContextWrapper.wrap(AnalysisRuleFactory.Context.class,
genericCxt)));
- case EVALUATOR_FACTORY:
-
- int cleaned = 0;
- for(Locale l : Locale.getAvailableLocales()){
- final Site s = Site.valueOf(null, site.getName(), l);
- if(null != s && AbstractEvaluatorFactory.removeAll(s)){
- ++cleaned;
- }
- }
-
- LOG.warn(cleaned + WARN_CLEANED_1 + "AbstractEvaluatorFactory"
+ WARN_CLEANED_2 + site);
-
- if(ReloadArg.ALL != reload){ break;}
-
case VELOCITY_ENGINE_FACTORY:
performReload(site, VelocityEngineFactory.instanceOf(
Modified:
trunk/core-api/src/test/java/no/sesat/search/http/servlet/FactoryReloadsTest.java
===================================================================
---
trunk/core-api/src/test/java/no/sesat/search/http/servlet/FactoryReloadsTest.java
2008-09-16 12:47:10 UTC (rev 6814)
+++
trunk/core-api/src/test/java/no/sesat/search/http/servlet/FactoryReloadsTest.java
2008-09-16 12:47:51 UTC (rev 6815)
@@ -26,7 +26,6 @@
import java.util.Properties;
import javax.xml.parsers.DocumentBuilder;
import no.sesat.search.http.servlet.FactoryReloads.ReloadArg;
-import no.sesat.search.site.SiteTestCase;
import no.sesat.search.site.config.DocumentLoader;
import no.sesat.search.site.config.FileResourceLoader;
import no.sesat.search.site.config.PropertiesLoader;
@@ -58,7 +57,6 @@
FactoryReloads.performReloads(genericContext(),
ReloadArg.SEARCH_TAB_FACTORY);
FactoryReloads.performReloads(genericContext(),
ReloadArg.SEARCH_MODE_FACTORY);
FactoryReloads.performReloads(genericContext(),
ReloadArg.ANALYSIS_RULES_FACTORY);
- FactoryReloads.performReloads(genericContext(),
ReloadArg.EVALUATOR_FACTORY);
// skip "velocity" because VelocityEngineFactory harcodes to
URLVelocityTemplateLoader
}
Modified:
trunk/generic.sesam/query-evaluation/src/main/java/no/sesat/search/query/token/JepEvaluatorFactory.java
===================================================================
---
trunk/generic.sesam/query-evaluation/src/main/java/no/sesat/search/query/token/JepEvaluatorFactory.java
2008-09-16 12:47:10 UTC (rev 6814)
+++
trunk/generic.sesam/query-evaluation/src/main/java/no/sesat/search/query/token/JepEvaluatorFactory.java
2008-09-16 12:47:51 UTC (rev 6815)
@@ -25,6 +25,7 @@
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.xml.parsers.DocumentBuilder;
import no.sesat.search.site.SiteKeyedFactoryInstantiationException;
import org.apache.log4j.Logger;
@@ -50,11 +51,11 @@
private static final String ERR_DOC_BUILDER_CREATION
= "Failed to
DocumentBuilderFactory.newInstance().newDocumentBuilder()";
- private volatile boolean init = false;
-
+ // TODO this will leak when sites are redeploy without Sesat being
restarted.
/** JepTokenEvaluator's to use against the "*" query. Notes which tokens
we're applicable to. **/
- private final Map<TokenPredicate,JepTokenEvaluator> jepEvaluators
- = new HashMap<TokenPredicate,JepTokenEvaluator>();
+ private static final Map<Site,Map<TokenPredicate,JepTokenEvaluator>>
EVALUATORS
+ = new HashMap<Site,Map<TokenPredicate,JepTokenEvaluator>>();
+ private static final ReentrantReadWriteLock EVALUATORS_LOCK = new
ReentrantReadWriteLock();
public JepEvaluatorFactory(final Context cxt)
throws SiteKeyedFactoryInstantiationException {
@@ -62,7 +63,7 @@
super(cxt);
try{
- init();
+ init(cxt);
}catch(ParserConfigurationException pce){
throw new
SiteKeyedFactoryInstantiationException(ERR_DOC_BUILDER_CREATION, pce);
@@ -70,21 +71,49 @@
}
- private void init() throws ParserConfigurationException {
+ private static void init(final Context cxt) throws
ParserConfigurationException {
- if (!init) {
- synchronized(jepEvaluators){
+ final Site site = cxt.getSite();
+ final Site parent = site.getParent();
+ final boolean parentUninitialised;
+
+ try{
+ EVALUATORS_LOCK.readLock().lock();
+
+ // initialise the parent site's configuration
+ parentUninitialised = (null != parent && null ==
EVALUATORS.get(parent));
+
+ }finally{
+ EVALUATORS_LOCK.readLock().unlock();
+ }
+
+ if(parentUninitialised){
+ init(ContextWrapper.wrap(
+ AbstractEvaluatorFactory.Context.class,
+ parent.getSiteContext(),
+ cxt
+ ));
+ }
+
+ try{
+ EVALUATORS_LOCK.writeLock().lock();
+
+ if(null == EVALUATORS.get(site)){
+
+ // create map entry for this site
+ EVALUATORS.put(site, new
HashMap<TokenPredicate,JepTokenEvaluator>());
+
final DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
factory.setValidating(false);
final DocumentBuilder builder = factory.newDocumentBuilder();
- final DocumentLoader loader =
getContext().newDocumentLoader(getContext(), JEP_EVALUATOR_XMLFILE, builder);
+ final DocumentLoader loader = cxt.newDocumentLoader(cxt,
JEP_EVALUATOR_XMLFILE, builder);
loader.abut();
LOG.info("Parsing " + JEP_EVALUATOR_XMLFILE + " started");
final Document doc = loader.getDocument();
- assert null != doc : "No document loaded for " +
getContext().getSite().getName();
+ assert null != doc : "No document loaded for " +
site.getName();
final Element root = doc.getDocumentElement();
if(null != root){
@@ -110,22 +139,33 @@
LOG.info(" ->[EMAIL PROTECTED]: " + queryDep);
final JepTokenEvaluator jepTokenEvaluator = new
JepTokenEvaluator("*", queryDep);
- jepEvaluators.put(token, jepTokenEvaluator);
+ EVALUATORS.get(site).put(token, jepTokenEvaluator);
}
}
LOG.info("Parsing " + JEP_EVALUATOR_XMLFILE + " finished");
- init = true;
}
+ }finally{
+ EVALUATORS_LOCK.writeLock().unlock();
}
}
public TokenEvaluator getEvaluator(final TokenPredicate token) throws
EvaluationException {
+
+ TokenEvaluator result;
final Context cxt = getContext();
- TokenEvaluator result = jepEvaluators.get(token);
- if(result == null && null != cxt.getSite().getParent()){
+ try{
+ EVALUATORS_LOCK.readLock().lock();
+ result = EVALUATORS.get(cxt.getSite()).get(token);
+
+ }finally{
+ EVALUATORS_LOCK.readLock().unlock();
+ }
+
+ if(null == result && null != cxt.getSite().getParent()){
+
result = instanceOf(ContextWrapper.wrap(
Context.class,
cxt.getSite().getParent().getSiteContext(),
@@ -140,6 +180,7 @@
return "*".equals(getContext().getQueryString())
? result
: new JepTokenEvaluator(getContext().getQueryString(),
result.isQueryDependant(token));
+
}
}
Modified:
trunk/generic.sesam/query-evaluation/src/main/java/no/sesat/search/query/token/RegExpEvaluatorFactory.java
===================================================================
---
trunk/generic.sesam/query-evaluation/src/main/java/no/sesat/search/query/token/RegExpEvaluatorFactory.java
2008-09-16 12:47:10 UTC (rev 6814)
+++
trunk/generic.sesam/query-evaluation/src/main/java/no/sesat/search/query/token/RegExpEvaluatorFactory.java
2008-09-16 12:47:51 UTC (rev 6815)
@@ -27,6 +27,7 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
import no.sesat.search.site.SiteKeyedFactoryInstantiationException;
@@ -54,17 +55,17 @@
/** The name of the file where regular expressions for each TokenPredicate
will be configured. **/
public static final String REGEXP_EVALUATOR_XMLFILE =
"RegularExpressionEvaluators.xml";
- private volatile boolean init = false;
+ // TODO this will leak when sites are redeploy without Sesat being
restarted.
+ private static final Map<Site,Map<TokenPredicate,RegExpTokenEvaluator>>
EVALUATORS
+ = new HashMap<Site,Map<TokenPredicate,RegExpTokenEvaluator>>();
+ private static final ReentrantReadWriteLock EVALUATORS_LOCK = new
ReentrantReadWriteLock();
- private final Map<TokenPredicate,RegExpTokenEvaluator> regExpEvaluators
- = new HashMap<TokenPredicate,RegExpTokenEvaluator>();
-
public RegExpEvaluatorFactory(final Context cxt)
throws SiteKeyedFactoryInstantiationException {
super(cxt);
try{
- init();
+ init(cxt);
}catch(ParserConfigurationException pce){
throw new
SiteKeyedFactoryInstantiationException(ERR_DOC_BUILDER_CREATION, pce);
@@ -74,22 +75,49 @@
/** Loads the resource SearchConstants.REGEXP_EVALUATOR_XMLFILE containing
all regular expression patterns
* for all the RegExpTokenEvaluators we will be using.
*/
- private void init() throws ParserConfigurationException {
+ private static void init(final Context cxt) throws
ParserConfigurationException {
- if (!init) {
- synchronized(regExpEvaluators){
+ final Site site = cxt.getSite();
+ final Site parent = site.getParent();
+ final boolean parentUninitialised;
+ try{
+ EVALUATORS_LOCK.readLock().lock();
+
+ // initialise the parent site's configuration
+ parentUninitialised = (null != parent && null ==
EVALUATORS.get(parent));
+
+ }finally{
+ EVALUATORS_LOCK.readLock().unlock();
+ }
+
+ if(parentUninitialised){
+ init(ContextWrapper.wrap(
+ AbstractEvaluatorFactory.Context.class,
+ parent.getSiteContext(),
+ cxt
+ ));
+ }
+
+ try{
+ EVALUATORS_LOCK.writeLock().lock();
+
+ if(null == EVALUATORS.get(site)){
+ // create map entry for this site
+ EVALUATORS.put(site, new
HashMap<TokenPredicate,RegExpTokenEvaluator>());
+
+
final DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
factory.setValidating(false);
final DocumentBuilder builder = factory.newDocumentBuilder();
final DocumentLoader loader
- = getContext().newDocumentLoader(getContext(),
REGEXP_EVALUATOR_XMLFILE, builder);
+ = cxt.newDocumentLoader(cxt, REGEXP_EVALUATOR_XMLFILE,
builder);
loader.abut();
LOG.info("Parsing " + REGEXP_EVALUATOR_XMLFILE + " started");
final Document doc = loader.getDocument();
- assert null != doc : "No document loaded for " +
getContext().getSite().getName();
+ assert null != doc : "No document loaded for " +
site.getName();
final Element root = doc.getDocumentElement();
if(null != root){
@@ -132,21 +160,32 @@
}
final RegExpTokenEvaluator regExpTokenEvaluator = new
RegExpTokenEvaluator(compiled, queryDep);
- regExpEvaluators.put(token, regExpTokenEvaluator);
+ EVALUATORS.get(site).put(token, regExpTokenEvaluator);
}
}
LOG.info("Parsing " + REGEXP_EVALUATOR_XMLFILE + " finished");
- init = true;
}
+
+ }finally{
+ EVALUATORS_LOCK.writeLock().unlock();
}
}
public TokenEvaluator getEvaluator(final TokenPredicate token) throws
EvaluationException {
+ TokenEvaluator result;
final Context cxt = getContext();
- TokenEvaluator result = regExpEvaluators.get(token);
+ try{
+ EVALUATORS_LOCK.readLock().lock();
+
+ result = EVALUATORS.get(cxt.getSite()).get(token);
+
+ }finally{
+ EVALUATORS_LOCK.readLock().unlock();
+ }
+
if(result == null && null != cxt.getSite().getParent()){
result = instanceOf(ContextWrapper.wrap(
Modified:
trunk/generic.sesam/query-evaluation/src/main/java/no/sesat/search/query/token/SolrEvaluatorFactory.java
===================================================================
---
trunk/generic.sesam/query-evaluation/src/main/java/no/sesat/search/query/token/SolrEvaluatorFactory.java
2008-09-16 12:47:10 UTC (rev 6814)
+++
trunk/generic.sesam/query-evaluation/src/main/java/no/sesat/search/query/token/SolrEvaluatorFactory.java
2008-09-16 12:47:51 UTC (rev 6815)
@@ -69,6 +69,7 @@
private SolrTokenEvaluator solrEvaluator;
private SolrServer server;
+ // TODO this will leak when sites are redeploy without Sesat being
restarted.
private static final Map<Site,Map<TokenPredicate,String[]>> LIST_NAMES
= new HashMap<Site,Map<TokenPredicate,String[]>>();
private static final ReentrantReadWriteLock LIST_NAMES_LOCK = new
ReentrantReadWriteLock();
Modified:
trunk/generic.sesam/query-evaluation/src/main/java/no/sesat/search/query/token/VeryFastTokenEvaluator.java
===================================================================
---
trunk/generic.sesam/query-evaluation/src/main/java/no/sesat/search/query/token/VeryFastTokenEvaluator.java
2008-09-16 12:47:10 UTC (rev 6814)
+++
trunk/generic.sesam/query-evaluation/src/main/java/no/sesat/search/query/token/VeryFastTokenEvaluator.java
2008-09-16 12:47:51 UTC (rev 6815)
@@ -89,6 +89,7 @@
/** General properties to regular expressions configured. **/
private static final int REG_EXP_OPTIONS = Pattern.CASE_INSENSITIVE |
Pattern.UNICODE_CASE;
+ // TODO this will leak when sites are redeploy without Sesat being
restarted.
// todo move deserialisation & this map to
FastQueryMatchingEvaluatorFactory
private static final Map<Site,Map<TokenPredicate,String[]>> LIST_NAMES
= new HashMap<Site,Map<TokenPredicate,String[]>>();
Modified:
trunk/query-api/src/main/java/no/sesat/search/query/token/AbstractEvaluatorFactory.java
===================================================================
---
trunk/query-api/src/main/java/no/sesat/search/query/token/AbstractEvaluatorFactory.java
2008-09-16 12:47:10 UTC (rev 6814)
+++
trunk/query-api/src/main/java/no/sesat/search/query/token/AbstractEvaluatorFactory.java
2008-09-16 12:47:51 UTC (rev 6815)
@@ -43,7 +43,7 @@
* SKER3540
* @version $Id$
*/
-public abstract class AbstractEvaluatorFactory implements SiteKeyedFactory {
+public abstract class AbstractEvaluatorFactory{
/**
* The context the RegExpEvaluatorFactory must work against.
@@ -62,11 +62,6 @@
// Constants -----------------------------------------------------
- private static final Map<Site,Map<String,AbstractEvaluatorFactory>>
INSTANCES
- = new HashMap<Site,Map<String,AbstractEvaluatorFactory>>();
-
- private static final ReentrantReadWriteLock INSTANCES_LOCK = new
ReentrantReadWriteLock();
-
private static final Logger LOG =
Logger.getLogger(AbstractEvaluatorFactory.class);
private static final String ERR_MUST_USE_CONTEXT_CONSTRUCTOR = "Must use
constructor that supplies a context!";
@@ -83,72 +78,41 @@
*/
public static final AbstractEvaluatorFactory instanceOf(final Context cxt)
{
- final Site site = cxt.getSite();
final String clsName = cxt.getEvaluatorFactoryClassName();
- checkSiteMapExists(site);
+ // We cannot cache the EvaluatorFactory instances so easily because
each depends on the QueryString.
+ // the cache would then need to be keyed on
Site->FactoryClassName->QueryString
+ // Effective and safe caching becomes difficult when each QueryString
has such a short lifespan.
+ // It is more effective than to let each EvaluatorFactory provide it's
own QueryString caching.
- AbstractEvaluatorFactory instance;
try {
- INSTANCES_LOCK.readLock().lock();
- instance = INSTANCES.get(site).get(clsName);
+ final SiteClassLoaderFactory f =
SiteClassLoaderFactory.instanceOf(createClassLoadingContext(cxt));
- }finally {
- INSTANCES_LOCK.readLock().unlock();
- }
- if (null == instance) {
+ final Class clazz = f.getClassLoader().loadClass(clsName);
- try {
- INSTANCES_LOCK.writeLock().lock();
+ @SuppressWarnings("unchecked")
+ final Constructor<? extends AbstractEvaluatorFactory> s =
clazz.getConstructor(Context.class);
- final SiteClassLoaderFactory f =
SiteClassLoaderFactory.instanceOf(createClassLoadingContext(cxt));
+ return s.newInstance(cxt);
- final Class clazz = f.getClassLoader().loadClass(clsName);
-
- @SuppressWarnings("unchecked")
- final Constructor<? extends AbstractEvaluatorFactory> s =
clazz.getConstructor(Context.class);
-
- instance = s.newInstance(cxt);
- INSTANCES.get(site).put(clsName, instance);
-
- }catch (InstantiationException ex) {
- throw new IllegalArgumentException("Unable to construct
AbstractEvaluatorFactory: " + clsName, ex);
- }catch (IllegalAccessException ex) {
- throw new IllegalArgumentException("Unable to construct
AbstractEvaluatorFactory: " + clsName, ex);
- }catch (IllegalArgumentException ex) {
- throw new IllegalArgumentException("Unable to construct
AbstractEvaluatorFactory: " + clsName, ex);
- }catch (InvocationTargetException ex) {
- throw new IllegalArgumentException("Unable to construct
AbstractEvaluatorFactory: " + clsName, ex);
- }catch (NoSuchMethodException ex) {
- throw new IllegalArgumentException("Unable to construct
AbstractEvaluatorFactory: " + clsName, ex);
- }catch (SecurityException ex) {
- throw new IllegalArgumentException("Unable to construct
AbstractEvaluatorFactory: " + clsName, ex);
- }catch(ClassNotFoundException ex){
- throw new IllegalArgumentException("Unable to construct
AbstractEvaluatorFactory: " + clsName, ex);
- }finally{
- INSTANCES_LOCK.writeLock().unlock();
- }
+ }catch (InstantiationException ex) {
+ throw new IllegalArgumentException("Unable to construct
AbstractEvaluatorFactory: " + clsName, ex);
+ }catch (IllegalAccessException ex) {
+ throw new IllegalArgumentException("Unable to construct
AbstractEvaluatorFactory: " + clsName, ex);
+ }catch (IllegalArgumentException ex) {
+ throw new IllegalArgumentException("Unable to construct
AbstractEvaluatorFactory: " + clsName, ex);
+ }catch (InvocationTargetException ex) {
+ throw new IllegalArgumentException("Unable to construct
AbstractEvaluatorFactory: " + clsName, ex);
+ }catch (NoSuchMethodException ex) {
+ throw new IllegalArgumentException("Unable to construct
AbstractEvaluatorFactory: " + clsName, ex);
+ }catch (SecurityException ex) {
+ throw new IllegalArgumentException("Unable to construct
AbstractEvaluatorFactory: " + clsName, ex);
+ }catch(ClassNotFoundException ex){
+ throw new IllegalArgumentException("Unable to construct
AbstractEvaluatorFactory: " + clsName, ex);
}
- return instance;
}
- /** custom implementation of SiteKeyedFactory.remove that cleans
- * all factory implementations belonging to a site. *
- * @param site
- * @return
- */
- public static boolean removeAll(final Site site) {
-
- try {
- INSTANCES_LOCK.writeLock().lock();
- return null != INSTANCES.remove(site);
- }
- finally {
- INSTANCES_LOCK.writeLock().unlock();
- }
- }
-
// Constructors --------------------------------------------------
/**
@@ -194,19 +158,7 @@
*/
public abstract TokenEvaluator getEvaluator(final TokenPredicate token)
throws EvaluationException;
- public boolean remove(final Site site) {
- final String clsName = context.getEvaluatorFactoryClassName();
-
- try {
- INSTANCES_LOCK.writeLock().lock();
- return null != INSTANCES.get(site).remove(clsName);
- }
- finally {
- INSTANCES_LOCK.writeLock().unlock();
- }
- }
-
// Z implementation ----------------------------------------------
// Y overrides ---------------------------------------------------
@@ -242,29 +194,5 @@
};
}
- private static void checkSiteMapExists(final Site site){
-
- final Map<String,AbstractEvaluatorFactory> factories;
- try {
- INSTANCES_LOCK.readLock().lock();
-
- factories = INSTANCES.get(site);
-
- }finally {
- INSTANCES_LOCK.readLock().unlock();
- }
- if(null == factories){
- try {
- INSTANCES_LOCK.writeLock().lock();
-
- INSTANCES.put(site, new
HashMap<String,AbstractEvaluatorFactory>());
-
- }finally{
- INSTANCES_LOCK.writeLock().unlock();
- }
- }
-
- }
-
// Inner classes -------------------------------------------------
}
_______________________________________________
Kernel-commits mailing list
[email protected]
http://sesat.no/mailman/listinfo/kernel-commits