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));
 }