33 #if INSIDE_MONO_PARALLEL 36 namespace Mono.Collections.Concurrent
38 namespace
System.Collections.Concurrent
41 #if INSIDE_MONO_PARALLEL 58 public Node (Node wrapped)
68 IEqualityComparer<T> comparer;
80 throw new ArgumentNullException (
"comparer");
82 this.comparer = comparer;
91 Node node =
new Node ();
93 node.Key = comparer.GetHashCode (data);
95 if (ListInsert (node)) {
96 Interlocked.Increment (ref count);
106 return TryRemoveHash (comparer.GetHashCode (data), out dummy);
111 if (ListDelete (key, out data)) {
112 Interlocked.Decrement (ref count);
121 return ListPop (out data);
126 return ContainsHash (comparer.GetHashCode (data));
133 if (!ListFind (key, out node))
145 if (!ListFind (key, out node))
157 public void CopyTo (T[] array,
int startIndex)
160 throw new ArgumentNullException (
"array");
162 throw new ArgumentOutOfRangeException (
"startIndex");
163 if (count > array.Length - startIndex)
164 throw new ArgumentException (
"array",
"The number of elements is greater than the available space from startIndex to the end of the destination array.");
166 foreach (T item
in this) {
167 if (startIndex >= array.Length)
170 array[startIndex++] = item;
174 public IEqualityComparer<T> Comparer {
186 Node ListSearch (
int key, ref Node left)
188 Node leftNodeNext = null, rightNode = null;
196 leftNodeNext = tNext;
198 t = tNext.Marked ? tNext.Next : tNext;
203 }
while (tNext.Marked || t.Key < key);
207 if (leftNodeNext == rightNode) {
208 if (rightNode != tail && rightNode.Next.Marked)
214 if (
AotInterlocked.CompareExchange (ref left.Next, rightNode, leftNodeNext) == leftNodeNext) {
215 if (rightNode != tail && rightNode.Next.Marked)
223 bool ListDelete (
int key, out T data)
225 Node rightNode = null, rightNodeNext = null, leftNode = null;
229 rightNode = ListSearch (key, ref leftNode);
230 if (rightNode == tail || rightNode.Key != key)
233 data = rightNode.Data;
235 rightNodeNext = rightNode.Next;
236 if (!rightNodeNext.Marked)
237 if (
AotInterlocked.CompareExchange (ref rightNode.Next,
new Node (rightNodeNext), rightNodeNext) == rightNodeNext)
241 if (
AotInterlocked.CompareExchange (ref leftNode.Next, rightNodeNext, rightNode) != rightNodeNext)
242 ListSearch (rightNode.Key, ref leftNode);
247 bool ListPop (out T data)
249 Node rightNode = null, rightNodeNext = null, leftNode = head;
253 rightNode = head.Next;
254 if (rightNode == tail)
257 data = rightNode.Data;
259 rightNodeNext = rightNode.Next;
260 if (!rightNodeNext.Marked)
261 if (
AotInterlocked.CompareExchange (ref rightNode.Next,
new Node (rightNodeNext), rightNodeNext) == rightNodeNext)
265 if (
AotInterlocked.CompareExchange (ref leftNode.Next, rightNodeNext, rightNode) != rightNodeNext)
266 ListSearch (rightNode.Key, ref leftNode);
271 bool ListInsert (Node newNode)
273 int key = newNode.Key;
274 Node rightNode = null, leftNode = null;
277 rightNode = ListSearch (key, ref leftNode);
278 if (rightNode != tail && rightNode.Key == key)
281 newNode.Next = rightNode;
282 if (
AotInterlocked.CompareExchange (ref leftNode.Next, newNode, rightNode) == rightNode)
287 bool ListFind (
int key, out Node data)
289 Node rightNode = null, leftNode = null;
292 data = rightNode = ListSearch (key, ref leftNode);
294 return rightNode != tail && rightNode.Key == key;
297 IEnumerator<T> IEnumerable<T>.GetEnumerator ()
299 return GetEnumeratorInternal ();
302 IEnumerator IEnumerable.GetEnumerator ()
304 return GetEnumeratorInternal ();
307 IEnumerator<T> GetEnumeratorInternal ()
309 Node node = head.Next;
311 while (node != tail) {
312 while (node.Marked) {
317 yield
return node.Data;
322 bool ICollection<T>.IsReadOnly {
328 void ICollection<T>.Add (T item)
333 bool ICollection<T>.Remove (T item)
335 return TryRemove (item);
void CopyTo(T[] array, int startIndex)
bool TryRemoveHash(int key, out T data)
ConcurrentOrderedList(IEqualityComparer< T > comparer)
bool ContainsHash(int key)
Interlocked reference exchanges do not work with the older Mono AOT compiler so this type fudges arou...
bool TryGetFromHash(int key, out T data)