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) { 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 (set._v1 == i || set._v2 == i || set._v3 == i || set._v4 == i) { return(true); } set = set._next; }while (set != 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) { Debug.Assert(i != unoccupied); return(SmallConcurrentSetOfInts.Add(this, i)); }