示例#1
0
        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;
        }
示例#2
0
        /// <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);
        }