/// <summary> /// Appends a new packet of buffered deletes to the stream, /// setting its generation: /// </summary> public virtual long Push(FrozenBufferedUpdates packet) { UninterruptableMonitor.Enter(this); try { /* * The insert operation must be atomic. If we let threads increment the gen * and push the packet afterwards we risk that packets are out of order. * With DWPT this is possible if two or more flushes are racing for pushing * updates. If the pushed packets get our of order would loose documents * since deletes are applied to the wrong segments. */ packet.DelGen = nextGen++; if (Debugging.AssertsEnabled) { Debugging.Assert(packet.Any()); Debugging.Assert(CheckDeleteStats()); Debugging.Assert(packet.DelGen < nextGen); Debugging.Assert(updates.Count == 0 || updates[updates.Count - 1].DelGen < packet.DelGen, "Delete packets must be in order"); } updates.Add(packet); numTerms.AddAndGet(packet.numTermDeletes); bytesUsed.AddAndGet(packet.bytesUsed); if (infoStream.IsEnabled("BD")) { infoStream.Message("BD", "push deletes " + packet + " delGen=" + packet.DelGen + " packetCount=" + updates.Count + " totBytesUsed=" + bytesUsed); } if (Debugging.AssertsEnabled) { Debugging.Assert(CheckDeleteStats()); } return(packet.DelGen); } finally { UninterruptableMonitor.Exit(this); } }
public virtual void TestPartiallyAppliedGlobalSlice() { DocumentsWriterDeleteQueue queue = new DocumentsWriterDeleteQueue(); System.Reflection.FieldInfo field = typeof(DocumentsWriterDeleteQueue).GetField("globalBufferLock", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance); ReentrantLock @lock = (ReentrantLock)field.GetValue(queue); @lock.Lock(); var t = new ThreadAnonymousInnerClassHelper(this, queue); t.Start(); t.Join(); @lock.Unlock(); Assert.IsTrue(queue.AnyChanges(), "changes in del queue but not in slice yet"); queue.TryApplyGlobalSlice(); Assert.IsTrue(queue.AnyChanges(), "changes in global buffer"); FrozenBufferedUpdates freezeGlobalBuffer = queue.FreezeGlobalBuffer(null); Assert.IsTrue(freezeGlobalBuffer.Any()); Assert.AreEqual(1, freezeGlobalBuffer.termCount); Assert.IsFalse(queue.AnyChanges(), "all changes applied"); }
protected void FinishFlush(IndexWriter indexWriter, FlushedSegment newSegment, FrozenBufferedUpdates bufferedUpdates) { // Finish the flushed segment and publish it to IndexWriter if (newSegment == null) { if (Debugging.AssertsEnabled) { Debugging.Assert(bufferedUpdates != null); } if (bufferedUpdates != null && bufferedUpdates.Any()) { indexWriter.PublishFrozenUpdates(bufferedUpdates); if (indexWriter.infoStream.IsEnabled("DW")) { indexWriter.infoStream.Message("DW", "flush: push buffered updates: " + bufferedUpdates); } } } else { PublishFlushedSegment(indexWriter, newSegment, bufferedUpdates); } }