/// <summary> /// Returns num of set bits within the specified recent history of the window /// </summary> /// <param name="recentHistLength">Length of the recent history (-1 means the whole available history)</param> public int GetNumOfSetBits(int recentHistLength = -1) { if (recentHistLength > Capacity || recentHistLength < -1) { throw new ArgumentException($"Invalid buffPartSize {recentHistLength}.", "buffPartSize"); } else if (recentHistLength == 0) { return(0); } else if (recentHistLength == -1) { return(NumOfSetBits); } else { int numOfSegments = recentHistLength / MaxBits + ((recentHistLength % MaxBits) > 0 ? 1 : 0); int lastSegHighestBitIndex = (recentHistLength - ((numOfSegments - 1) * MaxBits)) - 1; int counter = 0; for (int i = 0; i < numOfSegments - 1; i++) { counter += _segBitCounter[i]; } for (int i = 0; i <= lastSegHighestBitIndex; i++) { counter += Bitwise.GetBit(_buffSegments[numOfSegments - 1], i); } return(counter); } }
/// <summary> /// Adds next bit value into the window content /// </summary> /// <param name="bit">Specifies whether the bit to be added is set or not</param> public void AddNext(bool bit) { int lowestBitVal = bit ? 1 : 0; NumOfSetBits += lowestBitVal; for (int i = 0; i < _buffSegments.Length; i++) { if (i < _buffSegments.Length - 1) { int segHighestBitVal = Bitwise.GetBit(_buffSegments[i], BitMaxIndex); _segBitCounter[i] -= segHighestBitVal; _buffSegments[i] <<= 1; _buffSegments[i] += (ulong)lowestBitVal; _segBitCounter[i] += lowestBitVal; lowestBitVal = segHighestBitVal; } else { int segHighestBitVal = Bitwise.GetBit(_buffSegments[i], _lastSegHighestBitIndex); _segBitCounter[i] -= segHighestBitVal; NumOfSetBits -= segHighestBitVal; _buffSegments[i] = SetBit(_buffSegments[i], _lastSegHighestBitIndex, false); _buffSegments[i] <<= 1; _buffSegments[i] += (ulong)lowestBitVal; _segBitCounter[i] += lowestBitVal; } } if (BufferedHistLength < Capacity) { ++BufferedHistLength; } return; }
/// <summary> /// Returns bit value at the specified index within the window /// </summary> /// <param name="bitIndex">Zero based index of the bit (0 is the recent bit)</param> public int GetBit(int bitIndex) { if ((bitIndex + 1) > Capacity || bitIndex < 0) { throw new ArgumentException($"Invalid bitIndex {bitIndex}.", "bitIndex"); } int recentHistLength = bitIndex + 1; int numOfSegments = recentHistLength / MaxBits + ((recentHistLength % MaxBits) > 0 ? 1 : 0); int lastSegHighestBitIndex = (recentHistLength - ((numOfSegments - 1) * MaxBits)) - 1; return(Bitwise.GetBit(_buffSegments[numOfSegments - 1], lastSegHighestBitIndex)); }