multiindex.java

来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 1,855 行 · 第 1/5 页

JAVA
1,855
字号
            // flush whole index when volatile index has been commited.            if (flush) {                flush();            }        } finally {            synchronized (updateMonitor) {                updateInProgress = false;                updateMonitor.notifyAll();                if (multiReader != null) {                    multiReader.close();                    multiReader = null;                }            }        }    }    /**     * Adds a document to the index.     *     * @param doc the document to add.     * @throws IOException if an error occurs while adding the document to the     *                     index.     */    void addDocument(Document doc) throws IOException {        List add = Arrays.asList(new Document[]{doc});        update(EmptyIterator.INSTANCE, add.iterator());    }    /**     * Deletes the first document that matches the <code>uuid</code>.     *     * @param uuid document that match this <code>uuid</code> will be deleted.     * @throws IOException if an error occurs while deleting the document.     */    void removeDocument(UUID uuid) throws IOException {        List remove = Arrays.asList(new UUID[]{uuid});        update(remove.iterator(), EmptyIterator.INSTANCE);    }    /**     * Deletes all documents that match the <code>uuid</code>.     *     * @param uuid documents that match this <code>uuid</code> will be deleted.     * @return the number of deleted documents.     * @throws IOException if an error occurs while deleting documents.     */    synchronized int removeAllDocuments(UUID uuid) throws IOException {        synchronized (updateMonitor) {            updateInProgress = true;        }        int num;        try {            Term idTerm = new Term(FieldNames.UUID, uuid.toString());            executeAndLog(new Start(Action.INTERNAL_TRANSACTION));            num = volatileIndex.removeDocument(idTerm);            if (num > 0) {                redoLog.append(new DeleteNode(getTransactionId(), uuid));            }            for (int i = 0; i < indexes.size(); i++) {                PersistentIndex index = (PersistentIndex) indexes.get(i);                // only remove documents from registered indexes                if (indexNames.contains(index.getName())) {                    int removed = index.removeDocument(idTerm);                    if (removed > 0) {                        redoLog.append(new DeleteNode(getTransactionId(), uuid));                    }                    num += removed;                }            }            executeAndLog(new Commit(getTransactionId()));        } finally {            synchronized (updateMonitor) {                updateInProgress = false;                updateMonitor.notifyAll();                if (multiReader != null) {                    multiReader.close();                    multiReader = null;                }            }        }        return num;    }    /**     * Returns <code>IndexReader</code>s for the indexes named     * <code>indexNames</code>. An <code>IndexListener</code> is registered and     * notified when documents are deleted from one of the indexes in     * <code>indexNames</code>.     * <p/>     * Note: the number of <code>IndexReaders</code> returned by this method is     * not necessarily the same as the number of index names passed. An index     * might have been deleted and is not reachable anymore.     *     * @param indexNames the names of the indexes for which to obtain readers.     * @param listener   the listener to notify when documents are deleted.     * @return the <code>IndexReaders</code>.     * @throws IOException if an error occurs acquiring the index readers.     */    synchronized IndexReader[] getIndexReaders(String[] indexNames, IndexListener listener)            throws IOException {        Set names = new HashSet(Arrays.asList(indexNames));        Map indexReaders = new HashMap();        try {            for (Iterator it = indexes.iterator(); it.hasNext();) {                PersistentIndex index = (PersistentIndex) it.next();                if (names.contains(index.getName())) {                    indexReaders.put(index.getReadOnlyIndexReader(listener), index);                }            }        } catch (IOException e) {            // close readers obtained so far            for (Iterator it = indexReaders.keySet().iterator(); it.hasNext();) {                ReadOnlyIndexReader reader = (ReadOnlyIndexReader) it.next();                try {                    reader.close();                } catch (IOException ex) {                    log.warn("Exception closing index reader: " + ex);                }                ((PersistentIndex) indexReaders.get(reader)).resetListener();            }            throw e;        }        return (IndexReader[]) indexReaders.keySet().toArray(new IndexReader[indexReaders.size()]);    }    /**     * Creates a new Persistent index. The new index is not registered with this     * <code>MultiIndex</code>.     *     * @param indexName the name of the index to open, or <code>null</code> if     *                  an index with a new name should be created.     * @param create    if the index that is opened should delete existing index     *                  data.     * @return a new <code>PersistentIndex</code>.     * @throws IOException if a new index cannot be created.     */    synchronized PersistentIndex getOrCreateIndex(String indexName, boolean create)            throws IOException {        // check existing        for (Iterator it = indexes.iterator(); it.hasNext();) {            PersistentIndex idx = (PersistentIndex) it.next();            if (idx.getName().equals(indexName)) {                return idx;            }        }        // otherwise open / create it        File sub;        if (indexName == null) {            sub = newIndexFolder();            indexName = sub.getName();        } else {            sub = new File(indexDir, indexName);        }        PersistentIndex index = new PersistentIndex(indexName, sub, create,                handler.getTextAnalyzer(), cache, indexingQueue);        index.setMaxMergeDocs(handler.getMaxMergeDocs());        index.setMergeFactor(handler.getMergeFactor());        index.setMinMergeDocs(handler.getMinMergeDocs());        index.setMaxFieldLength(handler.getMaxFieldLength());        index.setUseCompoundFile(handler.getUseCompoundFile());        // add to list of open indexes and return it        indexes.add(index);        return index;    }    /**     * Returns <code>true</code> if this multi index has an index segment with     * the given name. This method even returns <code>true</code> if an index     * segments has not yet been loaded / initialized but exists on disk.     *     * @param indexName the name of the index segment.     * @return <code>true</code> if it exists; otherwise <code>false</code>.     */    synchronized boolean hasIndex(String indexName) {        // check existing        for (Iterator it = indexes.iterator(); it.hasNext();) {            PersistentIndex idx = (PersistentIndex) it.next();            if (idx.getName().equals(indexName)) {                return true;            }        }        // check if it exists on disk        return new File(indexDir, indexName).exists();    }    /**     * Replaces the indexes with names <code>obsoleteIndexes</code> with     * <code>index</code>. Documents that must be deleted in <code>index</code>     * can be identified with <code>Term</code>s in <code>deleted</code>.     *     * @param obsoleteIndexes the names of the indexes to replace.     * @param index      the new index that is the result of a merge of the     *                   indexes to replace.     * @param deleted    <code>Term</code>s that identify documents that must be     *                   deleted in <code>index</code>.     * @throws IOException if an exception occurs while replacing the indexes.     */    synchronized void replaceIndexes(String[] obsoleteIndexes,                                     PersistentIndex index,                                     Collection deleted)            throws IOException {        synchronized (updateMonitor) {            updateInProgress = true;        }        try {            // if we are reindexing there is already an active transaction            if (!reindexing) {                executeAndLog(new Start(Action.INTERNAL_TRANS_REPL_INDEXES));            }            // delete obsolete indexes            Set names = new HashSet(Arrays.asList(obsoleteIndexes));            for (Iterator it = names.iterator(); it.hasNext();) {                // do not try to delete indexes that are already gone                String indexName = (String) it.next();                if (indexNames.contains(indexName)) {                    executeAndLog(new DeleteIndex(getTransactionId(), indexName));                }            }            // Index merger does not log an action when it creates the target            // index of the merge. We have to do this here.            executeAndLog(new CreateIndex(getTransactionId(), index.getName(), false));            executeAndLog(new AddIndex(getTransactionId(), index.getName()));            // delete documents in index            for (Iterator it = deleted.iterator(); it.hasNext();) {                Term id = (Term) it.next();                index.removeDocument(id);            }            index.commit();            if (reindexing) {                // do some cleanup right away when reindexing                attemptDelete();            } else {                // only commit if we are not reindexing                // when reindexing the final commit is done at the very end                executeAndLog(new Commit(getTransactionId()));            }        } finally {            synchronized (updateMonitor) {                updateInProgress = false;                updateMonitor.notifyAll();                if (multiReader != null) {                    multiReader.close();                    multiReader = null;                }            }        }    }    /**     * Returns an read-only <code>IndexReader</code> that spans alls indexes of this     * <code>MultiIndex</code>.     *     * @return an <code>IndexReader</code>.     * @throws IOException if an error occurs constructing the <code>IndexReader</code>.     */    public IndexReader getIndexReader() throws IOException {        synchronized (updateMonitor) {            if (multiReader != null) {                multiReader.incrementRefCount();                return multiReader;            }            // no reader available            // wait until no update is in progress            while (updateInProgress) {                try {                    updateMonitor.wait();                } catch (InterruptedException e) {                    throw new IOException("Interrupted while waiting to aquire reader");                }            }            // some other read thread might have created the reader in the            // meantime -> check again            if (multiReader == null) {                List readerList = new ArrayList();                for (int i = 0; i < indexes.size(); i++) {                    PersistentIndex pIdx = (PersistentIndex) indexes.get(i);                    if (indexNames.contains(pIdx.getName())) {                        readerList.add(pIdx.getReadOnlyIndexReader());                    }                }                readerList.add(volatileIndex.getReadOnlyIndexReader());                ReadOnlyIndexReader[] readers =                        (ReadOnlyIndexReader[]) readerList.toArray(new ReadOnlyIndexReader[readerList.size()]);                multiReader = new CachingMultiReader(readers, cache);            }            multiReader.incrementRefCount();            return multiReader;        }    }    /**     * Returns the volatile index.     *     * @return the volatile index.     */    VolatileIndex getVolatileIndex() {        return volatileIndex;    }    /**     * Closes this <code>MultiIndex</code>.     */    void close() {        // stop index merger        // when calling this method we must not lock this MultiIndex, otherwise        // a deadlock might occur        merger.dispose();        synchronized (this) {            // stop timer            flushTask.cancel();            // commit / close indexes            if (multiReader != null) {                try {                    multiReader.close();                } catch (IOException e) {                    log.error("Exception while closing search index.", e);                }                multiReader = null;            }            try {                flush();            } catch (IOException e) {                log.error("Exception while closing search index.", e);            }            volatileIndex.close();            for (int i = 0; i < indexes.size(); i++) {                ((PersistentIndex) indexes.get(i)).close();            }            // finally close indexing queue            try {                indexingQueue.close();            } catch (IOException e) {                log.error("Exception while closing search index.", e);            }        }    }    /**     * Returns the namespace mappings of this search index.     * @return the namespace mappings of this search index.     */    NamespaceMappings getNamespaceMappings() {        return nsMappings;    }    /**     * Returns the indexing queue for this multi index.     * @return the indexing queue for this multi index.     */    IndexingQueue getIndexingQueue() {        return indexingQueue;    }    /**     * Returns a lucene Document for the <code>node</code>.     *     * @param node the node to index.

⌨️ 快捷键说明

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