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); } }
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); } }