Add a pop front operation to ConcurrentOrderedList
authorJérémie Laval <jeremie.laval@gmail.com>
Sat, 15 Oct 2011 12:51:38 +0000 (14:51 +0200)
committerJérémie Laval <jeremie.laval@gmail.com>
Sat, 15 Oct 2011 13:34:54 +0000 (15:34 +0200)
mcs/class/corlib/System.Collections.Concurrent/ConcurrentOrderedList.cs

index dec8ef5df108affae02efe05770aa6c6bf894505..14d49f2b8f585c3fe08c28b0dd86803ae6b5db91 100644 (file)
@@ -116,6 +116,11 @@ namespace System.Collections.Concurrent
                        return false;
                }
 
+               public bool TryPop (out T data)
+               {
+                       return ListPop (out data);
+               }
+
                public bool Contains (T data)
                {
                        return ContainsHash (comparer.GetHashCode (data));
@@ -238,6 +243,30 @@ namespace System.Collections.Concurrent
                        
                        return true;
                }
+
+               bool ListPop (out T data)
+               {
+                       Node rightNode = null, rightNodeNext = null, leftNode = null;
+                       data = default (T);
+
+                       do {
+                               rightNode = head.Next;
+                               if (rightNode == tail)
+                                       return false;
+
+                               data = rightNode.Data;
+
+                               rightNodeNext = rightNode.Next;
+                               if (!rightNodeNext.Marked)
+                                       if (Interlocked.CompareExchange (ref rightNode.Next, new Node (rightNodeNext), rightNodeNext) == rightNodeNext)
+                                               break;
+                       } while (true);
+
+                       if (Interlocked.CompareExchange (ref leftNode.Next, rightNodeNext, rightNode) != rightNodeNext)
+                               ListSearch (rightNode.Key, ref leftNode);
+
+                       return true;
+               }
                
                bool ListInsert (Node newNode)
                {