com.bugull.mongo.lucene.BuguIndex.java Source code

Java tutorial

Introduction

Here is the source code for com.bugull.mongo.lucene.BuguIndex.java

Source

/*
 * Copyright (c) www.bugull.com
 * 
 * Licensed 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.bugull.mongo.lucene;

import com.bugull.mongo.lucene.cache.IndexWriterCache;
import com.bugull.mongo.lucene.backend.IndexReopenTask;
import com.bugull.mongo.lucene.cluster.ClusterConfig;
import com.bugull.mongo.utils.ThreadUtil;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.Version;

/**
 * Set the lucene index attributes.
 * 
 * <p>Singleton Pattern is used here. An application should use only one BuguIndex.</p>
 * 
 * @author Frank Wen(xbwen@hotmail.com)
 */
public class BuguIndex {

    private final static Logger logger = Logger.getLogger(BuguIndex.class);

    private double bufferSizeMB = 16;
    private Version version = Version.LUCENE_35;
    private Analyzer analyzer = new StandardAnalyzer(version);

    private String directoryPath;
    private ClusterConfig clusterConfig; //used in clustering environment

    private ExecutorService executor; //thread pool to maintain index writing 
    private int threadPoolSize;

    private ScheduledExecutorService scheduler; //scheduler to reopen index
    private long period = 30L * 1000L; //by default, reopen index per 30 seconds

    private boolean reopening;
    private Set<String> rebuildingSet;

    private static class Holder {
        final static BuguIndex instance = new BuguIndex();
    }

    public static BuguIndex getInstance() {
        return Holder.instance;
    }

    public void open() {
        rebuildingSet = Collections.synchronizedSet(new HashSet<String>());
        //default thread pool size is: cpu * 2 + 1
        threadPoolSize = Runtime.getRuntime().availableProcessors() * 2 + 1;
        executor = Executors.newFixedThreadPool(threadPoolSize);
        scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(new IndexReopenTask(), period, period, TimeUnit.MILLISECONDS);
        if (clusterConfig != null) {
            clusterConfig.validate();
        }
    }

    public void close() {
        ThreadUtil.safeClose(executor);
        ThreadUtil.safeClose(scheduler);
        if (clusterConfig != null) {
            clusterConfig.invalidate();
        }

        Map<String, IndexWriter> map = IndexWriterCache.getInstance().getAll();
        for (IndexWriter writer : map.values()) {
            if (writer != null) {
                Directory dir = writer.getDirectory();
                try {
                    writer.commit();
                    writer.close(true);
                } catch (CorruptIndexException ex) {
                    logger.error("Can not commit and close the lucene index", ex);
                } catch (IOException ex) {
                    logger.error("Can not commit and close the lucene index", ex);
                } finally {
                    try {
                        if (dir != null && IndexWriter.isLocked(dir)) {
                            IndexWriter.unlock(dir);
                        }
                    } catch (IOException ex) {
                        logger.error("Can not unlock the lucene index", ex);
                    }
                }
            }
        }
    }

    public ExecutorService getExecutor() {
        return executor;
    }

    public void setThreadPoolSize(int threadPoolSize) {
        this.threadPoolSize = threadPoolSize;
    }

    public double getBufferSizeMB() {
        return bufferSizeMB;
    }

    public void setBufferSizeMB(double bufferSizeMB) {
        this.bufferSizeMB = bufferSizeMB;
    }

    public void setIndexReopenPeriod(long period) {
        this.period = period;
    }

    public Version getVersion() {
        return version;
    }

    public void setVersion(Version version) {
        this.version = version;
    }

    public Analyzer getAnalyzer() {
        return analyzer;
    }

    public void setAnalyzer(Analyzer analyzer) {
        this.analyzer = analyzer;
    }

    public String getDirectoryPath() {
        return directoryPath;
    }

    public void setDirectoryPath(String directoryPath) {
        this.directoryPath = directoryPath;
    }

    public boolean isReopening() {
        return reopening;
    }

    public void setReopening(boolean reopening) {
        this.reopening = reopening;
    }

    public boolean isRebuilding(String entityName) {
        return rebuildingSet.contains(entityName);
    }

    public void setRebuilding(String entityName, boolean rebuilding) {
        if (rebuilding) {
            rebuildingSet.add(entityName);
        } else {
            rebuildingSet.remove(entityName);
        }
    }

    public ClusterConfig getClusterConfig() {
        return clusterConfig;
    }

    public void setClusterConfig(ClusterConfig clusterConfig) {
        this.clusterConfig = clusterConfig;
    }

}