com.esri.gpt.catalog.lucene.LuceneIndexOptimizer.java Source code

Java tutorial

Introduction

Here is the source code for com.esri.gpt.catalog.lucene.LuceneIndexOptimizer.java

Source

/* See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * Esri Inc. licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.esri.gpt.catalog.lucene;

import com.esri.gpt.framework.collection.StringAttributeMap;
import com.esri.gpt.framework.context.RequestContext;
import com.esri.gpt.framework.scheduler.IScheduledTask;
import com.esri.gpt.server.assertion.AsnConfig;
import com.esri.gpt.server.assertion.AsnFactory;
import com.esri.gpt.server.assertion.index.AsnIndexAdapter;
import com.esri.gpt.server.assertion.index.AsnIndexReference;
import com.esri.gpt.server.assertion.index.AsnIndexReferences;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.Lock;
import org.apache.lucene.store.LockObtainFailedException;

/**
 * Background thread to optimize the Lucene index.
 */
public class LuceneIndexOptimizer implements Runnable, IScheduledTask {

    /** class variables ========================================================= */
    private static Logger LOGGER = Logger.getLogger(LuceneIndexOptimizer.class.getName());

    /** instance variables ====================================================== */
    private StringAttributeMap parameters = null;
    private boolean wasInterrupted = false;

    /** constructors  =========================================================== */

    /** Default constructor. */
    public LuceneIndexOptimizer() {
    }

    /** properties  ============================================================= */

    /**
    * Sets the configuration paramaters for the task.
    * @param parameters the configuration paramaters
    */
    public void setParameters(StringAttributeMap parameters) {
        this.parameters = parameters;
    }

    /** methods ================================================================= */

    /**
     * Checks to see if the thread was interrupted.
     * @return true if the thread was interrupted
     */
    private boolean checkInterrupted() {
        if (!this.wasInterrupted) {
            if (Thread.interrupted()) {
                this.wasInterrupted = true;
            }
        }
        return this.wasInterrupted;
    }

    /**
     * Run the optimization process.
     */
    public void run() {
        LOGGER.info("Optimization run started...");
        RequestContext context = null;
        IndexWriter writer = null;
        Lock backgroundLock = null;
        long tStartMillis = System.currentTimeMillis();
        try {

            // initialize
            context = RequestContext.extract(null);
            LuceneIndexAdapter adapter = new LuceneIndexAdapter(context);
            adapter.touch(); // ensures that a proper directory structure exists
            if (this.checkInterrupted())
                return;

            // obtain the background thread lock, 
            // sleep for 10 minutes if busy then try again
            try {
                backgroundLock = adapter.obtainBackgroundLock();
            } catch (LockObtainFailedException lofe) {
                if (this.checkInterrupted())
                    return;
                try {
                    Thread.sleep(10 * 1000);
                } catch (InterruptedException e) {
                    throw new IOException(e.toString());
                }
                if (this.checkInterrupted())
                    return;
                backgroundLock = adapter.obtainBackgroundLock();
            }

            // optimize the index
            writer = adapter.newWriter();
            if (this.checkInterrupted())
                return;
            writer.optimize();
            adapter.closeWriter(writer);
            writer = null;

            // log the summary message
            double dSec = (System.currentTimeMillis() - tStartMillis) / 1000.0;
            StringBuffer msg = new StringBuffer();
            msg.append("Optimization run completed.");
            msg.append(", runtime: ");
            msg.append(Math.round(dSec / 60.0 * 100.0) / 100.0).append(" minutes");
            if (dSec <= 600) {
                msg.append(", ").append(Math.round(dSec * 100.0) / 100.0).append(" seconds");
            }
            LOGGER.info(msg.toString());

        } catch (LockObtainFailedException e) {
            LOGGER.log(Level.INFO, "Optimization run aborted, reason: " + e.getMessage());
        } catch (Throwable t) {
            LOGGER.log(Level.SEVERE, "Error optimizing index.", t);
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (Throwable t) {
                    LOGGER.log(Level.SEVERE, "Error closing IndexWriter.", t);
                }
            }
            if (backgroundLock != null) {
                try {
                    backgroundLock.release();
                } catch (Throwable t) {
                    LOGGER.log(Level.WARNING, "Error releasing lock.", t);
                }
            }
            if (context != null) {
                context.onExecutionPhaseCompleted();
            }
            if (this.wasInterrupted) {
                LOGGER.info("LuceneIndexOptimizer run was interrupted.");
            }
        }

        // optimize the assertion indexes
        AsnFactory asnFactory = AsnFactory.newFactory(null);
        AsnConfig asnConfig = asnFactory.getConfiguration();
        if (asnConfig.getAreAssertionsEnabled()) {
            AsnIndexReferences asnIndexRefs = asnConfig.getIndexReferences();
            if (asnIndexRefs != null) {
                for (AsnIndexReference asnIndexRef : asnIndexRefs.values()) {
                    if ((asnIndexRef != null) && asnIndexRef.getEnabled()) {
                        String asnLoc = asnIndexRef.getIndexLocation();
                        LOGGER.fine("Optimizing assertion index: " + asnLoc);
                        try {
                            long asnStartMillis = System.currentTimeMillis();
                            AsnIndexAdapter asnIndexAdapter = asnIndexRef.makeIndexAdapter(null);
                            asnIndexAdapter.optimize();

                            double asnSec = (System.currentTimeMillis() - asnStartMillis) / 1000.0;
                            StringBuffer msg = new StringBuffer();
                            msg.append("Optimization of assertion index complete: " + asnLoc);
                            msg.append(", runtime: ");
                            msg.append(Math.round(asnSec / 60.0 * 100.0) / 100.0).append(" minutes");
                            if (asnSec <= 600) {
                                msg.append(", ").append(Math.round(asnSec * 100.0) / 100.0).append(" seconds");
                            }
                            LOGGER.fine(msg.toString());

                        } catch (Exception e) {
                            LOGGER.log(Level.SEVERE, "Error optimizing assertion index: " + asnLoc, e);
                        }
                    }
                }
            }
        }

    }

}