/// <summary> /// Finds members of a bitset that are not in the other set (ANDNOT). /// This does not modify either bitset. /// </summary> /// <param name="otherSet">The set to compare against</param> /// <returns>A new IBitset containing the members that are in /// the first bitset but not in the second.</returns> public IBitset AndNot(RoaringBitset otherSet) { RoaringBitset answer = new RoaringBitset(); int pos1 = 0, pos2 = 0; int length1 = containers.Size, length2 = otherSet.containers.Size; while (pos1 < length1 && pos2 < length2) { ushort s1 = containers.GetKeyAtIndex(pos1); ushort s2 = otherSet.containers.GetKeyAtIndex(pos2); if (s1 == s2) { Container c1 = containers.GetContainerAtIndex(pos1); Container c2 = otherSet.containers.GetContainerAtIndex(pos2); Container c = c1.AndNot(c2); if (c.GetCardinality() > 0) { answer.containers.Append(s1, c); } ++pos1; ++pos2; } else if (Utility.CompareUnsigned(s1, s2) < 0) { // s1 < s2 int nextPos1 = containers.AdvanceUntil(s2, pos1); answer.containers.AppendCopy(containers, pos1, nextPos1); pos1 = nextPos1; } else { // s1 > s2 pos2 = otherSet.containers.AdvanceUntil(s1, pos2); } } if (pos2 == length2) { answer.containers.AppendCopy(containers, pos1, length1); } return(answer); }
/// <summary> /// Performs an in-place intersection of two Roaring Bitsets. /// </summary> /// <param name="other">the second Roaring Bitset to intersect</param> private void AndWith(RoaringBitset other) { int thisLength = containers.Size; int otherLength = other.containers.Size; int pos1 = 0, pos2 = 0, intersectionSize = 0; while (pos1 < thisLength && pos2 < otherLength) { ushort s1 = containers.GetKeyAtIndex(pos1); ushort s2 = other.containers.GetKeyAtIndex(pos2); if (s1 == s2) { Container c1 = containers.GetContainerAtIndex(pos1); Container c2 = other.containers.GetContainerAtIndex(pos2); Container c = c1.IAnd(c2); if (c.GetCardinality() > 0) { containers.ReplaceKeyAndContainerAtIndex(intersectionSize++, s1, c); } ++pos1; ++pos2; } else if (s1 < s2) { // s1 < s2 pos1 = containers.AdvanceUntil(s2, pos1); } else { // s1 > s2 pos2 = other.containers.AdvanceUntil(s1, pos2); } } containers.Resize(intersectionSize); }