Lucene.Net.Index.DocumentsWriter.BalanceRAM C# (CSharp) Method

BalanceRAM() private method

private BalanceRAM ( ) : void
return void
		internal void  BalanceRAM()
		{
			
			// We flush when we've used our target usage
			long flushTrigger = ramBufferSize;
			
			long deletesRAMUsed = deletesInRAM.bytesUsed + deletesFlushed.bytesUsed;
			
			if (numBytesAlloc + deletesRAMUsed > freeTrigger)
			{
				
				if (infoStream != null)
					Message(
                        "  RAM: now balance allocations: usedMB=" + ToMB(numBytesUsed) + 
                        " vs trigger=" + ToMB(flushTrigger) + 
                        " allocMB=" + ToMB(numBytesAlloc) + 
                        " deletesMB=" + ToMB(deletesRAMUsed) + 
                        " vs trigger=" + ToMB(freeTrigger) + 
                        " byteBlockFree=" + ToMB(byteBlockAllocator.freeByteBlocks.Count * BYTE_BLOCK_SIZE) +
                        " perDocFree=" + ToMB(perDocAllocator.freeByteBlocks.Count * PER_DOC_BLOCK_SIZE) +
                        " charBlockFree=" + ToMB(freeCharBlocks.Count * CHAR_BLOCK_SIZE * CHAR_NUM_BYTE));
				
				long startBytesAlloc = numBytesAlloc + deletesRAMUsed;
				
				int iter = 0;
				
				// We free equally from each pool in 32 KB
				// chunks until we are below our threshold
				// (freeLevel)
				
				bool any = true;
				
				while (numBytesAlloc + deletesRAMUsed > freeLevel)
				{
					
					lock (this)
					{
                        if (0 == perDocAllocator.freeByteBlocks.Count
                              && 0 == byteBlockAllocator.freeByteBlocks.Count
                              && 0 == freeCharBlocks.Count
                              && 0 == freeIntBlocks.Count
                              && !any)
						{
							// Nothing else to free -- must flush now.
							bufferIsFull = numBytesUsed + deletesRAMUsed > flushTrigger;
							if (infoStream != null)
							{
                                if (bufferIsFull)
									Message("    nothing to free; now set bufferIsFull");
								else
									Message("    nothing to free");
							}
							System.Diagnostics.Debug.Assert(numBytesUsed <= numBytesAlloc);
							break;
						}
						
						if ((0 == iter % 5) && byteBlockAllocator.freeByteBlocks.Count > 0)
						{
							byteBlockAllocator.freeByteBlocks.RemoveAt(byteBlockAllocator.freeByteBlocks.Count - 1);
							numBytesAlloc -= BYTE_BLOCK_SIZE;
						}
						
						if ((1 == iter % 5) && freeCharBlocks.Count > 0)
						{
							freeCharBlocks.RemoveAt(freeCharBlocks.Count - 1);
							numBytesAlloc -= CHAR_BLOCK_SIZE * CHAR_NUM_BYTE;
						}
						
						if ((2 == iter % 5) && freeIntBlocks.Count > 0)
						{
							freeIntBlocks.RemoveAt(freeIntBlocks.Count - 1);
							numBytesAlloc -= INT_BLOCK_SIZE * INT_NUM_BYTE;
						}

                        if ((3 == iter % 5) && perDocAllocator.freeByteBlocks.Count > 0)
                        {
                            // Remove upwards of 32 blocks (each block is 1K)
                            for (int i = 0; i < 32; ++i)
                            {
                                perDocAllocator.freeByteBlocks.RemoveAt(perDocAllocator.freeByteBlocks.Count - 1);
                                numBytesAlloc -= PER_DOC_BLOCK_SIZE;
                                if (perDocAllocator.freeByteBlocks.Count == 0)
                                {
                                    break;
                                }
                            }
                        }
					}
					
					if ((4 == iter % 5) && any)
					// Ask consumer to free any recycled state
						any = consumer.FreeRAM();
					
					iter++;
				}
				
				if (infoStream != null)
					Message(System.String.Format(nf, "    after free: freedMB={0:f} usedMB={1:f} allocMB={2:f}",
						new System.Object[] { ((startBytesAlloc - numBytesAlloc) / 1024.0 / 1024.0), (numBytesUsed / 1024.0 / 1024.0), (numBytesAlloc / 1024.0 / 1024.0) }));
            }
			else
			{
				// If we have not crossed the 100% mark, but have
				// crossed the 95% mark of RAM we are actually
				// using, go ahead and flush.  This prevents
				// over-allocating and then freeing, with every
				// flush.
				lock (this)
				{
					
					if (numBytesUsed + deletesRAMUsed > flushTrigger)
					{
						if (infoStream != null)
							Message(System.String.Format(nf, "  RAM: now flush @ usedMB={0:f} allocMB={1:f} triggerMB={2:f}",
								new object[] { (numBytesUsed / 1024.0 / 1024.0), (numBytesAlloc / 1024.0 / 1024.0), (flushTrigger / 1024.0 / 1024.0) }));
						
						bufferIsFull = true;
					}
				}
			}
		}