Пример #1
0
 protected internal override void  SetDeleter(IndexFileDeleter deleter)
 {
     // Share deleter to our SegmentReaders:
     this.deleter = deleter;
     for (int i = 0; i < subReaders.Length; i++)
     {
         subReaders[i].SetDeleter(deleter);
     }
 }
Пример #2
0
		/// <summary> 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).
		/// </summary>
		/// <throws>  IOException if there is a low-level IO error </throws>
		protected internal override void  DoCommit()
		{
			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();
					
					bool success = false;
					try
					{
						CommitChanges();
						segmentInfos.Write(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;
		}
Пример #3
0
            public CommitPoint(IndexFileDeleter enclosingInstance, System.Collections.ICollection commitsToDelete, Directory directory, SegmentInfos segmentInfos)
            {
                InitBlock(enclosingInstance);
                this.directory       = directory;
                this.commitsToDelete = commitsToDelete;
                userData             = segmentInfos.GetUserData();
                segmentsFileName     = segmentInfos.GetCurrentSegmentFileName();
                version     = segmentInfos.GetVersion();
                generation  = segmentInfos.GetGeneration();
                files       = segmentInfos.Files(directory, true);
                gen         = segmentInfos.GetGeneration();
                isOptimized = segmentInfos.Count == 1 && !segmentInfos.Info(0).HasDeletions();

                System.Diagnostics.Debug.Assert(!segmentInfos.HasExternalSegments(directory));
            }
Пример #4
0
            public CommitPoint(IndexFileDeleter enclosingInstance, SegmentInfos segmentInfos)
            {
                InitBlock(enclosingInstance);
                segmentsFileName = segmentInfos.GetCurrentSegmentFileName();
                int size = segmentInfos.Count;

                files = new System.Collections.ArrayList(size);
                files.Add(segmentsFileName);
                gen = segmentInfos.GetGeneration();
                for (int i = 0; i < size; i++)
                {
                    SegmentInfo segmentInfo = segmentInfos.Info(i);
                    if (segmentInfo.dir == Enclosing_Instance.directory)
                    {
                        System.Collections.IEnumerator filesEnum = segmentInfo.Files().GetEnumerator();
                        while (filesEnum.MoveNext())
                        {
                            files.Add(filesEnum.Current);
                        }
                    }
                }
            }
            public CommitPoint(IndexFileDeleter enclosingInstance, ICollection <IndexCommitPoint> commitsToDelete, Directory directory, SegmentInfos segmentInfos)
            {
                InitBlock(enclosingInstance);
                this.directory       = directory;
                this.commitsToDelete = commitsToDelete;
                segmentsFileName     = segmentInfos.GetCurrentSegmentFileName();
                version    = segmentInfos.GetVersion();
                generation = segmentInfos.GetGeneration();
                int size = segmentInfos.Count;

                files = new List <string>(size);
                files.Add(segmentsFileName);
                gen = segmentInfos.GetGeneration();
                for (int i = 0; i < size; i++)
                {
                    SegmentInfo segmentInfo = segmentInfos.Info(i);
                    if (segmentInfo.dir == Enclosing_Instance.directory)
                    {
                        SupportClass.CollectionsSupport.AddAll(segmentInfo.Files(), files);
                    }
                }
                isOptimized = segmentInfos.Count == 1 && !segmentInfos.Info(0).HasDeletions();
            }
        /// <summary> 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).
        /// </summary>
        /// <throws>  IOException if there is a low-level IO error </throws>
        protected internal override void DoCommit()
        {
            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();

                    bool success = false;
                    try
                    {
                        CommitChanges();

                        // sync all the files we just wrote
                        for (int i = 0; i < segmentInfos.Count; i++)
                        {
                            SegmentInfo info = segmentInfos.Info(i);
                            IList<string> files = info.Files();
                            for (int j = 0; j < files.Count; j++)
                            {
                                string fileName = files[j];
                                if (!synced.ContainsKey(fileName))
                                {
                                    System.Diagnostics.Debug.Assert(directory.FileExists(fileName));
                                    directory.Sync(fileName);
                                    synced[fileName] = 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;
        }
Пример #7
0
		protected internal override void  SetDeleter(IndexFileDeleter deleter)
		{
			// Share deleter to our SegmentReaders:
			this.deleter = deleter;
			for (int i = 0; i < subReaders.Length; i++)
				subReaders[i].SetDeleter(deleter);
		}
Пример #8
0
        internal readonly Codec Codec; // for writing new segments

        /// <summary>
        /// Constructs a new IndexWriter per the settings given in <code>conf</code>.
        /// If you want to make "live" changes to this writer instance, use
        /// <seealso cref="#getConfig()"/>.
        ///
        /// <p>
        /// <b>NOTE:</b> after ths writer is created, the given configuration instance
        /// cannot be passed to another writer. If you intend to do so, you should
        /// <seealso cref="IndexWriterConfig#clone() clone"/> it beforehand.
        /// </summary>
        /// <param name="d">
        ///          the index directory. The index is either created or appended
        ///          according <code>conf.getOpenMode()</code>. </param>
        /// <param name="conf">
        ///          the configuration settings according to which IndexWriter should
        ///          be initialized. </param>
        /// <exception cref="IOException">
        ///           if the directory cannot be read/written to, or if it does not
        ///           exist and <code>conf.getOpenMode()</code> is
        ///           <code>OpenMode.APPEND</code> or if there is any other low-level
        ///           IO error </exception>
        public IndexWriter(Directory d, IndexWriterConfig conf)
        {
            /*if (!InstanceFieldsInitialized)
            {
                InitializeInstanceFields();
                InstanceFieldsInitialized = true;
            }*/
            readerPool = new ReaderPool(this);
            conf.SetIndexWriter(this); // prevent reuse by other instances
            Config_Renamed = new LiveIndexWriterConfig(conf);
            directory = d;
            analyzer = Config_Renamed.Analyzer;
            infoStream = Config_Renamed.InfoStream;
            mergePolicy = Config_Renamed.MergePolicy;
            mergePolicy.IndexWriter = this;
            mergeScheduler = Config_Renamed.MergeScheduler;
            Codec = Config_Renamed.Codec;

            BufferedUpdatesStream = new BufferedUpdatesStream(infoStream);
            PoolReaders = Config_Renamed.ReaderPooling;

            WriteLock = directory.MakeLock(WRITE_LOCK_NAME);

            if (!WriteLock.Obtain(Config_Renamed.WriteLockTimeout)) // obtain write lock
            {
                throw new LockObtainFailedException("Index locked for write: " + WriteLock);
            }

            bool success = false;
            try
            {
                OpenMode_e? mode = Config_Renamed.OpenMode;
                bool create;
                if (mode == OpenMode_e.CREATE)
                {
                    create = true;
                }
                else if (mode == OpenMode_e.APPEND)
                {
                    create = false;
                }
                else
                {
                    // CREATE_OR_APPEND - create only if an index does not exist
                    create = !DirectoryReader.IndexExists(directory);
                }

                // If index is too old, reading the segments will throw
                // IndexFormatTooOldException.
                segmentInfos = new SegmentInfos();

                bool initialIndexExists = true;

                if (create)
                {
                    // Try to read first.  this is to allow create
                    // against an index that's currently open for
                    // searching.  In this case we write the next
                    // segments_N file with no segments:
                    try
                    {
                        segmentInfos.Read(directory);
                        segmentInfos.Clear();
                    }
                    catch (IOException)
                    {
                        // Likely this means it's a fresh directory
                        initialIndexExists = false;
                    }

                    // Record that we have a change (zero out all
                    // segments) pending:
                    Changed();
                }
                else
                {
                    segmentInfos.Read(directory);

                    IndexCommit commit = Config_Renamed.IndexCommit;
                    if (commit != null)
                    {
                        // Swap out all segments, but, keep metadata in
                        // SegmentInfos, like version & generation, to
                        // preserve write-once.  this is important if
                        // readers are open against the future commit
                        // points.
                        if (commit.Directory != directory)
                        {
                            throw new System.ArgumentException("IndexCommit's directory doesn't match my directory");
                        }
                        SegmentInfos oldInfos = new SegmentInfos();
                        oldInfos.Read(directory, commit.SegmentsFileName);
                        segmentInfos.Replace(oldInfos);
                        Changed();
                        if (infoStream.IsEnabled("IW"))
                        {
                            infoStream.Message("IW", "init: loaded commit \"" + commit.SegmentsFileName + "\"");
                        }
                    }
                }

                RollbackSegments = segmentInfos.CreateBackupSegmentInfos();

                // start with previous field numbers, but new FieldInfos
                GlobalFieldNumberMap = FieldNumberMap;
                Config_Renamed.FlushPolicy.Init(Config_Renamed);
                DocWriter = new DocumentsWriter(this, Config_Renamed, directory);
                eventQueue = DocWriter.EventQueue();

                // Default deleter (for backwards compatibility) is
                // KeepOnlyLastCommitDeleter:
                lock (this)
                {
                    Deleter = new IndexFileDeleter(directory, Config_Renamed.DelPolicy, segmentInfos, infoStream, this, initialIndexExists);
                }

                if (Deleter.StartingCommitDeleted)
                {
                    // Deletion policy deleted the "head" commit point.
                    // We have to mark ourself as changed so that if we
                    // are closed w/o any further changes we write a new
                    // segments_N file.
                    Changed();
                }

                if (infoStream.IsEnabled("IW"))
                {
                    infoStream.Message("IW", "init: create=" + create);
                    MessageState();
                }

                success = true;
            }
            finally
            {
                if (!success)
                {
                    if (infoStream.IsEnabled("IW"))
                    {
                        infoStream.Message("IW", "init: hit exception on init; releasing write lock");
                    }
                    WriteLock.Release();
                    IOUtils.CloseWhileHandlingException(WriteLock);
                    WriteLock = null;
                }
            }
        }
Пример #9
0
		private void  Init(Directory d, Analyzer a, bool create, bool closeDir, IndexDeletionPolicy deletionPolicy, bool autoCommit, int maxFieldLength, IndexingChain indexingChain, IndexCommit commit)
		{
			this.closeDir = closeDir;
			directory = d;
			analyzer = a;
			SetMessageID(defaultInfoStream);
			this.maxFieldLength = maxFieldLength;
			
			if (indexingChain == null)
				indexingChain = DocumentsWriter.DefaultIndexingChain;
			
			if (create)
			{
				// Clear the write lock in case it's leftover:
				directory.ClearLock(WRITE_LOCK_NAME);
			}
			
			Lock writeLock = directory.MakeLock(WRITE_LOCK_NAME);
			if (!writeLock.Obtain(writeLockTimeout))
			// obtain write lock
			{
				throw new LockObtainFailedException("Index locked for write: " + writeLock);
			}
			this.writeLock = writeLock; // save it

            bool success = false;
			try
			{
				if (create)
				{
					// Try to read first.  This is to allow create
					// against an index that's currently open for
					// searching.  In this case we write the next
					// segments_N file with no segments:
					bool doCommit;
					try
					{
						segmentInfos.Read(directory);
						segmentInfos.Clear();
						doCommit = false;
					}
					catch (System.IO.IOException e)
					{
						// Likely this means it's a fresh directory
						doCommit = true;
					}
					
					if (autoCommit || doCommit)
					{
						// Always commit if autoCommit=true, else only
						// commit if there is no segments file in this dir
						// already.
						segmentInfos.Commit(directory);
						SupportClass.CollectionsHelper.AddAllIfNotContains(synced, segmentInfos.Files(directory, true));
					}
					else
					{
						// Record that we have a change (zero out all
						// segments) pending:
						changeCount++;
					}
				}
				else
				{
					segmentInfos.Read(directory);
					
					if (commit != null)
					{
						// Swap out all segments, but, keep metadata in
						// SegmentInfos, like version & generation, to
						// preserve write-once.  This is important if
						// readers are open against the future commit
						// points.
						if (commit.GetDirectory() != directory)
							throw new System.ArgumentException("IndexCommit's directory doesn't match my directory");
						SegmentInfos oldInfos = new SegmentInfos();
						oldInfos.Read(directory, commit.GetSegmentsFileName());
						segmentInfos.Replace(oldInfos);
						changeCount++;
						if (infoStream != null)
							Message("init: loaded commit \"" + commit.GetSegmentsFileName() + "\"");
					}
					
					// We assume that this segments_N was previously
					// properly sync'd:
					SupportClass.CollectionsHelper.AddAllIfNotContains(synced, segmentInfos.Files(directory, true));
				}
				
				this.autoCommit = autoCommit;
				SetRollbackSegmentInfos(segmentInfos);
				
				docWriter = new DocumentsWriter(directory, this, indexingChain);
				docWriter.SetInfoStream(infoStream);
				docWriter.SetMaxFieldLength(maxFieldLength);
				
				// Default deleter (for backwards compatibility) is
				// KeepOnlyLastCommitDeleter:
				deleter = new IndexFileDeleter(directory, deletionPolicy == null?new KeepOnlyLastCommitDeletionPolicy():deletionPolicy, segmentInfos, infoStream, docWriter,synced);
				
				if (deleter.startingCommitDeleted)
				// Deletion policy deleted the "head" commit point.
				// We have to mark ourself as changed so that if we
				// are closed w/o any further changes we write a new
				// segments_N file.
					changeCount++;
				
				PushMaxBufferedDocs();
				
				if (infoStream != null)
				{
					Message("init: create=" + create);
					MessageState();
				}

                success = true;
			}
			finally
			{
                if (!success)
                {
                    if (infoStream != null)
                    {
                        Message("init: hit exception on init; releasing write lock");
                    }
                    try
                    {
                        writeLock.Release();
                    }
                    catch (Exception t)
                    {
                        // don't mask the original exception
                    }
                    writeLock = null;
                }
			}
		}
Пример #10
0
        /// <summary> 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).
        /// 
        /// </summary>
        /// <throws>  IOException if there is a low-level IO error </throws>
        protected internal override void DoCommit(IDictionary<string, string> commitUserData)
        {
            if (hasChanges)
            {
                segmentInfos.UserData = commitUserData;
                // Default deleter (for backwards compatibility) is
                // KeepOnlyLastCommitDeleter:
                var deleter = new IndexFileDeleter(internalDirectory, deletionPolicy ?? new KeepOnlyLastCommitDeletionPolicy(), segmentInfos, null, null, synced);

                segmentInfos.UpdateGeneration(deleter.LastSegmentInfos);

                // Checkpoint the state we are about to change, in
                // case we have to roll back:
                StartCommit();
                
                bool success = false;
                try
                {
                    foreach (SegmentReader t in subReaders)
                    	t.Commit();

                	// Sync all files we just wrote
                    foreach(string fileName in segmentInfos.Files(internalDirectory, false))
                    {
                        if(!synced.Contains(fileName))
                        {
                            System.Diagnostics.Debug.Assert(internalDirectory.FileExists(fileName));
                            internalDirectory.Sync(fileName);
                            synced.Add(fileName);
                        }   
                    }
                    
                    segmentInfos.Commit(internalDirectory);
                    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);
                deleter.Dispose();

                maxIndexVersion = segmentInfos.Version;
                
                if (writeLock != null)
                {
                    writeLock.Release(); // release write lock
                    writeLock = null;
                }
            }
            hasChanges = false;
        }
Пример #11
0
 protected internal virtual void  SetDeleter(IndexFileDeleter deleter)
 {
     this.deleter = deleter;
 }
        /// <summary> 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).
        /// </summary>
        /// <throws>  IOException if there is a low-level IO error </throws>
        protected internal override void DoCommit()
        {
            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();

                    bool success = false;
                    try
                    {
                        CommitChanges();

                        // sync all the files we just wrote
                        for (int i = 0; i < segmentInfos.Count; i++)
                        {
                            SegmentInfo    info  = segmentInfos.Info(i);
                            IList <string> files = info.Files();
                            for (int j = 0; j < files.Count; j++)
                            {
                                string fileName = files[j];
                                if (!synced.ContainsKey(fileName))
                                {
                                    System.Diagnostics.Debug.Assert(directory.FileExists(fileName));
                                    directory.Sync(fileName);
                                    synced[fileName] = 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;
        }
Пример #13
0
		protected internal virtual void  SetDeleter(IndexFileDeleter deleter)
		{
			this.deleter = deleter;
		}
Пример #14
0
            public CommitPoint(IndexFileDeleter enclosingInstance, System.Collections.ICollection commitsToDelete, Directory directory, SegmentInfos segmentInfos)
            {
                InitBlock(enclosingInstance);
                this.directory = directory;
                this.commitsToDelete = commitsToDelete;
                userData = segmentInfos.GetUserData();
                segmentsFileName = segmentInfos.GetCurrentSegmentFileName();
                version = segmentInfos.GetVersion();
                generation = segmentInfos.GetGeneration();
                files = segmentInfos.Files(directory, true);
                gen = segmentInfos.GetGeneration();
                isOptimized = segmentInfos.Count == 1 && !segmentInfos.Info(0).HasDeletions();

                System.Diagnostics.Debug.Assert(!segmentInfos.HasExternalSegments(directory));
            }
Пример #15
0
 public CommitPoint(IndexFileDeleter enclosingInstance, ICollection<IndexCommitPoint> commitsToDelete, Directory directory, SegmentInfos segmentInfos)
 {
     InitBlock(enclosingInstance);
     this.directory = directory;
     this.commitsToDelete = commitsToDelete;
     segmentsFileName = segmentInfos.GetCurrentSegmentFileName();
     version = segmentInfos.GetVersion();
     generation = segmentInfos.GetGeneration();
     int size = segmentInfos.Count;
     files = new List<string>(size);
     files.Add(segmentsFileName);
     gen = segmentInfos.GetGeneration();
     for (int i = 0; i < size; i++)
     {
         SegmentInfo segmentInfo = segmentInfos.Info(i);
         if (segmentInfo.dir == Enclosing_Instance.directory)
         {
             SupportClass.CollectionsSupport.AddAll(segmentInfo.Files(), files);
         }
     }
     isOptimized = segmentInfos.Count == 1 && !segmentInfos.Info(0).HasDeletions();
 }
Пример #16
0
		private void  Init(Directory d, Analyzer a, bool create, bool closeDir)
		{
			this.closeDir = closeDir;
			directory = d;
			analyzer = a;
			
			if (create)
			{
				// Clear the write lock in case it's leftover:
				directory.ClearLock(IndexWriter.WRITE_LOCK_NAME);
			}
			
			Lock writeLock = directory.MakeLock(IndexWriter.WRITE_LOCK_NAME);
			if (!writeLock.Obtain(writeLockTimeout))
			// obtain write lock
			{
				throw new System.IO.IOException("Index locked for write: " + writeLock);
			}
			this.writeLock = writeLock; // save it
			
			try
			{
				if (create)
				{
					// Try to read first. This is to allow create
					// against an index that's currently open for
					// searching. In this case we write the next
					// segments_N file with no segments:
					try
					{
						segmentInfos.Read(directory);
						segmentInfos.Clear();
					}
					catch (System.IO.IOException e)
					{
						// Likely this means it's a fresh directory
					}
					segmentInfos.Write(directory);
				}
				else
				{
					segmentInfos.Read(directory);
				}
				
				// Create a deleter to keep track of which files can
				// be deleted:
				deleter = new IndexFileDeleter(segmentInfos, directory);
				deleter.SetInfoStream(infoStream);
				deleter.FindDeletableFiles();
				deleter.DeleteFiles();
			}
			catch (System.IO.IOException e)
			{
				this.writeLock.Release();
				this.writeLock = null;
				throw e;
			}
		}
Пример #17
0
		private void  Init(Directory d, Analyzer a, bool create, bool closeDir, IndexDeletionPolicy deletionPolicy, bool autoCommit)
		{
			this.closeDir = closeDir;
			directory = d;
			analyzer = a;
			this.infoStream = defaultInfoStream;
			SetMessageID();
			
			if (create)
			{
				// Clear the write lock in case it's leftover:
				directory.ClearLock(IndexWriter.WRITE_LOCK_NAME);
			}
			
			Lock writeLock = directory.MakeLock(IndexWriter.WRITE_LOCK_NAME);
			if (!writeLock.Obtain(writeLockTimeout))
			// obtain write lock
			{
				throw new LockObtainFailedException("Index locked for write: " + writeLock);
			}
			this.writeLock = writeLock; // save it
			
			try
			{
				if (create)
				{
					// Try to read first.  This is to allow create
					// against an index that's currently open for
					// searching.  In this case we write the next
					// segments_N file with no segments:
					try
					{
						segmentInfos.Read(directory);
						segmentInfos.Clear();
					}
					catch (System.IO.IOException e)
					{
						// Likely this means it's a fresh directory
					}
					segmentInfos.Write(directory);
				}
				else
				{
					segmentInfos.Read(directory);
				}
				
				this.autoCommit = autoCommit;
				if (!autoCommit)
				{
					rollbackSegmentInfos = (SegmentInfos) segmentInfos.Clone();
				}
				
				docWriter = new DocumentsWriter(directory, this);
				docWriter.SetInfoStream(infoStream);
				
				// Default deleter (for backwards compatibility) is
				// KeepOnlyLastCommitDeleter:
				deleter = new IndexFileDeleter(directory, deletionPolicy == null ? new KeepOnlyLastCommitDeletionPolicy() : deletionPolicy, segmentInfos, infoStream, docWriter);
				
				PushMaxBufferedDocs();
				
				if (infoStream != null)
				{
					Message("init: create=" + create);
					MessageState();
				}
			}
			catch (System.IO.IOException e)
			{
				this.writeLock.Release();
				this.writeLock = null;
				throw e;
			}
		}
Пример #18
0
 private void  InitBlock(IndexFileDeleter enclosingInstance)
 {
     this.enclosingInstance = enclosingInstance;
 }
Пример #19
0
		public virtual void  TestDiskFull()
		{
			
			bool debug = false;
			Term searchTerm = new Term("content", "aaa");
			int START_COUNT = 157;
			int END_COUNT = 144;
			
			// First build up a starting index:
			RAMDirectory startDir = new MockRAMDirectory();
			IndexWriter writer = new IndexWriter(startDir, new WhitespaceAnalyzer(), true);
			for (int i = 0; i < 157; i++)
			{
				Lucene.Net.Documents.Document d = new Lucene.Net.Documents.Document();
				d.Add(new Field("id", System.Convert.ToString(i), Field.Store.YES, Field.Index.UN_TOKENIZED));
				d.Add(new Field("content", "aaa " + i, Field.Store.NO, Field.Index.TOKENIZED));
				writer.AddDocument(d);
			}
			writer.Close();
			
			long diskUsage = startDir.SizeInBytes();
			long diskFree = diskUsage + 100;
			
			System.IO.IOException err = null;
			
			bool done = false;
			
			// Iterate w/ ever increasing free disk space:
			while (!done)
			{
				MockRAMDirectory dir = new MockRAMDirectory(startDir);
				IndexReader reader = IndexReader.Open(dir);
				
				// For each disk size, first try to commit against
				// dir that will hit random IOExceptions & disk
				// full; after, give it infinite disk space & turn
				// off random IOExceptions & retry w/ same reader:
				bool success = false;
				
				for (int x = 0; x < 2; x++)
				{
					
					double rate = 0.05;
					double diskRatio = ((double) diskFree) / diskUsage;
					long thisDiskFree;
					System.String testName;
					
					if (0 == x)
					{
						thisDiskFree = diskFree;
						if (diskRatio >= 2.0)
						{
							rate /= 2;
						}
						if (diskRatio >= 4.0)
						{
							rate /= 2;
						}
						if (diskRatio >= 6.0)
						{
							rate = 0.0;
						}
						if (debug)
						{
							System.Console.Out.WriteLine("\ncycle: " + diskFree + " bytes");
						}
						testName = "disk full during reader.Close() @ " + thisDiskFree + " bytes";
					}
					else
					{
						thisDiskFree = 0;
						rate = 0.0;
						if (debug)
						{
							System.Console.Out.WriteLine("\ncycle: same writer: unlimited disk space");
						}
						testName = "reader re-use after disk full";
					}
					
					dir.SetMaxSizeInBytes(thisDiskFree);
					dir.SetRandomIOExceptionRate(rate, diskFree);
					
					try
					{
						if (0 == x)
						{
							int docId = 12;
							for (int i = 0; i < 13; i++)
							{
								reader.DeleteDocument(docId);
								reader.SetNorm(docId, "contents", (float) 2.0);
								docId += 12;
							}
						}
						reader.Close();
						success = true;
						if (0 == x)
						{
							done = true;
						}
					}
					catch (System.IO.IOException e)
					{
						if (debug)
						{
							System.Console.Out.WriteLine("  hit IOException: " + e);
						}
						err = e;
						if (1 == x)
						{
							System.Console.Error.WriteLine(e.StackTrace);
							Assert.Fail(testName + " hit IOException after disk space was freed up");
						}
					}
					
					// Whether we succeeded or failed, check that all
					// un-referenced files were in fact deleted (ie,
					// we did not create garbage).  Just create a
					// new IndexFileDeleter, have it delete
					// unreferenced files, then verify that in fact
					// no files were deleted:
					System.String[] startFiles = dir.List();
					SegmentInfos infos = new SegmentInfos();
					infos.Read(dir);
					IndexFileDeleter d = new IndexFileDeleter(dir, new KeepOnlyLastCommitDeletionPolicy(), infos, null, null);
					System.String[] endFiles = dir.List();
					
					System.Array.Sort(startFiles);
					System.Array.Sort(endFiles);
					
					//for(int i=0;i<startFiles.length;i++) {
					//  System.out.println("  startFiles: " + i + ": " + startFiles[i]);
					//}
					
					if (SupportClass.Compare.CompareStringArrays(startFiles, endFiles) == false)
					{
						System.String successStr;
						if (success)
						{
							successStr = "success";
						}
						else
						{
							successStr = "IOException";
							System.Console.Error.WriteLine(err.StackTrace);
						}
						Assert.Fail("reader.Close() failed to delete unreferenced files after " + successStr + " (" + diskFree + " bytes): before delete:\n    " + ArrayToString(startFiles) + "\n  after delete:\n    " + ArrayToString(endFiles));
					}
					
					// Finally, verify index is not corrupt, and, if
					// we succeeded, we see all docs changed, and if
					// we failed, we see either all docs or no docs
					// changed (transactional semantics):
					IndexReader newReader = null;
					try
					{
						newReader = IndexReader.Open(dir);
					}
					catch (System.IO.IOException e)
					{
						System.Console.Error.WriteLine(e.StackTrace);
						Assert.Fail(testName + ":exception when creating IndexReader after disk full during Close: " + e);
					}
					/*
					int result = newReader.docFreq(searchTerm);
					if (success) {
					if (result != END_COUNT) {
					fail(testName + ": method did not throw exception but docFreq('aaa') is " + result + " instead of expected " + END_COUNT);
					}
					} else {
					// On hitting exception we still may have added
					// all docs:
					if (result != START_COUNT && result != END_COUNT) {
					err.printStackTrace();
					fail(testName + ": method did throw exception but docFreq('aaa') is " + result + " instead of expected " + START_COUNT + " or " + END_COUNT);
					}
					}
					*/
					
					IndexSearcher searcher = new IndexSearcher(newReader);
					Hits hits = null;
					try
					{
						hits = searcher.Search(new TermQuery(searchTerm));
					}
					catch (System.IO.IOException e)
					{
						System.Console.Error.WriteLine(e.StackTrace);
						Assert.Fail(testName + ": exception when searching: " + e);
					}
					int result2 = hits.Length();
					if (success)
					{
						if (result2 != END_COUNT)
						{
							Assert.Fail(testName + ": method did not throw exception but hits.length for search on term 'aaa' is " + result2 + " instead of expected " + END_COUNT);
						}
					}
					else
					{
						// On hitting exception we still may have added
						// all docs:
						if (result2 != START_COUNT && result2 != END_COUNT)
						{
							System.Console.Error.WriteLine(err.StackTrace);
							Assert.Fail(testName + ": method did throw exception but hits.length for search on term 'aaa' is " + result2 + " instead of expected " + START_COUNT);
						}
					}
					
					searcher.Close();
					newReader.Close();
					
					if (result2 == END_COUNT)
					{
						break;
					}
				}
				
				dir.Close();
				
				// Try again with 10 more bytes of free space:
				diskFree += 10;
			}
			
			startDir.Close();
		}
Пример #20
0
        private void Init(Directory d, Analyzer a, bool create, bool closeDir, IndexDeletionPolicy deletionPolicy, bool autoCommit, int maxFieldLength)
        {
            this.closeDir = closeDir;
            directory = d;
            analyzer = a;
            SetMessageID(defaultInfoStream);
            this.maxFieldLength = maxFieldLength;

            if (create)
            {
                // Clear the write lock in case it's leftover:
                directory.ClearLock(WRITE_LOCK_NAME);
            }

            Lock writeLock = directory.MakeLock(WRITE_LOCK_NAME);
            if (!writeLock.Obtain(writeLockTimeout))
            // obtain write lock
            {
                throw new LockObtainFailedException("Index locked for write: " + writeLock);
            }
            this.writeLock = writeLock; // save it

            try
            {
                if (create)
                {
                    // Try to read first.  This is to allow create
                    // against an index that's currently open for
                    // searching.  In this case we write the next
                    // segments_N file with no segments:
                    try
                    {
                        segmentInfos.Read(directory);
                        segmentInfos.Clear();
                    }
                    catch (System.IO.IOException)
                    {
                        // Likely this means it's a fresh directory
                    }
                    segmentInfos.Commit(directory);
                }
                else
                {
                    segmentInfos.Read(directory);

                    // We assume that this segments_N was previously
                    // properly sync'd:
                    for (int i = 0; i < segmentInfos.Count; i++)
                    {
                        SegmentInfo info = segmentInfos.Info(i);
                        List<string> files = info.Files();
                        for (int j = 0; j < files.Count; j++)
                            synced[files[j]] = files[j];
                    }
                }

                this.autoCommit = autoCommit;
                SetRollbackSegmentInfos(segmentInfos);

                docWriter = new DocumentsWriter(directory, this);
                docWriter.SetInfoStream(infoStream);
                docWriter.SetMaxFieldLength(maxFieldLength);

                // Default deleter (for backwards compatibility) is
                // KeepOnlyLastCommitDeleter:
                deleter = new IndexFileDeleter(directory, deletionPolicy == null ? new KeepOnlyLastCommitDeletionPolicy() : deletionPolicy, segmentInfos, infoStream, docWriter);

                PushMaxBufferedDocs();

                if (infoStream != null)
                {
                    Message("init: create=" + create);
                    MessageState();
                }
            }
            catch (System.IO.IOException e)
            {
                this.writeLock.Release();
                this.writeLock = null;
                throw e;
            }
        }
Пример #21
0
			public CommitPoint(IndexFileDeleter enclosingInstance, SegmentInfos segmentInfos)
			{
				InitBlock(enclosingInstance);
				segmentsFileName = segmentInfos.GetCurrentSegmentFileName();
				int size = segmentInfos.Count;
				files = new System.Collections.ArrayList(size);
				files.Add(segmentsFileName);
				gen = segmentInfos.GetGeneration();
				for (int i = 0; i < size; i++)
				{
					SegmentInfo segmentInfo = segmentInfos.Info(i);
					if (segmentInfo.dir == Enclosing_Instance.directory)
					{
                        System.Collections.IEnumerator filesEnum = segmentInfo.Files().GetEnumerator();
                        while (filesEnum.MoveNext())
                        {
                            files.Add(filesEnum.Current);
                        }
					}
				}
			}
Пример #22
0
 private void InitBlock(IndexFileDeleter enclosingInstance)
 {
     this.enclosingInstance = enclosingInstance;
 }
Пример #23
0
        /// <summary> 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).
        /// 
        /// </summary>
        /// <throws>  IOException if there is a low-level IO error </throws>
        protected internal override void DoCommit(System.Collections.IDictionary commitUserData)
        {
            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);

                // Checkpoint the state we are about to change, in
                // case we have to roll back:
                StartCommit();

                bool success = false;
                try
                {
                    for (int i = 0; i < subReaders.Length; i++)
                        subReaders[i].Commit();

                    // Sync all files we just wrote
                    System.Collections.IEnumerator it = segmentInfos.Files(directory, false).GetEnumerator();
                    while (it.MoveNext())
                    {
                        System.String fileName = (string)((System.Collections.DictionaryEntry) it.Current).Value;
                        if (!synced.Contains(fileName))
                        {
                            System.Diagnostics.Debug.Assert(directory.FileExists(fileName));
                            directory.Sync(fileName);
                            SupportClass.CollectionsHelper.AddIfNotContains(synced, 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);
                deleter.Close();

                if (writeLock != null)
                {
                    writeLock.Release(); // release write lock
                    writeLock = null;
                }
            }
            hasChanges = false;
        }