/** * Commit changes resulting from delete, undeleteAll, or setNorm operations * * <p>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 */ @Override protected void doCommit(Map<String, String> commitUserData) throws IOException { if (hasChanges) { segmentInfos.setUserData(commitUserData); // Default deleter (for backwards compatibility) is // KeepOnlyLastCommitDeleter: IndexFileDeleter deleter = new IndexFileDeleter( directory, deletionPolicy == null ? new KeepOnlyLastCommitDeletionPolicy() : deletionPolicy, segmentInfos, null, null); segmentInfos.updateGeneration(deleter.getLastSegmentInfos()); segmentInfos.changed(); // Checkpoint the state we are about to change, in // case we have to roll back: startCommit(); final List<SegmentInfo> rollbackSegments = segmentInfos.createBackupSegmentInfos(false); boolean success = false; try { for (int i = 0; i < subReaders.length; i++) subReaders[i].commit(); // Remove segments that contain only 100% deleted // docs: segmentInfos.pruneDeletedSegments(); // Sync all files we just wrote directory.sync(segmentInfos.files(directory, false)); 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(); // Restore all SegmentInfos (in case we pruned some) segmentInfos.rollbackSegmentInfos(rollbackSegments); } } // Have the deleter remove any now unreferenced // files due to this commit: deleter.checkpoint(segmentInfos, true); deleter.close(); maxIndexVersion = segmentInfos.getVersion(); if (writeLock != null) { writeLock.release(); // release write lock writeLock = null; } } hasChanges = false; }
/** * Replaces all segments in this instance, but keeps generation, version, counter so that future * commits remain write once. */ void replace(SegmentInfos other) { rollbackSegmentInfos(other.asList()); lastGeneration = other.lastGeneration; }