📄 directoryindexreader.java
字号:
package org.apache.lucene.index;/** * 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. */import java.io.IOException;import java.io.FileNotFoundException;import java.util.HashSet;import java.util.Collection;import java.util.ArrayList;import java.util.List;import org.apache.lucene.store.Directory;import org.apache.lucene.store.Lock;import org.apache.lucene.store.LockObtainFailedException;/** * IndexReader implementation that has access to a Directory. * Instances that have a SegmentInfos object (i. e. segmentInfos != null) * "own" the directory, which means that they try to acquire a write lock * whenever index modifications are performed. */abstract class DirectoryIndexReader extends IndexReader { protected Directory directory; protected boolean closeDirectory; private IndexDeletionPolicy deletionPolicy; private SegmentInfos segmentInfos; private Lock writeLock; private boolean stale; private final HashSet synced = new HashSet(); /** Used by commit() to record pre-commit state in case * rollback is necessary */ private boolean rollbackHasChanges; private SegmentInfos rollbackSegmentInfos; protected boolean readOnly; void init(Directory directory, SegmentInfos segmentInfos, boolean closeDirectory, boolean readOnly) throws IOException { this.directory = directory; this.segmentInfos = segmentInfos; this.closeDirectory = closeDirectory; this.readOnly = readOnly; if (!readOnly && segmentInfos != null) { // We assume that this segments_N was previously // properly sync'd: for(int i=0;i<segmentInfos.size();i++) { final SegmentInfo info = segmentInfos.info(i); List files = info.files(); for(int j=0;j<files.size();j++) synced.add(files.get(j)); } } } protected DirectoryIndexReader() {} DirectoryIndexReader(Directory directory, SegmentInfos segmentInfos, boolean closeDirectory, boolean readOnly) throws IOException { super(); init(directory, segmentInfos, closeDirectory, readOnly); } static DirectoryIndexReader open(final Directory directory, final boolean closeDirectory, final IndexDeletionPolicy deletionPolicy) throws CorruptIndexException, IOException { return open(directory, closeDirectory, deletionPolicy, null, false); } static DirectoryIndexReader open(final Directory directory, final boolean closeDirectory, final IndexDeletionPolicy deletionPolicy, final IndexCommit commit, final boolean readOnly) throws CorruptIndexException, IOException { SegmentInfos.FindSegmentsFile finder = new SegmentInfos.FindSegmentsFile(directory) { protected Object doBody(String segmentFileName) throws CorruptIndexException, IOException { SegmentInfos infos = new SegmentInfos(); infos.read(directory, segmentFileName); DirectoryIndexReader reader; if (infos.size() == 1) { // index is optimized reader = SegmentReader.get(readOnly, infos, infos.info(0), closeDirectory); } else if (readOnly) { reader = new ReadOnlyMultiSegmentReader(directory, infos, closeDirectory); } else { reader = new MultiSegmentReader(directory, infos, closeDirectory, false); } reader.setDeletionPolicy(deletionPolicy); return reader; } }; if (commit == null) return (DirectoryIndexReader) finder.run(); else { if (directory != commit.getDirectory()) throw new IOException("the specified commit does not match the specified Directory"); // This can & will directly throw IOException if the // specified commit point has been deleted: return (DirectoryIndexReader) finder.doBody(commit.getSegmentsFileName()); } } public final synchronized IndexReader reopen() throws CorruptIndexException, IOException { ensureOpen(); if (this.hasChanges || this.isCurrent()) { // this has changes, therefore we have the lock and don't need to reopen // OR: the index in the directory hasn't changed - nothing to do here return this; } return (DirectoryIndexReader) new SegmentInfos.FindSegmentsFile(directory) { protected Object doBody(String segmentFileName) throws CorruptIndexException, IOException { SegmentInfos infos = new SegmentInfos(); infos.read(directory, segmentFileName); DirectoryIndexReader newReader = doReopen(infos); if (DirectoryIndexReader.this != newReader) { newReader.init(directory, infos, closeDirectory, readOnly); newReader.deletionPolicy = deletionPolicy; } return newReader; } }.run(); } /** * Re-opens the index using the passed-in SegmentInfos */ protected abstract DirectoryIndexReader doReopen(SegmentInfos infos) throws CorruptIndexException, IOException; public void setDeletionPolicy(IndexDeletionPolicy deletionPolicy) { this.deletionPolicy = deletionPolicy; } /** Returns the directory this index resides in. */ public Directory directory() { ensureOpen(); return directory; } /** * Version number when this IndexReader was opened. */ public long getVersion() { ensureOpen(); return segmentInfos.getVersion(); } /** * Check whether this IndexReader is still using the * current (i.e., most recently committed) version of the * index. If a writer has committed any changes to the * index since this reader was opened, this will return * <code>false</code>, in which case you must open a new * IndexReader in order to see the changes. See the * description of the <a href="IndexWriter.html#autoCommit"><code>autoCommit</code></a> * flag which controls when the {@link IndexWriter} * actually commits changes to the index. * * @throws CorruptIndexException if the index is corrupt * @throws IOException if there is a low-level IO error */ public boolean isCurrent() throws CorruptIndexException, IOException { ensureOpen(); return SegmentInfos.readCurrentVersion(directory) == segmentInfos.getVersion(); } /** * Checks is the index is optimized (if it has a single segment and no deletions) * @return <code>true</code> if the index is optimized; <code>false</code> otherwise */ public boolean isOptimized() { ensureOpen(); return segmentInfos.size() == 1 && hasDeletions() == false; } protected void doClose() throws IOException { if(closeDirectory) directory.close(); } /** * Commit changes resulting from delete, undeleteAll, or * setNorm operations * * If an exception is hit, then either no changes or all * changes will have been committed to the index * (transactional semantics). * @throws IOException if there is a low-level IO error */ protected void doCommit() throws IOException { if (hasChanges) { if (segmentInfos != null) { // Default deleter (for backwards compatibility) is // KeepOnlyLastCommitDeleter: IndexFileDeleter deleter = new IndexFileDeleter(directory, deletionPolicy == null ? new KeepOnlyLastCommitDeletionPolicy() : deletionPolicy, segmentInfos, null, null); // Checkpoint the state we are about to change, in // case we have to roll back: startCommit(); boolean success = false; try { commitChanges(); // Sync all files we just wrote for(int i=0;i<segmentInfos.size();i++) { final SegmentInfo info = segmentInfos.info(i);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -