6
6
* The {@code CircularBuffer} class implements a generic circular (or ring) buffer.
7
7
* A circular buffer is a fixed-size data structure that operates in a FIFO (First In, First Out) manner.
8
8
* The buffer allows you to overwrite old data when the buffer is full and efficiently use limited memory.
9
+ * When the buffer is full, adding a new item will overwrite the oldest data.
9
10
*
10
11
* @param <Item> The type of elements stored in the circular buffer.
11
12
*/
@@ -19,8 +20,12 @@ public class CircularBuffer<Item> {
19
20
* Constructor to initialize the circular buffer with a specified size.
20
21
*
21
22
* @param size The size of the circular buffer.
23
+ * @throws IllegalArgumentException if the size is zero or negative.
22
24
*/
23
25
public CircularBuffer (int size ) {
26
+ if (size <= 0 ) {
27
+ throw new IllegalArgumentException ("Buffer size must be positive" );
28
+ }
24
29
// noinspection unchecked
25
30
this .buffer = (Item []) new Object [size ];
26
31
this .putPointer = new CircularPointer (0 , size );
@@ -29,6 +34,7 @@ public CircularBuffer(int size) {
29
34
30
35
/**
31
36
* Checks if the circular buffer is empty.
37
+ * This method is based on the current size of the buffer.
32
38
*
33
39
* @return {@code true} if the buffer is empty, {@code false} otherwise.
34
40
*/
@@ -38,6 +44,7 @@ public boolean isEmpty() {
38
44
39
45
/**
40
46
* Checks if the circular buffer is full.
47
+ * The buffer is considered full when its size equals its capacity.
41
48
*
42
49
* @return {@code true} if the buffer is full, {@code false} otherwise.
43
50
*/
@@ -47,6 +54,7 @@ public boolean isFull() {
47
54
48
55
/**
49
56
* Retrieves and removes the item at the front of the buffer (FIFO).
57
+ * This operation will move the {@code getPointer} forward.
50
58
*
51
59
* @return The item at the front of the buffer, or {@code null} if the buffer is empty.
52
60
*/
@@ -62,23 +70,37 @@ public Item get() {
62
70
63
71
/**
64
72
* Adds an item to the end of the buffer (FIFO).
73
+ * If the buffer is full, this operation will overwrite the oldest data.
65
74
*
66
75
* @param item The item to be added.
67
- * @return {@code true} if the item was successfully added, or {@code false} if the buffer is full.
76
+ * @throws IllegalArgumentException if the item is null.
77
+ * @return {@code true} if the item was successfully added, {@code false} if the buffer was full and the item overwrote existing data.
68
78
*/
69
79
public boolean put (Item item ) {
80
+ if (item == null ) {
81
+ throw new IllegalArgumentException ("Null items are not allowed" );
82
+ }
83
+
84
+ boolean wasEmpty = isEmpty ();
70
85
if (isFull ()) {
71
- return false ;
86
+ getPointer .getAndIncrement (); // Move get pointer to discard oldest item
87
+ } else {
88
+ size .incrementAndGet ();
72
89
}
73
90
74
91
buffer [putPointer .getAndIncrement ()] = item ;
75
- size .incrementAndGet ();
76
- return true ;
92
+ return wasEmpty ;
77
93
}
78
94
79
95
/**
80
96
* The {@code CircularPointer} class is a helper class used to track the current index (pointer)
81
- * in the circular buffer. It automatically wraps around when reaching the maximum index.
97
+ * in the circular buffer.
98
+ * The max value represents the capacity of the buffer.
99
+ * The `CircularPointer` class ensures that the pointer automatically wraps around to 0
100
+ * when it reaches the maximum index.
101
+ * This is achieved in the `getAndIncrement` method, where the pointer
102
+ * is incremented and then taken modulo the maximum value (`max`).
103
+ * This operation ensures that the pointer always stays within the bounds of the buffer.
82
104
*/
83
105
private static class CircularPointer {
84
106
private int pointer ;
@@ -96,16 +118,14 @@ private static class CircularPointer {
96
118
}
97
119
98
120
/**
99
- * Increments the pointer by 1 and wraps it around to 0 if it exceeds the maximum value.
121
+ * Increments the pointer by 1 and wraps it around to 0 if it reaches the maximum value.
122
+ * This ensures the pointer always stays within the buffer's bounds.
100
123
*
101
124
* @return The current pointer value before incrementing.
102
125
*/
103
126
public int getAndIncrement () {
104
- if (pointer == max ) {
105
- pointer = 0 ;
106
- }
107
127
int tmp = pointer ;
108
- pointer ++ ;
128
+ pointer = ( pointer + 1 ) % max ;
109
129
return tmp ;
110
130
}
111
131
}
0 commit comments