20 using System.Collections;
21 using System.Collections.Generic;
22 using System.Threading;
24 namespace OpenSim.Framework
35 private object syncRoot;
38 : this(capacity, false)
45 throw new ArgumentException(
"Needs to have at least 1",
"capacity");
47 this.capacity = capacity;
51 buffer =
new T[capacity];
52 AllowOverflow = allowOverflow;
55 public bool AllowOverflow
63 get {
return capacity; }
66 if (value == capacity)
70 throw new ArgumentOutOfRangeException(
"value",
"Capacity is too small.");
72 var dst =
new T[value];
88 int bufferIndex = head;
89 var comparer = EqualityComparer<T>.Default;
90 for (
int i = 0; i < size; i++, bufferIndex++)
92 if (bufferIndex == capacity)
95 if (item == null && buffer[bufferIndex] == null)
97 else if ((buffer[bufferIndex] != null) &&
98 comparer.Equals(buffer[bufferIndex], item))
114 return Put(src, 0, src.Length);
117 public int Put(T[] src,
int offset,
int count)
119 if (!AllowOverflow && count > capacity - size)
120 throw new InvalidOperationException(
"Buffer Overflow");
122 int srcIndex = offset;
123 for (
int i = 0; i < count; i++, tail++, srcIndex++)
125 if (tail == capacity)
127 buffer[tail] = src[srcIndex];
129 size = Math.Min(size + count, capacity);
135 if (!AllowOverflow && size == capacity)
136 throw new InvalidOperationException(
"Buffer Overflow");
139 if (++tail == capacity)
147 if (head >= capacity)
153 var dst =
new T[count];
160 return Get(dst, 0, dst.Length);
163 public int Get(T[] dst,
int offset,
int count)
165 int realCount = Math.Min(count, size);
166 int dstIndex = offset;
167 for (
int i = 0; i < realCount; i++, head++, dstIndex++)
169 if (head == capacity)
171 dst[dstIndex] = buffer[head];
180 throw new InvalidOperationException(
"Buffer Empty");
182 var item = buffer[head];
183 if (++head == capacity)
194 public void CopyTo(T[] array,
int arrayIndex)
196 CopyTo(0, array, arrayIndex, size);
199 public void CopyTo(
int index, T[] array,
int arrayIndex,
int count)
202 throw new ArgumentOutOfRangeException(
"count",
"Count Too Large");
204 int bufferIndex = head;
205 for (
int i = 0; i < count; i++, bufferIndex++, arrayIndex++)
207 if (bufferIndex == capacity)
209 array[arrayIndex] = buffer[bufferIndex];
215 int bufferIndex = head;
216 for (
int i = 0; i < size; i++, bufferIndex++)
218 if (bufferIndex == capacity)
221 yield
return buffer[bufferIndex];
232 var dst =
new T[size];
237 #region ICollection<T> Members
239 int ICollection<T>.Count
244 bool ICollection<T>.IsReadOnly
246 get {
return false; }
249 void ICollection<T>.Add(T item)
254 bool ICollection<T>.Remove(T item)
265 #region IEnumerable<T> Members
269 return GetEnumerator();
274 #region ICollection Members
276 int ICollection.Count
281 bool ICollection.IsSynchronized
283 get {
return false; }
286 object ICollection.SyncRoot
290 if (syncRoot == null)
291 Interlocked.CompareExchange(ref syncRoot,
new object(), null);
296 void ICollection.CopyTo(
Array array,
int arrayIndex)
298 CopyTo((T[])array, arrayIndex);
303 #region IEnumerable Members
305 IEnumerator IEnumerable.GetEnumerator()
307 return (IEnumerator)GetEnumerator();
IEnumerator< T > GetEnumerator()
CircularBuffer(int capacity)
void CopyTo(int index, T[] array, int arrayIndex, int count)
int Put(T[] src, int offset, int count)
System.Collections.IEnumerable IEnumerable
void CopyTo(T[] array, int arrayIndex)
CircularBuffer(int capacity, bool allowOverflow)
int Get(T[] dst, int offset, int count)