public void Add(T element) { /* * This algorithm tries to update pointer to the next node, as opposed to tail node itself. * Drawback of this approach is that actual tail is not known, so additional tail look-up * in the form of nested while loop is required before every insert attempt. * Alternatevely, CAS operation can be applied to the tail node itself, in which case * count cannot be calculated along with the insert operation and requires iterating * when taking a snapshot. */ var newNode = new ConcurrentLinkedListNode <T>(element); var tail = volatileTail; do { while (tail.Next != null) { tail = tail.Next; } } while (!tail.SetNext(newNode)); volatileTail = newNode; Interlocked.Increment(ref count); }
public bool MoveNext() { if (index >= count || current == null) { return(false); } current = current.Next; ++index; return(current != null); }
public AppendOnlyConcurrentLinkedListSnapshot(ConcurrentLinkedListNode <T> head, int count) { Guard.NotNull("head", head); this.head = head; this.count = count; }
public void Reset() { current = head; index = 0; }
public AppendOnlyConcurrentLinkedListEnumerator(ConcurrentLinkedListNode <T> head, int count) { Guard.NotNull("head", head); this.current = this.head = head; this.count = count; }
public bool SetNext(ConcurrentLinkedListNode <T> newNext) { var oldNext = next; return(Interlocked.CompareExchange(ref next, newNext, oldNext) == oldNext); }
public AppendOnlyConcurrentLinkedList() { volatileTail = head = new ConcurrentLinkedListNode <T>(default(T)); }