Ejemplo n.º 1
0
        public override void Fill(int fromIndex, int toIndex, long val)
        {
            Debug.Assert(PackedInt32s.BitsRequired(val) <= BitsPerValue);
            Debug.Assert(fromIndex <= toIndex);

            // minimum number of values that use an exact number of full blocks
            int nAlignedValues = 64 / Gcd(64, m_bitsPerValue);
            int span           = toIndex - fromIndex;

            if (span <= 3 * nAlignedValues)
            {
                // there needs be at least 2 * nAlignedValues aligned values for the
                // block approach to be worth trying
                base.Fill(fromIndex, toIndex, val);
                return;
            }

            // fill the first values naively until the next block start
            int fromIndexModNAlignedValues = fromIndex % nAlignedValues;

            if (fromIndexModNAlignedValues != 0)
            {
                for (int i = fromIndexModNAlignedValues; i < nAlignedValues; ++i)
                {
                    Set(fromIndex++, val);
                }
            }
            Debug.Assert(fromIndex % nAlignedValues == 0);

            // compute the long[] blocks for nAlignedValues consecutive values and
            // use them to set as many values as possible without applying any mask
            // or shift
            int nAlignedBlocks = (nAlignedValues * m_bitsPerValue) >> 6;

            long[] nAlignedValuesBlocks;
            {
                Packed64 values = new Packed64(nAlignedValues, m_bitsPerValue);
                for (int i = 0; i < nAlignedValues; ++i)
                {
                    values.Set(i, val);
                }
                nAlignedValuesBlocks = values.blocks;
                Debug.Assert(nAlignedBlocks <= nAlignedValuesBlocks.Length);
            }
            int startBlock = (int)((ulong)((long)fromIndex * m_bitsPerValue) >> 6);
            int endBlock   = (int)((ulong)((long)toIndex * m_bitsPerValue) >> 6);

            for (int block = startBlock; block < endBlock; ++block)
            {
                long blockValue = nAlignedValuesBlocks[block % nAlignedBlocks];
                blocks[block] = blockValue;
            }

            // fill the gap
            for (int i = (int)(((long)endBlock << 6) / m_bitsPerValue); i < toIndex; ++i)
            {
                Set(i, val);
            }
        }
Ejemplo n.º 2
0
        public override void Fill(int fromIndex, int toIndex, long val)
        {
            Debug.Assert(PackedInts.BitsRequired(val) <= BitsPerValue);
            Debug.Assert(fromIndex <= toIndex);

            // minimum number of values that use an exact number of full blocks
            int nAlignedValues = 64 / Gcd(64, bitsPerValue);
            int span = toIndex - fromIndex;
            if (span <= 3 * nAlignedValues)
            {
                // there needs be at least 2 * nAlignedValues aligned values for the
                // block approach to be worth trying
                base.Fill(fromIndex, toIndex, val);
                return;
            }

            // fill the first values naively until the next block start
            int fromIndexModNAlignedValues = fromIndex % nAlignedValues;
            if (fromIndexModNAlignedValues != 0)
            {
                for (int i = fromIndexModNAlignedValues; i < nAlignedValues; ++i)
                {
                    Set(fromIndex++, val);
                }
            }
            Debug.Assert(fromIndex % nAlignedValues == 0);

            // compute the long[] blocks for nAlignedValues consecutive values and
            // use them to set as many values as possible without applying any mask
            // or shift
            int nAlignedBlocks = (nAlignedValues * bitsPerValue) >> 6;
            long[] nAlignedValuesBlocks;
            {
                Packed64 values = new Packed64(nAlignedValues, bitsPerValue);
                for (int i = 0; i < nAlignedValues; ++i)
                {
                    values.Set(i, val);
                }
                nAlignedValuesBlocks = values.Blocks;
                Debug.Assert(nAlignedBlocks <= nAlignedValuesBlocks.Length);
            }
            int startBlock = (int)((ulong)((long)fromIndex * bitsPerValue) >> 6);
            int endBlock = (int)((ulong)((long)toIndex * bitsPerValue) >> 6);
            for (int block = startBlock; block < endBlock; ++block)
            {
                long blockValue = nAlignedValuesBlocks[block % nAlignedBlocks];
                Blocks[block] = blockValue;
            }

            // fill the gap
            for (int i = (int)(((long)endBlock << 6) / bitsPerValue); i < toIndex; ++i)
            {
                Set(i, val);
            }
        }