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.io.IOException;
020:
021: import org.apache.lucene.index.IndexWriter;
022: import org.apache.lucene.index.LuceneSubIndexInfo;
023: import org.apache.lucene.store.Directory;
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.lucene.LuceneEnvironment;
029: import org.compass.core.lucene.engine.manager.LuceneSearchEngineIndexManager;
030:
031: /**
032: * @author kimchy
033: */
034: public class AggressiveOptimizer extends AbstractIndexInfoOptimizer
035: implements CompassConfigurable {
036:
037: private long mergeFactor;
038:
039: public void configure(CompassSettings settings)
040: throws CompassException {
041: mergeFactor = settings
042: .getSettingAsLong(
043: LuceneEnvironment.Optimizer.Aggressive.MERGE_FACTOR,
044: 10);
045: }
046:
047: public boolean canBeScheduled() {
048: return true;
049: }
050:
051: protected boolean isOptimizeOnlyIfIndexChanged() {
052: return true;
053: }
054:
055: protected boolean doNeedOptimizing(String subIndex,
056: LuceneSubIndexInfo indexInfo) {
057: if (indexInfo.size() >= mergeFactor) {
058: if (log.isDebugEnabled()) {
059: log.debug("Need to optimize sub-index [" + subIndex
060: + "]. Optimizing " + indexInfo.size()
061: + " segments into one segment.");
062: }
063: return true;
064: }
065: return false;
066: }
067:
068: protected void doOptimize(String subIndex,
069: LuceneSubIndexInfo indexInfo) throws SearchEngineException {
070: if (!doNeedOptimizing(subIndex, indexInfo)) {
071: return;
072: }
073: LuceneSearchEngineIndexManager indexManager = getSearchEngineFactory()
074: .getLuceneIndexManager();
075: IndexWriter indexWriter = null;
076: Directory dir = null;
077: try {
078: if (log.isDebugEnabled()) {
079: log.debug("Optimizing sub-index [" + subIndex + "]");
080: }
081: long time = System.currentTimeMillis();
082: dir = indexManager.getStore().openDirectory(subIndex);
083: indexWriter = indexManager.openIndexWriter(indexManager
084: .getSettings().getSettings(), dir, false);
085: long lockTime = System.currentTimeMillis() - time;
086: time = System.currentTimeMillis();
087: indexWriter.optimize();
088: long optimizeTime = System.currentTimeMillis() - time;
089: if (log.isDebugEnabled()) {
090: log.debug("Optimization of sub-index [" + subIndex
091: + "] took [" + (optimizeTime + lockTime)
092: + "ms], Locking took [" + lockTime
093: + "ms], and optimization took [" + optimizeTime
094: + "ms].");
095: }
096: } catch (IOException e) {
097: if (e.getMessage().startsWith("Lock obtain")) {
098: log.warn("Failed to obtain lock on sub-index ["
099: + subIndex + "], will do it next time.");
100: } else {
101: throw new SearchEngineException(
102: "Failed to optimize sub-index [" + subIndex
103: + "]", e);
104: }
105: } finally {
106: try {
107: if (indexWriter != null) {
108: indexWriter.close();
109: }
110: } catch (IOException e) {
111: log.warn("Failed to close index writer for sub index ["
112: + subIndex + "]", e);
113: }
114: }
115: }
116: }
|