persistentindex.java

来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 233 行

JAVA
233
字号
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF 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 org.apache.jackrabbit.core.query.lucene;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.apache.lucene.analysis.Analyzer;import org.apache.lucene.index.IndexReader;import org.apache.lucene.index.IndexWriter;import org.apache.lucene.index.Term;import org.apache.lucene.store.Directory;import org.apache.lucene.store.IndexInput;import org.apache.lucene.store.IndexOutput;import java.io.IOException;import java.io.File;/** * Implements a lucene index which is based on a * {@link org.apache.jackrabbit.core.fs.FileSystem}. */class PersistentIndex extends AbstractIndex {    /** The logger instance for this class */    private static final Logger log = LoggerFactory.getLogger(PersistentIndex.class);    /** Name of the write lock file */    private static final String WRITE_LOCK = IndexWriter.WRITE_LOCK_NAME;    /** Name of the commit lock file */    private static final String COMMIT_LOCK = "commit.lock";    /** The name of this persistent index */    private final String name;    /** Set to <code>true</code> if this index encountered locks on startup */    private boolean lockEncountered = false;    /**     * If non <code>null</code>, <code>listener</code> needs to be informed     * when a document is deleted.     */    private IndexListener listener;    /**     * Creates a new <code>PersistentIndex</code> based on the file system     * <code>indexDir</code>.     * @param name the name of this index.     * @param indexDir the directory to store the index.     * @param create if <code>true</code> an existing index is deleted.     * @param analyzer the analyzer for text tokenizing.     * @param cache the document number cache     * @param indexingQueue the indexing queue.     * @throws IOException if an error occurs while opening / creating the     *  index.     * @throws IOException if an error occurs while opening / creating     *  the index.     */    PersistentIndex(String name, File indexDir, boolean create,                    Analyzer analyzer, DocNumberCache cache,                    IndexingQueue indexingQueue)            throws IOException {        super(analyzer, FSDirectory.getDirectory(indexDir, create),                cache, indexingQueue);        this.name = name;        // check if index is locked, probably from an unclean repository        // shutdown        File writeLock = new File(indexDir, WRITE_LOCK);        if (writeLock.exists()) {            lockEncountered = true;            log.warn("Removing write lock on search index.");            if (!writeLock.delete()) {                log.error("Unable to remove write lock on search index.");            }        }        File commitLock = new File(indexDir, COMMIT_LOCK);        if (commitLock.exists()) {            lockEncountered = true;            log.warn("Removing commit lock on search index.");            if (!commitLock.delete()) {                log.error("Unable to remove write lock on search index.");            }        }    }    /**     * @inheritDoc     */    int removeDocument(Term idTerm) throws IOException {        int num = super.removeDocument(idTerm);        if (num > 0 && listener != null) {            listener.documentDeleted(idTerm);        }        return num;    }    /**     * Returns <code>true</code> if this index encountered a lock on the file     * system during startup. This indicates a unclean shutdown.     *     * @return <code>true</code> if this index encountered a lock on startup;     *         <code>false</code> otherwise.     */    boolean getLockEncountered() {        return lockEncountered;    }    /**     * Merges another index into this persistent index. Before <code>index</code>     * is merged, {@link AbstractIndex#commit()} is called on that     * <code>index</code>.     *     * @param index the other index to merge.     * @throws IOException if an error occurs while merging.     */    void mergeIndex(AbstractIndex index) throws IOException {        // commit changes to directory on other index.        index.commit();        // merge index        getIndexWriter().addIndexes(new Directory[]{            index.getDirectory()        });        invalidateSharedReader();    }    /**     * Merges the provided indexes into this index. After this completes, the     * index is optimized.     * <p/>     * The provided IndexReaders are not closed.     *     * @param readers the readers of indexes to add.     * @throws IOException if an error occurs while adding indexes.     */    void addIndexes(IndexReader[] readers) throws IOException {        getIndexWriter().addIndexes(readers);        getIndexWriter().optimize();    }    /**     * Copies <code>index</code> into this persistent index. This method should     * only be called when <code>this</code> index is empty otherwise the     * behaviour is undefined.     *     * @param index the index to copy from.     * @throws IOException if an error occurs while copying.     */    void copyIndex(AbstractIndex index) throws IOException {        // commit changes to directory on other index.        index.commit(true);        // simply copy over the files        byte[] buffer = new byte[1024];        Directory dir = index.getDirectory();        Directory dest = getDirectory();        String[] files = dir.list();        for (int i = 0; i < files.length; i++) {            IndexInput in = dir.openInput(files[i]);            try {                IndexOutput out = dest.createOutput(files[i]);                try {                    long remaining = in.length();                    while (remaining > 0) {                        int num = (int) Math.min(remaining, buffer.length);                        in.readBytes(buffer, 0, num);                        out.writeBytes(buffer, num);                        remaining -= num;                    }                } finally {                    out.close();                }            } finally {                in.close();            }        }    }    /**     * Returns a <code>ReadOnlyIndexReader</code> and registeres     * <code>listener</code> to send notifications when documents are deleted on     * <code>this</code> index.     *     * @param listener the listener to notify when documents are deleted.     * @return a <code>ReadOnlyIndexReader</code>.     * @throws IOException if the reader cannot be obtained.     */    synchronized ReadOnlyIndexReader getReadOnlyIndexReader(IndexListener listener)            throws IOException {        ReadOnlyIndexReader reader = getReadOnlyIndexReader();        this.listener = listener;        return reader;    }    /**     * Removes a potentially registered {@link IndexListener}.     */    synchronized void resetListener() {        this.listener = null;    }    /**     * Returns the number of documents in this persistent index.     *     * @return the number of documents in this persistent index.     * @throws IOException if an error occurs while reading from the index.     */    int getNumDocuments() throws IOException {        return getIndexReader().numDocs();    }    /**     * Returns the name of this index.     * @return the name of this index.     */    String getName() {        return name;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?