?? indexfiledeleter.java
字號:
!fileName.equals(IndexFileNames.SEGMENTS_GEN)) { // Unreferenced file, so remove it if (infoStream != null) { message("refresh [prefix=" + segmentName + "]: removing newly created unreferenced file \"" + fileName + "\""); } deleteFile(fileName); } } } public void refresh() throws IOException { refresh(null); } public void close() throws IOException { deletePendingFiles(); } private void deletePendingFiles() throws IOException { if (deletable != null) { List oldDeletable = deletable; deletable = null; int size = oldDeletable.size(); for(int i=0;i<size;i++) { if (infoStream != null) message("delete pending file " + oldDeletable.get(i)); deleteFile((String) oldDeletable.get(i)); } } } /** * For definition of "check point" see IndexWriter comments: * "Clarification: Check Points (and commits)". * * Writer calls this when it has made a "consistent * change" to the index, meaning new files are written to * the index and the in-memory SegmentInfos have been * modified to point to those files. * * This may or may not be a commit (segments_N may or may * not have been written). * * We simply incref the files referenced by the new * SegmentInfos and decref the files we had previously * seen (if any). * * If this is a commit, we also call the policy to give it * a chance to remove other commits. If any commits are * removed, we decref their files as well. */ public void checkpoint(SegmentInfos segmentInfos, boolean isCommit) throws IOException { if (infoStream != null) { message("now checkpoint \"" + segmentInfos.getCurrentSegmentFileName() + "\" [" + segmentInfos.size() + " segments " + "; isCommit = " + isCommit + "]"); } // Try again now to delete any previously un-deletable // files (because they were in use, on Windows): deletePendingFiles(); // Incref the files: incRef(segmentInfos, isCommit); if (isCommit) { // Append to our commits list: commits.add(new CommitPoint(commitsToDelete, directory, segmentInfos)); // Tell policy so it can remove commits: policy.onCommit(commits); // Decref files for commits that were deleted by the policy: deleteCommits(); } else { final List docWriterFiles; if (docWriter != null) { docWriterFiles = docWriter.openFiles(); if (docWriterFiles != null) // We must incRef these files before decRef'ing // last files to make sure we don't accidentally // delete them: incRef(docWriterFiles); } else docWriterFiles = null; // DecRef old files from the last checkpoint, if any: int size = lastFiles.size(); if (size > 0) { for(int i=0;i<size;i++) decRef((List) lastFiles.get(i)); lastFiles.clear(); } // Save files so we can decr on next checkpoint/commit: size = segmentInfos.size(); for(int i=0;i<size;i++) { SegmentInfo segmentInfo = segmentInfos.info(i); if (segmentInfo.dir == directory) { lastFiles.add(segmentInfo.files()); } } if (docWriterFiles != null) lastFiles.add(docWriterFiles); } } void incRef(SegmentInfos segmentInfos, boolean isCommit) throws IOException { int size = segmentInfos.size(); for(int i=0;i<size;i++) { SegmentInfo segmentInfo = segmentInfos.info(i); if (segmentInfo.dir == directory) { incRef(segmentInfo.files()); } } if (isCommit) { // Since this is a commit point, also incref its // segments_N file: getRefCount(segmentInfos.getCurrentSegmentFileName()).IncRef(); } } void incRef(List files) throws IOException { int size = files.size(); for(int i=0;i<size;i++) { String fileName = (String) files.get(i); RefCount rc = getRefCount(fileName); if (infoStream != null && VERBOSE_REF_COUNTS) { message(" IncRef \"" + fileName + "\": pre-incr count is " + rc.count); } rc.IncRef(); } } void decRef(List files) throws IOException { int size = files.size(); for(int i=0;i<size;i++) { decRef((String) files.get(i)); } } void decRef(String fileName) throws IOException { RefCount rc = getRefCount(fileName); if (infoStream != null && VERBOSE_REF_COUNTS) { message(" DecRef \"" + fileName + "\": pre-decr count is " + rc.count); } if (0 == rc.DecRef()) { // This file is no longer referenced by any past // commit points nor by the in-memory SegmentInfos: deleteFile(fileName); refCounts.remove(fileName); } } void decRef(SegmentInfos segmentInfos) throws IOException { final int size = segmentInfos.size(); for(int i=0;i<size;i++) { SegmentInfo segmentInfo = segmentInfos.info(i); if (segmentInfo.dir == directory) { decRef(segmentInfo.files()); } } } private RefCount getRefCount(String fileName) { RefCount rc; if (!refCounts.containsKey(fileName)) { rc = new RefCount(); refCounts.put(fileName, rc); } else { rc = (RefCount) refCounts.get(fileName); } return rc; } void deleteFiles(List files) throws IOException { final int size = files.size(); for(int i=0;i<size;i++) deleteFile((String) files.get(i)); } /** Delets the specified files, but only if they are new * (have not yet been incref'd). */ void deleteNewFiles(Collection files) throws IOException { final Iterator it = files.iterator(); while(it.hasNext()) { final String fileName = (String) it.next(); if (!refCounts.containsKey(fileName)) deleteFile(fileName); } } void deleteFile(String fileName) throws IOException { try { if (infoStream != null) { message("delete \"" + fileName + "\""); } directory.deleteFile(fileName); } catch (IOException e) { // if delete fails if (directory.fileExists(fileName)) { // Some operating systems (e.g. Windows) don't // permit a file to be deleted while it is opened // for read (e.g. by another process or thread). So // we assume that when a delete fails it is because // the file is open in another process, and queue // the file for subsequent deletion. if (infoStream != null) { message("IndexFileDeleter: unable to remove file \"" + fileName + "\": " + e.toString() + "; Will re-try later."); } if (deletable == null) { deletable = new ArrayList(); } deletable.add(fileName); // add to deletable } } } /** * Tracks the reference count for a single index file: */ final private static class RefCount { int count; public int IncRef() { return ++count; } public int DecRef() { assert count > 0; return --count; } } /** * Holds details for each commit point. This class is * also passed to the deletion policy. Note: this class * has a natural ordering that is inconsistent with * equals. */ final private static class CommitPoint extends IndexCommit implements Comparable { long gen; List files; String segmentsFileName; boolean deleted; Directory directory; Collection commitsToDelete; long version; long generation; final boolean isOptimized; public CommitPoint(Collection commitsToDelete, Directory directory, SegmentInfos segmentInfos) throws IOException { this.directory = directory; this.commitsToDelete = commitsToDelete; segmentsFileName = segmentInfos.getCurrentSegmentFileName(); version = segmentInfos.getVersion(); generation = segmentInfos.getGeneration(); int size = segmentInfos.size(); files = new ArrayList(size); files.add(segmentsFileName); gen = segmentInfos.getGeneration(); for(int i=0;i<size;i++) { SegmentInfo segmentInfo = segmentInfos.info(i); if (segmentInfo.dir == directory) { files.addAll(segmentInfo.files()); } } isOptimized = segmentInfos.size() == 1 && !segmentInfos.info(0).hasDeletions(); } public boolean isOptimized() { return isOptimized; } public String getSegmentsFileName() { return segmentsFileName; } public Collection getFileNames() throws IOException { return Collections.unmodifiableCollection(files); } public Directory getDirectory() { return directory; } public long getVersion() { return version; } public long getGeneration() { return generation; } /** * Called only be the deletion policy, to remove this * commit point from the index. */ public void delete() { if (!deleted) { deleted = true; commitsToDelete.add(this); } } public boolean isDeleted() { return deleted; } public int compareTo(Object obj) { CommitPoint commit = (CommitPoint) obj; if (gen < commit.gen) { return -1; } else if (gen > commit.gen) { return 1; } else { return 0; } } }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -