📄 directoryindexreader.java
字号:
final List files = info.files(); for(int j=0;j<files.size();j++) { final String fileName = (String) files.get(j); if (!synced.contains(fileName)) { assert directory.fileExists(fileName); directory.sync(fileName); synced.add(fileName); } } } segmentInfos.commit(directory); success = true; } finally { if (!success) { // Rollback changes that were made to // SegmentInfos but failed to get [fully] // committed. This way this reader instance // remains consistent (matched to what's // actually in the index): rollbackCommit(); // Recompute deletable files & remove them (so // partially written .del files, etc, are // removed): deleter.refresh(); } } // Have the deleter remove any now unreferenced // files due to this commit: deleter.checkpoint(segmentInfos, true); if (writeLock != null) { writeLock.release(); // release write lock writeLock = null; } } else commitChanges(); } hasChanges = false; } protected abstract void commitChanges() throws IOException; /** * Tries to acquire the WriteLock on this directory. * this method is only valid if this IndexReader is directory owner. * * @throws StaleReaderException if the index has changed * since this reader was opened * @throws CorruptIndexException if the index is corrupt * @throws LockObtainFailedException if another writer * has this index open (<code>write.lock</code> could not * be obtained) * @throws IOException if there is a low-level IO error */ protected void acquireWriteLock() throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException { if (segmentInfos != null) { ensureOpen(); if (stale) throw new StaleReaderException("IndexReader out of date and no longer valid for delete, undelete, or setNorm operations"); if (writeLock == null) { Lock writeLock = directory.makeLock(IndexWriter.WRITE_LOCK_NAME); if (!writeLock.obtain(IndexWriter.WRITE_LOCK_TIMEOUT)) // obtain write lock throw new LockObtainFailedException("Index locked for write: " + writeLock); this.writeLock = writeLock; // we have to check whether index has changed since this reader was opened. // if so, this reader is no longer valid for deletion if (SegmentInfos.readCurrentVersion(directory) > segmentInfos.getVersion()) { stale = true; this.writeLock.release(); this.writeLock = null; throw new StaleReaderException("IndexReader out of date and no longer valid for delete, undelete, or setNorm operations"); } } } } /** * Should internally checkpoint state that will change * during commit so that we can rollback if necessary. */ void startCommit() { if (segmentInfos != null) { rollbackSegmentInfos = (SegmentInfos) segmentInfos.clone(); } rollbackHasChanges = hasChanges; } /** * Rolls back state to just before the commit (this is * called by commit() if there is some exception while * committing). */ void rollbackCommit() { if (segmentInfos != null) { for(int i=0;i<segmentInfos.size();i++) { // Rollback each segmentInfo. Because the // SegmentReader holds a reference to the // SegmentInfo we can't [easily] just replace // segmentInfos, so we reset it in place instead: segmentInfos.info(i).reset(rollbackSegmentInfos.info(i)); } rollbackSegmentInfos = null; } hasChanges = rollbackHasChanges; } /** Release the write lock, if needed. */ protected void finalize() throws Throwable { try { if (writeLock != null) { writeLock.release(); // release write lock writeLock = null; } } finally { super.finalize(); } } private static class ReaderCommit extends IndexCommit { private String segmentsFileName; Collection files; Directory dir; long generation; long version; final boolean isOptimized; ReaderCommit(SegmentInfos infos, Directory dir) throws IOException { segmentsFileName = infos.getCurrentSegmentFileName(); this.dir = dir; final int size = infos.size(); files = new ArrayList(size); files.add(segmentsFileName); for(int i=0;i<size;i++) { SegmentInfo info = infos.info(i); if (info.dir == dir) files.addAll(info.files()); } version = infos.getVersion(); generation = infos.getGeneration(); isOptimized = infos.size() == 1 && !infos.info(0).hasDeletions(); } public boolean isOptimized() { return isOptimized; } public String getSegmentsFileName() { return segmentsFileName; } public Collection getFileNames() { return files; } public Directory getDirectory() { return dir; } public long getVersion() { return version; } public long getGeneration() { return generation; } public boolean isDeleted() { return false; } } /** * Expert: return the IndexCommit that this reader has * opened. * * <p><b>WARNING</b>: this API is new and experimental and * may suddenly change.</p> */ public IndexCommit getIndexCommit() throws IOException { return new ReaderCommit(segmentInfos, directory); } /** @see IndexReader#listCommits */ public static Collection listCommits(Directory dir) throws IOException { final String[] files = dir.list(); if (files == null) throw new IOException("cannot read directory " + dir + ": list() returned null"); Collection commits = new ArrayList(); SegmentInfos latest = new SegmentInfos(); latest.read(dir); final long currentGen = latest.getGeneration(); commits.add(new ReaderCommit(latest, dir)); for(int i=0;i<files.length;i++) { final String fileName = files[i]; if (fileName.startsWith(IndexFileNames.SEGMENTS) && !fileName.equals(IndexFileNames.SEGMENTS_GEN) && SegmentInfos.generationFromSegmentsFileName(fileName) < currentGen) { SegmentInfos sis = new SegmentInfos(); try { // IOException allowed to throw there, in case // segments_N is corrupt sis.read(dir, fileName); } catch (FileNotFoundException fnfe) { // LUCENE-948: on NFS (and maybe others), if // you have writers switching back and forth // between machines, it's very likely that the // dir listing will be stale and will claim a // file segments_X exists when in fact it // doesn't. So, we catch this and handle it // as if the file does not exist sis = null; } if (sis != null) commits.add(new ReaderCommit(sis, dir)); } } return commits; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -