예제 #1
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));
            }
예제 #2
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));
			}
예제 #3
0
 private void InitBlock(IndexFileDeleter enclosingInstance)
 {
     this.enclosingInstance = enclosingInstance;
 }
예제 #4
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.Generic.IDictionary<string, string> 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, synced);

                segmentInfos.UpdateGeneration(deleter.GetLastSegmentInfos());

				// 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
                    foreach(string fileName in segmentInfos.Files(directory, false))
                    {
                        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);
				deleter.Close();

                maxIndexVersion = segmentInfos.GetVersion();
				
				if (writeLock != null)
				{
					writeLock.Release(); // release write lock
					writeLock = null;
				}
			}
			hasChanges = false;
		}
예제 #5
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;
                }
			}
		}
예제 #6
0
 private void InitBlock(IndexFileDeleter enclosingInstance)
 {
     this.enclosingInstance = enclosingInstance;
 }