internal ReaderCommit(SegmentInfos infos, Directory dir)
 {
     segmentsFileName = infos.GetSegmentsFileName();
     this.dir         = dir;
     userData         = infos.UserData;
     files            = infos.GetFiles(dir, true);
     generation       = infos.Generation;
     segmentCount     = infos.Count;
 }
Beispiel #2
0
 public CommitPoint(ICollection <CommitPoint> commitsToDelete, Directory directory, SegmentInfos segmentInfos)
 {
     this.directory       = directory;
     this.commitsToDelete = commitsToDelete;
     userData             = segmentInfos.UserData;
     segmentsFileName     = segmentInfos.GetSegmentsFileName();
     generation           = segmentInfos.Generation;
     files        = segmentInfos.GetFiles(directory, true);
     segmentCount = segmentInfos.Count;
 }
Beispiel #3
0
        /// <summary>
        /// Initialize the deleter: find all previous commits in
        /// the <see cref="Directory"/>, incref the files they reference, call
        /// the policy to let it delete commits.  this will remove
        /// any files not referenced by any of the commits. </summary>
        /// <exception cref="IOException"> if there is a low-level IO error </exception>
        public IndexFileDeleter(Directory directory, IndexDeletionPolicy policy, SegmentInfos segmentInfos, InfoStream infoStream, IndexWriter writer, bool initialIndexExists)
        {
            this.infoStream = infoStream;
            this.writer     = writer;

            string currentSegmentsFile = segmentInfos.GetSegmentsFileName();

            if (infoStream.IsEnabled("IFD"))
            {
                infoStream.Message("IFD", "init: current segments file is \"" + currentSegmentsFile + "\"; deletionPolicy=" + policy);
            }

            this.policy    = policy;
            this.directory = directory;

            // First pass: walk the files and initialize our ref
            // counts:
            long currentGen = segmentInfos.Generation;

            CommitPoint currentCommitPoint = null;

            string[] files = null;
            try
            {
                files = directory.ListAll();
            }
#pragma warning disable 168
            catch (DirectoryNotFoundException e)
#pragma warning restore 168
            {
                // it means the directory is empty, so ignore it.
                files = new string[0];
            }

            if (currentSegmentsFile != null)
            {
                Regex r = IndexFileNames.CODEC_FILE_PATTERN;
                foreach (string fileName in files)
                {
                    if (!fileName.EndsWith("write.lock", StringComparison.Ordinal) && !fileName.Equals(IndexFileNames.SEGMENTS_GEN, StringComparison.Ordinal) &&
                        (r.IsMatch(fileName) || fileName.StartsWith(IndexFileNames.SEGMENTS, StringComparison.Ordinal)))
                    {
                        // Add this file to refCounts with initial count 0:
                        GetRefCount(fileName);

                        if (fileName.StartsWith(IndexFileNames.SEGMENTS, StringComparison.Ordinal))
                        {
                            // this is a commit (segments or segments_N), and
                            // it's valid (<= the max gen).  Load it, then
                            // incref all files it refers to:
                            if (infoStream.IsEnabled("IFD"))
                            {
                                infoStream.Message("IFD", "init: load commit \"" + fileName + "\"");
                            }
                            SegmentInfos sis = new SegmentInfos();
                            try
                            {
                                sis.Read(directory, fileName);
                            }
#pragma warning disable 168
                            catch (FileNotFoundException e)
#pragma warning restore 168
                            {
                                // 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
                                if (infoStream.IsEnabled("IFD"))
                                {
                                    infoStream.Message("IFD", "init: hit FileNotFoundException when loading commit \"" + fileName + "\"; skipping this commit point");
                                }
                                sis = null;
                            }
                            // LUCENENET specific - .NET (thankfully) only has one FileNotFoundException, so we don't need this
                            //catch (NoSuchFileException)
                            //{
                            //    // 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
                            //    if (infoStream.IsEnabled("IFD"))
                            //    {
                            //        infoStream.Message("IFD", "init: hit FileNotFoundException when loading commit \"" + fileName + "\"; skipping this commit point");
                            //    }
                            //    sis = null;
                            //}
                            // LUCENENET specific - since NoSuchDirectoryException subclasses FileNotFoundException
                            // in Lucene, we need to catch it here to be on the safe side.
                            catch (System.IO.DirectoryNotFoundException)
                            {
                                // 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
                                if (infoStream.IsEnabled("IFD"))
                                {
                                    infoStream.Message("IFD", "init: hit FileNotFoundException when loading commit \"" + fileName + "\"; skipping this commit point");
                                }
                                sis = null;
                            }
                            catch (IOException /*e*/)
                            {
                                if (SegmentInfos.GenerationFromSegmentsFileName(fileName) <= currentGen && directory.FileLength(fileName) > 0)
                                {
                                    throw; // LUCENENET: CA2200: Rethrow to preserve stack details (https://docs.microsoft.com/en-us/visualstudio/code-quality/ca2200-rethrow-to-preserve-stack-details)
                                }
                                else
                                {
                                    // Most likely we are opening an index that
                                    // has an aborted "future" commit, so suppress
                                    // exc in this case
                                    sis = null;
                                }
                            }
                            if (sis != null)
                            {
                                CommitPoint commitPoint = new CommitPoint(commitsToDelete, directory, sis);
                                if (sis.Generation == segmentInfos.Generation)
                                {
                                    currentCommitPoint = commitPoint;
                                }
                                commits.Add(commitPoint);
                                IncRef(sis, true);

                                if (lastSegmentInfos == null || sis.Generation > lastSegmentInfos.Generation)
                                {
                                    lastSegmentInfos = sis;
                                }
                            }
                        }
                    }
                }
            }

            if (currentCommitPoint == null && currentSegmentsFile != null && initialIndexExists)
            {
                // We did not in fact see the segments_N file
                // corresponding to the segmentInfos that was passed
                // in.  Yet, it must exist, because our caller holds
                // the write lock.  this can happen when the directory
                // listing was stale (eg when index accessed via NFS
                // client with stale directory listing cache).  So we
                // try now to explicitly open this commit point:
                SegmentInfos sis = new SegmentInfos();
                try
                {
                    sis.Read(directory, currentSegmentsFile);
                }
                catch (IOException e)
                {
                    throw new CorruptIndexException("failed to locate current segments_N file \"" + currentSegmentsFile + "\"" + e.ToString(), e);
                }
                if (infoStream.IsEnabled("IFD"))
                {
                    infoStream.Message("IFD", "forced open of current segments file " + segmentInfos.GetSegmentsFileName());
                }
                currentCommitPoint = new CommitPoint(commitsToDelete, directory, sis);
                commits.Add(currentCommitPoint);
                IncRef(sis, true);
            }

            // We keep commits list in sorted order (oldest to newest):
            CollectionUtil.TimSort(commits);

            // Now delete anything with ref count at 0.  These are
            // presumably abandoned files eg due to crash of
            // IndexWriter.
            foreach (KeyValuePair <string, RefCount> entry in refCounts)
            {
                RefCount rc       = entry.Value;
                string   fileName = entry.Key;
                if (0 == rc.count)
                {
                    if (infoStream.IsEnabled("IFD"))
                    {
                        infoStream.Message("IFD", "init: removing unreferenced file \"" + fileName + "\"");
                    }
                    DeleteFile(fileName);
                }
            }

            // Finally, give policy a chance to remove things on
            // startup:
            this.policy.OnInit(commits);

            // Always protect the incoming segmentInfos since
            // sometime it may not be the most recent commit
            Checkpoint(segmentInfos, false);

            startingCommitDeleted = currentCommitPoint == null ? false : currentCommitPoint.IsDeleted;

            DeleteCommits();
        }