Skip to content

Commit 7555d9e

Browse files
Merge pull request TheAlgorithms#166 from KyleScharnhorst/add-circular-buffer
Add: circular buffer implementation.
2 parents 1a9aa87 + 0ade40c commit 7555d9e

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import java.util.Random;
2+
import java.util.concurrent.atomic.AtomicInteger;
3+
4+
public class CircularBuffer {
5+
private char[] _buffer;
6+
public final int _buffer_size;
7+
private int _write_index = 0;
8+
private int _read_index = 0;
9+
private AtomicInteger _readable_data = new AtomicInteger(0);
10+
11+
public CircularBuffer(int buffer_size) {
12+
if(!IsPowerOfTwo(buffer_size)) {
13+
throw new IllegalArgumentException();
14+
}
15+
this._buffer_size = buffer_size;
16+
_buffer = new char[buffer_size];
17+
}
18+
19+
private boolean IsPowerOfTwo(int i) {
20+
return (i & (i - 1)) == 0;
21+
}
22+
23+
private int getTrueIndex(int i) {
24+
return i % _buffer_size;
25+
}
26+
27+
public Character readOutChar() {
28+
Character result = null;
29+
30+
//if we have data to read
31+
if(_readable_data.get() > 0) {
32+
result = new Character(_buffer[getTrueIndex(_read_index)]);
33+
_readable_data.decrementAndGet();
34+
_read_index++;
35+
}
36+
37+
return result;
38+
}
39+
40+
public boolean writeToCharBuffer(char c) {
41+
boolean result = false;
42+
43+
//if we can write to the buffer
44+
if(_readable_data.get() < _buffer_size) {
45+
//write to buffer
46+
_buffer[getTrueIndex(_write_index)] = c;
47+
_readable_data.incrementAndGet();
48+
_write_index++;
49+
result = true;
50+
}
51+
52+
return result;
53+
}
54+
55+
private static class TestWriteWorker implements Runnable {
56+
String _alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
57+
Random _random = new Random();
58+
CircularBuffer _buffer;
59+
public TestWriteWorker(CircularBuffer cb) {
60+
this._buffer = cb;
61+
}
62+
63+
private char getRandomChar() {
64+
return _alphabet.charAt(_random.nextInt(_alphabet.length()));
65+
}
66+
67+
public void run() {
68+
while(!Thread.interrupted()) {
69+
if(!_buffer.writeToCharBuffer(getRandomChar())){
70+
Thread.yield();
71+
try{
72+
Thread.sleep(10);
73+
} catch (InterruptedException e) {
74+
return;
75+
}
76+
}
77+
}
78+
}
79+
}
80+
81+
private static class TestReadWorker implements Runnable {
82+
CircularBuffer _buffer;
83+
public TestReadWorker(CircularBuffer cb) {
84+
this._buffer = cb;
85+
}
86+
87+
public void run() {
88+
System.out.println("Printing Buffer:");
89+
while(!Thread.interrupted()) {
90+
Character c = _buffer.readOutChar();
91+
if(c != null) {
92+
System.out.print(c.charValue());
93+
} else {
94+
Thread.yield();
95+
try {
96+
Thread.sleep(10);
97+
} catch (InterruptedException e) {
98+
System.out.println();
99+
return;
100+
}
101+
}
102+
}
103+
}
104+
}
105+
106+
public static void main(String[] args) throws InterruptedException {
107+
int buffer_size = 1024;
108+
//create circular buffer
109+
CircularBuffer cb = new CircularBuffer(buffer_size);
110+
111+
//create threads that read and write the buffer.
112+
Thread write_thread = new Thread(new TestWriteWorker(cb));
113+
Thread read_thread = new Thread(new TestReadWorker(cb));
114+
read_thread.start();
115+
write_thread.start();
116+
117+
//wait some amount of time
118+
Thread.sleep(10000);
119+
120+
//interrupt threads and exit
121+
write_thread.interrupt();
122+
read_thread.interrupt();
123+
}
124+
}

0 commit comments

Comments
 (0)