private void InternalInitializeToNewCapacity(int newCapacity, BufferInitializer initializer, bool initializeSequentially) { Resize(newCapacity / m_entriesPerBuffer); Action <int> initBuffer = bufferNumber => { m_entryBuffers[bufferNumber] = initializer != null ? initializer(bufferNumber *m_entriesPerBuffer, m_entriesPerBuffer) : new TEntry[m_entriesPerBuffer]; }; var start = m_capacity / m_entriesPerBuffer; var end = newCapacity / m_entriesPerBuffer; var count = end - start; if ((count > 16 || (count > 1 && initializer != null)) && !initializeSequentially) { // parallelization initialization of buffers brings significant improvement during deserialization where big buffer sizes are known beforehand // (seen initialization of directed graph edges speed up from 300ms to 90ms) Parallel.For(start, end, initBuffer); } else { for (int bufferNumber = start; bufferNumber < end; bufferNumber++) { initBuffer(bufferNumber); } } m_capacity = newCapacity; }
/// <summary> /// Ensures that the buffer has the given capacity /// NOTE: This method must be called prior to getting or setting entries in the buffer /// </summary> /// <param name="minimumCapacity">Minimum capacity</param> /// <param name="initializer">Optional initializer for new buffers</param> /// <param name="initializeSequentially">Whether the initializer needs to run sequentially</param> /// <returns>Actual new capacity</returns> public int Initialize(int minimumCapacity, BufferInitializer initializer = null, bool initializeSequentially = false) { if (m_capacity < minimumCapacity) { lock (m_syncRoot) { var currentCapacity = m_capacity; var newCapacity = checked (minimumCapacity + m_entriesPerBuffer - 1) & ~m_entriesPerBufferMask; if (currentCapacity < newCapacity) { // No more entry buffers. We need to allocate more. // At least twice as many, but maybe more depending on requested capacity newCapacity = Math.Max(m_entryBuffers.Length * m_entriesPerBuffer * 2, newCapacity); InternalInitializeToNewCapacity(newCapacity, initializer, initializeSequentially); } } } return(m_capacity); }