001: /*
002: * Copyright 2004-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.compass.core.lucene.engine.optimizer;
018:
019: import java.util.concurrent.ScheduledFuture;
020: import java.util.concurrent.TimeUnit;
021:
022: import org.apache.commons.logging.Log;
023: import org.apache.commons.logging.LogFactory;
024: import org.compass.core.CompassException;
025: import org.compass.core.config.CompassConfigurable;
026: import org.compass.core.config.CompassSettings;
027: import org.compass.core.engine.SearchEngineException;
028: import org.compass.core.engine.SearchEngineOptimizer;
029: import org.compass.core.lucene.LuceneEnvironment;
030: import org.compass.core.lucene.engine.LuceneSearchEngineFactory;
031: import org.compass.core.util.ClassUtils;
032:
033: /**
034: * @author kimchy
035: */
036: public class LuceneSearchEngineOptimizerManager implements
037: CompassConfigurable, SearchEngineOptimizer {
038:
039: private static final Log log = LogFactory
040: .getLog(LuceneSearchEngineOptimizerManager.class);
041:
042: private LuceneSearchEngineFactory searchEngineFactory;
043:
044: private LuceneSearchEngineOptimizer searchEngineOptimizer;
045:
046: private ScheduledFuture scheduledFuture;
047:
048: private volatile boolean started = false;
049:
050: public LuceneSearchEngineOptimizerManager(
051: LuceneSearchEngineFactory searchEngineFactory) {
052: this .searchEngineFactory = searchEngineFactory;
053: }
054:
055: public void configure(CompassSettings settings)
056: throws CompassException {
057: // build the optimizer and start it
058: String optimizerClassSetting = settings.getSetting(
059: LuceneEnvironment.Optimizer.TYPE,
060: AdaptiveOptimizer.class.getName());
061: if (log.isDebugEnabled()) {
062: log
063: .debug("Using optimizer [" + optimizerClassSetting
064: + "]");
065: }
066: try {
067: Class optimizerClass = ClassUtils.forName(
068: optimizerClassSetting, settings.getClassLoader());
069: searchEngineOptimizer = (LuceneSearchEngineOptimizer) optimizerClass
070: .newInstance();
071: if (searchEngineOptimizer instanceof CompassConfigurable) {
072: ((CompassConfigurable) searchEngineOptimizer)
073: .configure(settings);
074: }
075: } catch (Exception e) {
076: throw new SearchEngineException(
077: "Can't find optimizer class ["
078: + optimizerClassSetting + "]", e);
079: }
080: searchEngineOptimizer
081: .setSearchEngineFactory(searchEngineFactory);
082: }
083:
084: public void start() throws SearchEngineException {
085: if (started) {
086: return;
087: }
088: started = true;
089: searchEngineOptimizer.start();
090:
091: CompassSettings settings = searchEngineFactory.getSettings();
092: if (searchEngineOptimizer.canBeScheduled()) {
093: boolean scheduledOptimizer = searchEngineFactory
094: .getSettings().getSettingAsBoolean(
095: LuceneEnvironment.Optimizer.SCHEDULE, true);
096: if (scheduledOptimizer) {
097: long period = (long) (settings
098: .getSettingAsFloat(
099: LuceneEnvironment.Optimizer.SCHEDULE_PERIOD,
100: 10) * 1000);
101: if (log.isInfoEnabled()) {
102: log.info("Starting scheduled optimizer ["
103: + searchEngineOptimizer.getClass()
104: + "] with period [" + period + "ms]");
105: }
106:
107: ScheduledOptimizeRunnable scheduledOptimizeRunnable = new ScheduledOptimizeRunnable(
108: searchEngineOptimizer);
109: scheduledFuture = searchEngineFactory
110: .getExecutorManager().scheduleWithFixedDelay(
111: scheduledOptimizeRunnable, period,
112: period, TimeUnit.MILLISECONDS);
113: }
114: }
115: }
116:
117: public void stop() throws SearchEngineException {
118: if (!started) {
119: return;
120: }
121: started = false;
122: if (scheduledFuture != null) {
123: scheduledFuture.cancel(true);
124: scheduledFuture = null;
125: }
126: searchEngineOptimizer.stop();
127: }
128:
129: public boolean isRunning() {
130: return searchEngineOptimizer.isRunning();
131: }
132:
133: public void optimize() throws SearchEngineException {
134: searchEngineOptimizer.optimize();
135: }
136:
137: public void optimize(String subIndex) throws SearchEngineException {
138: searchEngineOptimizer.optimize(subIndex);
139: }
140:
141: public SearchEngineOptimizer getOptimizer() {
142: return searchEngineOptimizer;
143: }
144:
145: private static class ScheduledOptimizeRunnable implements Runnable {
146:
147: private SearchEngineOptimizer optimizer;
148:
149: public ScheduledOptimizeRunnable(SearchEngineOptimizer optimizer) {
150: this .optimizer = optimizer;
151: }
152:
153: public void run() {
154: if (log.isDebugEnabled()) {
155: log.debug("Checking for index optimization");
156: }
157: try {
158: optimizer.optimize();
159: } catch (Exception e) {
160: if (log.isDebugEnabled()) {
161: log.debug("Failed to optimize", e);
162: }
163: }
164: }
165: }
166: }
|