37 namespace System.Collections.Concurrent
40 [DebuggerDisplay (
"Count={Count}")]
41 [DebuggerTypeProxy (typeof (CollectionDebuggerView<>))]
59 foreach (T item
in collection)
63 public void Add (T item)
66 CyclicDeque<T> bag = GetBag (out index);
67 bag.PushBottom (item);
69 Interlocked.Increment (ref count);
86 CyclicDeque<T> bag = GetBag (out hintIndex,
false);
89 if (bag == null || bag.PopBottom (out result) !=
PopResult.Succeed) {
91 foreach (var other
in staging) {
93 ret = TryGetHint (out hintIndex) && (bag = container[hintIndex]).PopTop (out result) ==
PopResult.Succeed;
96 if (!ret && other.Value !=
self) {
97 var status = other.Value.PopTop (out result);
99 status = other.Value.PopTop (out result);
101 hintIndex = other.Key;
112 TidyBag (hintIndex, bag);
113 Interlocked.Decrement (ref count);
121 result =
default (T);
127 CyclicDeque<T> bag = GetBag (out hintIndex,
false);
130 if (bag == null || !bag.PeekBottom (out result)) {
132 foreach (var other
in staging) {
134 ret = TryGetHint (out hintIndex) && container[hintIndex].PeekTop (out result);
137 if (!ret && other.Value !=
self)
138 ret = other.Value.PeekTop (out result);
149 void AddHint (
int index)
156 Interlocked.CompareExchange (ref hints, (
long)(((ulong)hs) << 4 | (uint)index), (
long)hs);
159 bool TryGetHint (out
int index)
168 if (Interlocked.CompareExchange (ref hints, (
long)(((ulong)hs) >> 4), hs) == hs)
169 index = (
int)(hs & 0xF);
180 public bool IsEmpty {
198 IEnumerator IEnumerable.GetEnumerator ()
200 return GetEnumeratorInternal ();
205 return GetEnumeratorInternal ();
208 IEnumerator<T> GetEnumeratorInternal ()
210 foreach (var bag
in container)
211 foreach (T item
in bag.Value.GetEnumerable ())
217 T[] a = array as T[];
224 public void CopyTo (T[] array,
int index)
227 if (array.Length < c + index)
228 throw new InvalidOperationException (
"Array is not big enough");
230 CopyTo (array, index, c);
233 void CopyTo (T[] array,
int index,
int num)
237 foreach (T item
in this) {
257 return Thread.CurrentThread.ManagedThreadId;
260 CyclicDeque<T> GetBag (out
int index,
bool createBag =
true)
263 CyclicDeque<T> value;
264 if (container.TryGetValue (index, out value))
267 var bag = createBag ? container.GetOrAdd (index,
new CyclicDeque<T> ()) : null;
269 staging.TryAdd (index, bag);
273 void TidyBag (
int index, CyclicDeque<T> bag)
275 if (bag != null && bag.IsEmpty) {
276 if (staging.TryRemove (index, out bag) && !bag.IsEmpty)
277 staging.TryAdd (index, bag);
bool TryPeek(out T result)
bool TryTake(out T result)
IEnumerator< T > GetEnumerator()
void CopyTo(T[] array, int index)
ConcurrentBag(IEnumerable< T > collection)