5
5
6
6
namespace DataStructures . Lists
7
7
{
8
- public class CircularBuffer < T > : IEnumerable < T > , ICollection < T > where T : IComparable < T > {
8
+ public class CircularBuffer < T > : IEnumerable < T > , ICollection < T > where T : IComparable < T >
9
+ {
9
10
private T [ ] _circularBuffer ;
10
11
private int _end ;
11
12
private int _start ;
12
- private int _length { get => _circularBuffer . Length - 1 ; }
13
13
private readonly T _default ;
14
14
private static readonly int _defaultBufferLength = 10 ;
15
15
16
16
/// <summary>
17
- /// Controls whether data should be overridden when it is continously inserted without reading
17
+ /// Returns the length of the buffer
18
+ /// </summary>
19
+ public int Length
20
+ {
21
+ get
22
+ {
23
+ return _circularBuffer . Length - 1 ;
24
+ }
25
+ }
26
+
27
+ /// <summary>
28
+ /// Checks if no element is inserted into the buffer
18
29
/// </summary>
19
- public bool CanOverride { get ; }
20
- public bool IsEmpty { get => _end == _start ; }
21
- public bool IsFilledUp { get => ( ( _end + 1 ) % _circularBuffer . Length == _start ) && ! _circularBuffer [ _start ] . Equals ( _circularBuffer [ _end ] ) ; }
30
+ public bool IsEmpty
31
+ {
32
+ get
33
+ {
34
+ return _count == 0 ;
35
+ }
36
+ }
22
37
38
+ /// <summary>
39
+ /// Checks if the buffer is filled up
40
+ /// </summary>
41
+ public bool IsFilledUp
42
+ {
43
+ get
44
+ {
45
+ return ( ( _end + 1 ) % _circularBuffer . Length == _start ) && ! _circularBuffer [ _start ] . Equals ( _circularBuffer [ _end ] ) ;
46
+ }
47
+ }
48
+
49
+ /// <summary>
50
+ /// Controls whether data should be overridden when it is continously inserted without reading
51
+ /// </summary>
52
+ public bool CanOverride
53
+ {
54
+ get ;
55
+ }
23
56
24
57
/// <summary>
25
58
/// Initializes a circular buffer with initial length of 10
26
59
/// </summary>
27
- public CircularBuffer ( bool canOverride = true ) : this ( _defaultBufferLength , canOverride )
60
+ public CircularBuffer ( bool canOverride = true ) : this ( _defaultBufferLength , canOverride )
28
61
{
29
62
}
30
63
31
64
/// <summary>
32
65
/// Initializes a circular buffer with given length
33
66
/// </summary>
34
67
/// <param name="length">The length of the buffer</param>
35
- public CircularBuffer ( int length , bool canOverride = true )
68
+ public CircularBuffer ( int length , bool canOverride = true )
36
69
{
37
70
if ( length < 1 )
38
71
{
@@ -51,18 +84,11 @@ public CircularBuffer(int length, bool canOverride=true)
51
84
/// <param name="value">value to be added to the buffer</param>
52
85
public void Add ( T value )
53
86
{
54
- if ( CanOverride )
55
- {
56
- innerInsert ( value ) ;
57
- }
58
- else
87
+ if ( CanOverride == false && IsFilledUp == true )
59
88
{
60
- if ( IsFilledUp )
61
- {
62
- throw new CircularBufferFullException ( $ "Circular Buffer is filled up. { value } can not be inserted") ;
63
- }
64
- innerInsert ( value ) ;
89
+ throw new CircularBufferFullException ( $ "Circular Buffer is filled up. { value } can not be inserted") ;
65
90
}
91
+ innerInsert ( value ) ;
66
92
}
67
93
68
94
// Inserts data into the buffer without checking if it is full
@@ -74,6 +100,9 @@ private void innerInsert(T value)
74
100
{
75
101
_start = ( _start + 1 ) % _circularBuffer . Length ;
76
102
}
103
+
104
+ // Count should not be greater than the length of the buffer when overriding
105
+ _count = _count < Length ? ++ _count : _count ;
77
106
}
78
107
79
108
/// <summary>
@@ -84,13 +113,16 @@ public T Pop()
84
113
var result = _circularBuffer [ _start ] ;
85
114
_circularBuffer [ _start ] = _circularBuffer [ _end ] ;
86
115
_start = ( _start + 1 ) % _circularBuffer . Length ;
116
+ //Count should not go below Zero when poping an empty buffer.
117
+ _count = _count > 0 ? -- _count : _count ;
87
118
return result ;
88
119
}
89
120
90
121
#region IEnumerable Implementation
91
122
public IEnumerator < T > GetEnumerator ( )
92
123
{
93
- for ( int i = 0 ; i < Count ; i ++ ) {
124
+ for ( int i = 0 ; i < Count ; i ++ )
125
+ {
94
126
yield return _circularBuffer [ i ] ;
95
127
}
96
128
}
@@ -102,29 +134,34 @@ IEnumerator IEnumerable.GetEnumerator()
102
134
#endregion
103
135
104
136
#region ICollection Implementation
137
+ private int _count ;
105
138
/// <summary>
106
139
/// Returns the number of elements.
107
140
/// </summary>
108
141
public int Count
109
142
{
110
- get { return _length ; }
143
+ get
144
+ {
145
+ return _count ;
146
+ }
111
147
}
112
148
/// <summary>
113
149
/// Checks whether this collection is readonly
114
150
/// </summary>
115
151
public bool IsReadOnly
116
152
{
117
- get { return false ; }
153
+ get
154
+ {
155
+ return false ;
156
+ }
118
157
}
119
158
/// <summary>
120
159
/// Clears this instance
121
160
/// </summary>
122
161
public void Clear ( )
123
162
{
124
- for ( int i = 0 ; i < _circularBuffer . Length ; i ++ )
125
- {
126
- _circularBuffer [ i ] = _default ;
127
- }
163
+ _count = 0 ;
164
+ _circularBuffer = new T [ Length + 1 ] ;
128
165
}
129
166
/// <summary>
130
167
/// Checks whether the buffer contains an item
@@ -143,10 +180,11 @@ public void CopyTo(T[] array, int arrayIndex)
143
180
throw new ArgumentNullException ( "array can not be null" ) ;
144
181
}
145
182
146
- if ( array . Length == 0 || arrayIndex >= array . Length || arrayIndex < 0 ) {
183
+ if ( array . Length == 0 || arrayIndex >= array . Length || arrayIndex < 0 )
184
+ {
147
185
throw new IndexOutOfRangeException ( ) ;
148
186
}
149
-
187
+
150
188
// Get enumerator
151
189
var enumarator = GetEnumerator ( ) ;
152
190
@@ -169,26 +207,23 @@ public void CopyTo(T[] array, int arrayIndex)
169
207
/// </summary>
170
208
public bool Remove ( T item )
171
209
{
172
- if ( Contains ( item ) )
210
+ var result = false ;
211
+ for ( int i = 0 ; i < _circularBuffer . Length ; i ++ )
173
212
{
174
- for ( int i = 0 ; i < _circularBuffer . Length ; i ++ )
213
+ if ( item . Equals ( _circularBuffer [ i ] ) )
175
214
{
176
- if ( item . Equals ( _circularBuffer [ i ] ) )
177
- {
178
- _circularBuffer [ i ] = _default ;
179
- }
215
+ _circularBuffer [ i ] = _default ;
216
+ -- _count ;
217
+ result = true ;
180
218
}
181
- return true ;
182
- }
183
- else
184
- {
185
- return false ;
186
219
}
220
+ return result ;
221
+
187
222
}
188
223
#endregion
189
224
}
190
225
191
- public class CircularBufferFullException : Exception
226
+ public class CircularBufferFullException : Exception
192
227
{
193
228
public CircularBufferFullException ( string message ) : base ( message )
194
229
{
0 commit comments