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 + -
显示快捷键?