/// <summary> /// Subtract the given Bloom filter, resulting in the difference. /// </summary> /// <param name="bloomFilterData"></param> /// <remarks>Results in the symmetric difference of the two Bloom filters.</remarks> public virtual void Subtract(IBloomFilterData bloomFilterData) { if (bloomFilterData == null) { return; } var foldedSize = _configuration.FoldingStrategy?.GetFoldFactors(_blockSize, bloomFilterData.BlockSize); if (bloomFilterData.BlockSize != BlockSize & foldedSize == null) { throw new ArgumentException("Bloom filters of different sizes cannot be subtracted.", nameof(bloomFilterData)); } var otherBitArray = new FastBitArray(bloomFilterData.Bits ?? EmptyByteArray) { Length = (int)bloomFilterData.BlockSize }; if (foldedSize != null && (foldedSize.Item2 != 1 || foldedSize.Item1 != 1)) { if (foldedSize.Item1 != 1) { Fold((uint)foldedSize.Item1, true); } if (foldedSize.Item2 != 1) { for (var i = 0; i < _data.Length; i++) { _data.Set(i, _data.Get(i) ^ GetFolded(otherBitArray, i, (uint)foldedSize.Item2)); } ItemCount = EstimateItemCount(_data, _hashFunctionCount); return; } } _data = _data.Xor(otherBitArray); ItemCount = EstimateItemCount(_data, _hashFunctionCount); }