asmirnov82 commented on code in PR #35342:
URL: https://github.com/apache/arrow/pull/35342#discussion_r1190313750


##########
csharp/src/Apache.Arrow/BitUtility.cs:
##########
@@ -62,73 +62,154 @@ public static void SetBit(Span<byte> data, int index, bool 
value)
                 : (byte)(data[idx] & ~BitMask[mod]);
         }
 
+        /// <summary>
+        /// Set the number of bits in a span of bytes starting
+        /// at a specific index, and limiting to length.
+        /// </summary>
+        /// <param name="data">Span to set bits value.</param>
+        /// <param name="index">Bit index to start counting from.</param>
+        /// <param name="length">Maximum of bits in the span to 
consider.</param>
+        public static void SetBits(Span<byte> data, int index, int length, 
bool value)
+        {
+            if (length == 0)
+                return;
+
+            long spanLengthInBits = (long)data.Length * 8;
+
+            if (index < 0 || index >= spanLengthInBits)
+                throw new ArgumentOutOfRangeException(nameof(index));
+
+            int endBitIndex = checked(index + length - 1);
+
+            if (length < 0 || endBitIndex >= spanLengthInBits)
+                throw new ArgumentOutOfRangeException(nameof(length));
+
+            // Use simpler method if there aren't many values
+            if (length < 20)
+            {
+                for (int i = index; i <= endBitIndex; i++)
+                {
+                    SetBit(data, i, value);
+                }
+                return;
+            }
+            
+            // Otherwise do the work to figure out how to copy whole bytes
+            int startByteIndex = index / 8;
+            int startBitOffset = index % 8;
+            int endByteIndex = endBitIndex / 8;
+            int endBitOffset = endBitIndex % 8;
+                        
+            // If the starting index and ending index are not byte-aligned,
+            // we'll need to set bits the slow way. If they are
+            // byte-aligned, and for all other bytes in the 'middle', we
+            // can use a faster byte-aligned set.
+            int fullByteStartIndex = startBitOffset == 0 ? startByteIndex : 
startByteIndex + 1;
+            int fullByteEndIndex = endBitOffset == 7 ? endByteIndex : 
endByteIndex - 1;
+
+            // Bits we will be using to finish up the first byte
+            if (startBitOffset != 0)
+            {
+                Span<byte> slice = data.Slice(startByteIndex, 1);
+                for (int i = startBitOffset; i <= 7; i++)
+                    SetBit(slice, i, value);
+            }
+
+            if (fullByteEndIndex >= fullByteStartIndex)
+            {
+                Span<byte> slice = data.Slice(fullByteStartIndex, 
fullByteEndIndex - fullByteStartIndex + 1);
+                byte fill = (byte)(value ? 0xFF : 0x00);
+
+                slice.Fill(fill);
+            }
+
+            if (endBitOffset != 7)
+            {
+                Span<byte> slice = data.Slice(endByteIndex, 1);
+                for (int i = 0; i <= endBitOffset; i++)
+                    SetBit(slice, i, value);
+            }
+        }
+
         public static void ToggleBit(Span<byte> data, int index)
         {
             data[index / 8] ^= BitMask[index % 8];
         }
 
         /// <summary>
         /// Counts the number of set bits in a span of bytes starting
-        /// at a specific bit offset.
+        /// at a specific bit index.
         /// </summary>
-        /// <param name="data">Span to count bits</param>
-        /// <param name="offset">Bit offset to start counting from</param>
-        /// <returns>Count of set (one) bits</returns>
-        public static int CountBits(ReadOnlySpan<byte> data, int offset) =>
-            CountBits(data, offset, data.Length * 8 - offset);
+        /// <param name="data">Span to count bits.</param>
+        /// <param name="index">Bit index to start counting from.</param>
+        /// <returns>Count of set (one) bits.</returns>
+        public static int CountBits(ReadOnlySpan<byte> data, int index) =>

Review Comment:
   Got it. Thanks



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to