private static bool Add(SmallConcurrentSetOfInts set, int i) { bool added = false; while (true) { if (AddHelper(ref set._v1, i, ref added) || AddHelper(ref set._v2, i, ref added) || AddHelper(ref set._v3, i, ref added) || AddHelper(ref set._v4, i, ref added)) { return(added); } var nextSet = set._next; if (nextSet == null) { // Need to add a new 'block'. SmallConcurrentSetOfInts tail = new SmallConcurrentSetOfInts(initialValue: i); nextSet = Interlocked.CompareExchange(ref set._next, tail, null); if (nextSet == null) { // Successfully added a new tail return(true); } // Lost the race. Another thread added a new tail so resume searching from there. } set = nextSet; } }
private static bool Contains(SmallConcurrentSetOfInts set, int i) { SmallConcurrentSetOfInts?current = set; do { // PERF: Not testing for unoccupied slots since it adds complexity. The extra comparisons // would slow down this inner loop such that any benefit of an 'early out' would be lost. if (current._v1 == i || current._v2 == i || current._v3 == i || current._v4 == i) { return(true); } current = current._next; }while (current != null); return(false); }
/// <summary> /// Insert the given value into the set. /// </summary> /// <param name="i">The value to insert</param> /// <returns>true if <paramref name="i"/> was added. false if it was already present.</returns> public bool Add(int i) { RoslynDebug.Assert(i != unoccupied); return(SmallConcurrentSetOfInts.Add(this, i)); }