bool ListPop(out T data) { Node rightNode = null, rightNodeNext = null, leftNode = (Node)head; data = default(T); do { rightNode = (Node)((Node)head).Next; if (rightNode == tail) { return(false); } data = rightNode.Data; rightNodeNext = (Node)rightNode.Next; if (!rightNodeNext.Marked) { if (ClientInterlocked.CompareExchange(ref rightNode.Next, new Node(rightNodeNext), rightNodeNext) == rightNodeNext) { break; } } } while (true); if (ClientInterlocked.CompareExchange(ref leftNode.Next, rightNodeNext, rightNode) != rightNodeNext) { ListSearch(rightNode.Key, ref leftNode); } return(true); }
public void PushRange(T[] items, int startIndex, int count) { RangeArgumentsCheck(items, startIndex, count); Node insert = null; Node first = null; for (int i = startIndex; i < count; i++) { Node temp = new Node(); temp.Value = items[i]; temp.Next = insert; insert = temp; if (first == null) { first = temp; } } do { first.Next = head; } while (ClientInterlocked.CompareExchange(ref head, insert, first.Next) != first.Next); ClientInterlocked.Add(ref this.count, count); }
bool ListDelete(int key, out T data) { Node rightNode = null, rightNodeNext = null, leftNode = null; data = default(T); do { rightNode = ListSearch(key, ref leftNode); if (rightNode == tail || rightNode.Key != key) { return(false); } data = rightNode.Data; rightNodeNext = ((Node)rightNode.Next); if (!rightNodeNext.Marked) { if (ClientInterlocked.CompareExchange(ref rightNode.Next, new Node(rightNodeNext), rightNodeNext) == rightNodeNext) { break; } } } while (true); if (ClientInterlocked.CompareExchange(ref leftNode.Next, rightNodeNext, rightNode) != rightNodeNext) { ListSearch(rightNode.Key, ref leftNode); } return(true); }
bool InsertInternal(uint key, TKey subKey, KeyValuePair <TKey, TValue> data, out Node current) { Node node = new Node().Init(ComputeRegularKey(key), subKey, data); uint b = key % (uint)size; Node bucket; if ((bucket = GetBucket(b)) == null) { bucket = InitializeBucket(b); } if (!ListInsert(node, bucket, out current)) { return(false); } int csize = size; if (ClientInterlocked.Increment(ref count) / csize > MaxLoad && (csize & 0x40000000) == 0) { ClientInterlocked.CompareExchange(ref size, 2 * csize, csize); } current = node; return(true); }
Node SetBucket(uint index, Node node) { try { slim.EnterReadLock(); CheckSegment(index, true); ClientInterlocked.CompareExchange(ref buckets[index], node, null); return((Node)buckets[index]); } finally { slim.ExitReadLock(); } }
public void Push(T item) { Node temp = new Node(); temp.Value = item; do { temp.Next = head; } while (ClientInterlocked.CompareExchange(ref head, temp, temp.Next) != temp.Next); ClientInterlocked.Increment(ref count); }
Node ListSearch(int key, ref Node left) { Node leftNodeNext = null, rightNode = null; do { Node t = (Node)head; Node tNext = (Node)t.Next; do { if (!tNext.Marked) { left = t; leftNodeNext = tNext; } t = tNext.Marked ? (Node)tNext.Next : tNext; if (t == tail) { break; } tNext = (Node)((Node)t).Next; } while (tNext.Marked || t.Key < key); rightNode = t; if (leftNodeNext == rightNode) { if (rightNode != tail && ((Node)rightNode.Next).Marked) { continue; } else { return(rightNode); } } if (ClientInterlocked.CompareExchange(ref left.Next, rightNode, leftNodeNext) == leftNodeNext) { if (rightNode != tail && ((Node)rightNode.Next).Marked) { continue; } else { return(rightNode); } } } while (true); }
Node ListSearch(ulong key, TKey subKey, ref Node left, Node h) { Node leftNodeNext = null, rightNode = null; do { Node t = h; Node tNext = (Node)t.Next; do { if (!tNext.Marked) { left = t; leftNodeNext = tNext; } t = tNext.Marked ? (Node)tNext.Next : tNext; if (t == tail) { break; } tNext = (Node)t.Next; } while (tNext.Marked || t.Key < key || (tNext.Key == key && !comparer.Equals(subKey, t.SubKey))); rightNode = t; if (leftNodeNext == rightNode) { if (rightNode != tail && ((Node)rightNode.Next).Marked) { continue; } else { return(rightNode); } } if (ClientInterlocked.CompareExchange(ref left.Next, rightNode, leftNodeNext) == leftNodeNext) { if (rightNode != tail && ((Node)rightNode.Next).Marked) { continue; } else { return(rightNode); } } } while (true); }
public bool TryDequeue(out T result) { result = default(T); object oldNext = null; bool advanced = false; while (!advanced) { object oldHead = head; object oldTail = tail; oldNext = ((Node)oldHead).Next; if (oldHead == head) { // Empty case ? if (oldHead == oldTail) { // This should be false then if (oldNext != null) { // If not then the linked list is mal formed, update tail ClientInterlocked.CompareExchange(ref tail, oldNext, oldTail); continue; } result = default(T); return(false); } else { if (oldNext != null) { result = ((Node)oldNext).Value; advanced = ClientInterlocked.CompareExchange(ref head, oldNext, oldHead) == oldHead; } } } } if (null != oldNext) { ((Node)oldNext).Value = default(T); } ClientInterlocked.Decrement(ref count); return(true); }
bool ListInsert(Node newNode) { int key = newNode.Key; Node rightNode = null, leftNode = null; do { rightNode = ListSearch(key, ref leftNode); if (rightNode != tail && rightNode.Key == key) { return(false); } newNode.Next = rightNode; if (ClientInterlocked.CompareExchange(ref leftNode.Next, newNode, rightNode) == rightNode) { return(true); } } while (true); }
bool ListInsert(Node newNode, Node startPoint, out Node current) { ulong key = newNode.Key; Node rightNode = null, leftNode = null; do { rightNode = current = ListSearch(key, newNode.SubKey, ref leftNode, startPoint); if (rightNode != tail && rightNode.Key == key && comparer.Equals(newNode.SubKey, rightNode.SubKey)) { return(false); } newNode.Next = rightNode; if (ClientInterlocked.CompareExchange(ref leftNode.Next, newNode, rightNode) == rightNode) { return(true); } } while (true); }
public bool TryPop(out T result) { Node temp; do { temp = (Node)head; // The stak is empty if (temp == null) { result = default(T); return(false); } } while (ClientInterlocked.CompareExchange(ref head, temp.Next, temp) != temp); ClientInterlocked.Decrement(ref count); result = temp.Value; return(true); }
bool ListDelete(Node startPoint, ulong key, TKey subKey, out KeyValuePair <TKey, TValue> data) { Node rightNode = null, rightNodeNext = null, leftNode = null; data = default(KeyValuePair <TKey, TValue>); Node markedNode = null; do { rightNode = ListSearch(key, subKey, ref leftNode, startPoint); if (rightNode == tail || rightNode.Key != key || !comparer.Equals(subKey, rightNode.SubKey)) { return(false); } data = rightNode.Data; rightNodeNext = (Node)rightNode.Next; if (!rightNodeNext.Marked) { if (markedNode == null) { markedNode = new Node(); } markedNode.Init(rightNodeNext); if (ClientInterlocked.CompareExchange(ref rightNode.Next, markedNode, rightNodeNext) == rightNodeNext) { break; } } } while (true); if (ClientInterlocked.CompareExchange(ref leftNode.Next, rightNodeNext, rightNode) != rightNode) { ListSearch(rightNode.Key, subKey, ref leftNode, startPoint); } return(true); }
public int TryPopRange(T[] items, int startIndex, int count) { RangeArgumentsCheck(items, startIndex, count); object temp; object end; do { temp = head; if (temp == null) { return(0); } end = temp; for (int j = 0; j < count; j++) { end = ((Node)end).Next; if (end == null) { break; } } } while (ClientInterlocked.CompareExchange(ref head, end, temp) != temp); int i; for (i = startIndex; i < startIndex + count && temp != null; i++) { items[i] = ((Node)temp).Value; end = temp; temp = ((Node)temp).Next; } ClientInterlocked.Add(ref this.count, -(i - startIndex)); return(i - startIndex); }
public void Enqueue(T item) { Node node = new Node(); node.Value = item; object oldTail = null; object oldNext = null; bool update = false; while (!update) { oldTail = tail; oldNext = ((Node)oldTail).Next; // Did tail was already updated ? if (tail == oldTail) { if (oldNext == null) { // The place is for us Node tailObj = (Node)tail; update = ClientInterlocked.CompareExchange(ref tailObj.Next, node, null) == null; } else { // another Thread already used the place so give him a hand by putting tail where it should be ClientInterlocked.CompareExchange(ref tail, oldNext, oldTail); } } } // At this point we added correctly our node, now we have to update tail. If it fails then it will be done by another thread ClientInterlocked.CompareExchange(ref tail, node, oldTail); ClientInterlocked.Increment(ref count); }